001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.runtime.reflection.storage; 020 021import java.lang.reflect.Constructor; 022import java.util.WeakHashMap; 023 024import lucee.runtime.type.Array; 025import lucee.runtime.type.ArrayImpl; 026 027import org.apache.commons.collections.map.ReferenceMap; 028 029/** 030 * Constructor Storage Class 031 */ 032public final class WeakConstructorStorage { 033 private WeakHashMap map=new WeakHashMap(ReferenceMap.SOFT,ReferenceMap.SOFT); 034 035 /** 036 * returns a constructor matching given criteria or null if Constructor doesn't exist 037 * @param clazz Class to get Constructor for 038 * @param count count of arguments for the constructor 039 * @return returns the constructors 040 */ 041 public synchronized Constructor[] getConstructors(Class clazz,int count) { 042 Object o=map.get(clazz); 043 Array con; 044 if(o==null) { 045 con=store(clazz); 046 } 047 else con=(Array) o; 048 049 o=con.get(count+1,null); 050 if(o==null) return null; 051 return (Constructor[]) o; 052 } 053 054 /** 055 * stores the constructors for a Class 056 * @param clazz 057 * @return stored structure 058 */ 059 private Array store(Class clazz) { 060 Constructor[] conArr=clazz.getConstructors(); 061 Array args=new ArrayImpl(); 062 for(int i=0;i<conArr.length;i++) { 063 storeArgs(conArr[i],args); 064 } 065 map.put(clazz,args); 066 return args; 067 068 } 069 070 /** 071 * seperate and store the different arguments of one constructor 072 * @param constructor 073 * @param conArgs 074 */ 075 private void storeArgs(Constructor constructor, Array conArgs) { 076 Class[] pmt = constructor.getParameterTypes(); 077 Object o=conArgs.get(pmt.length+1,null); 078 Constructor[] args; 079 if(o==null) { 080 args=new Constructor[1]; 081 conArgs.setEL(pmt.length+1,args); 082 } 083 else { 084 Constructor[] cs=(Constructor[]) o; 085 args = new Constructor[cs.length+1]; 086 for(int i=0;i<cs.length;i++) { 087 args[i]=cs[i]; 088 } 089 conArgs.setEL(pmt.length+1,args); 090 } 091 args[args.length-1]=constructor; 092 093 } 094}