001    package railo.runtime.reflection.storage;
002    
003    import java.lang.reflect.Constructor;
004    import java.util.WeakHashMap;
005    
006    import org.apache.commons.collections.map.ReferenceMap;
007    
008    import railo.runtime.type.Array;
009    import railo.runtime.type.ArrayImpl;
010    
011    /**
012     * Constructor Storage Class
013     */
014    public final class WeakConstructorStorage {
015            private WeakHashMap map=new WeakHashMap(ReferenceMap.SOFT,ReferenceMap.SOFT);
016            
017            /**
018             * returns a constructor matching given criteria or null if Constructor doesn't exist
019             * @param clazz Class to get Constructor for
020             * @param count count of arguments for the constructor
021             * @return returns the constructors
022             */
023            public synchronized Constructor[] getConstructors(Class clazz,int count) {
024                    Object o=map.get(clazz);
025                    Array con;
026                    if(o==null) {
027                            con=store(clazz);
028                    }
029                    else con=(Array) o;
030    
031                    o=con.get(count+1,null);
032                    if(o==null) return null;
033                    return (Constructor[]) o;
034            }
035    
036            /**
037             * stores the constructors for a Class
038             * @param clazz 
039             * @return stored structure
040             */
041            private Array store(Class clazz) {
042                            Constructor[] conArr=clazz.getConstructors();
043                            Array args=new ArrayImpl();
044                            for(int i=0;i<conArr.length;i++) {
045                                    storeArgs(conArr[i],args);
046                            }
047                            map.put(clazz,args);
048                            return args;
049                    
050            }
051    
052            /**
053             * seperate and store the different arguments of one constructor
054             * @param constructor
055             * @param conArgs
056             */
057            private void storeArgs(Constructor constructor, Array conArgs) {
058                    Class[] pmt = constructor.getParameterTypes();
059                    Object o=conArgs.get(pmt.length+1,null);
060                    Constructor[] args;
061                    if(o==null) {
062                            args=new Constructor[1];
063                            conArgs.setEL(pmt.length+1,args);
064                    }
065                    else {
066                            Constructor[] cs=(Constructor[]) o;
067                            args = new Constructor[cs.length+1];
068                            for(int i=0;i<cs.length;i++) {
069                                    args[i]=cs[i];
070                            }
071                            conArgs.setEL(pmt.length+1,args);
072                    }
073                    args[args.length-1]=constructor;
074                    
075            }
076    }