001    package railo.runtime.reflection.storage;
002    
003    import java.lang.reflect.Method;
004    import java.util.Map;
005    
006    import org.apache.commons.collections.map.ReferenceMap;
007    
008    import railo.runtime.type.Array;
009    import railo.runtime.type.ArrayImpl;
010    import railo.runtime.type.Collection;
011    import railo.runtime.type.Collection.Key;
012    import railo.runtime.type.KeyImpl;
013    import railo.runtime.type.Struct;
014    import railo.runtime.type.StructImpl;
015    
016    /**
017     * Method Storage Class
018     */
019    public final class WeakMethodStorage {
020            private Map map=new ReferenceMap();
021            
022            /**
023             * returns a methods matching given criteria or null if method doesn't exist
024             * @param clazz clazz to get methods from
025             * @param methodName Name of the Method to get
026             * @param count wished count of arguments
027             * @return matching Methods as Array
028             */
029            public Method[] getMethods(Class clazz,Collection.Key methodName, int count) {
030                    Object o=map.get(clazz);
031                    Struct methodsMap;
032                    if(o==null) {
033                            methodsMap=store(clazz);
034                    }
035                    else methodsMap=(Struct) o;
036                    
037                    o=methodsMap.get(methodName,null);
038                    if(o==null) return null;
039                    Array methods=(Array) o;
040                    o=methods.get(count+1,null);
041                    if(o==null) return null;
042                    return (Method[]) o;
043                    
044            }
045    
046    
047            /**
048             * store a class with his methods
049             * @param clazz
050             * @return returns stored struct
051             */
052            private StructImpl store(Class clazz) {
053                    Method[] methodsArr=clazz.getMethods();
054                    StructImpl methodsMap=new StructImpl();
055                    for(int i=0;i<methodsArr.length;i++) {
056                            storeMethod(methodsArr[i],methodsMap);
057                            
058                    }
059                    map.put(clazz,methodsMap);
060                    return methodsMap;
061            }
062    
063            /**
064             * stores a single method
065             * @param method
066             * @param methodsMap
067             */
068            private void storeMethod(Method method, StructImpl methodsMap) {
069                    Key methodName = KeyImpl.getInstance(method.getName());
070                    
071                    
072                    Object o=methodsMap.get(methodName,null);
073                    Array methodArgs;
074                    if(o==null) {
075                            methodArgs=new ArrayImpl();
076                            methodsMap.setEL(methodName,methodArgs);
077                    }
078                    else methodArgs=(Array) o;
079                    storeArgs(method,methodArgs);
080                    //Modifier.isStatic(method.getModifiers());
081            }
082    
083            /**
084             * stores arguments of a method
085             * @param method
086             * @param methodArgs
087             */
088            private void storeArgs(Method method, Array methodArgs) {
089                    
090                    Class[] pmt = method.getParameterTypes();
091                    Object o=methodArgs.get(pmt.length+1,null);
092                    Method[] args;
093                    if(o==null) {
094                            args=new Method[1];
095                            methodArgs.setEL(pmt.length+1,args);
096                    }
097                    else {
098                            Method[] ms = (Method[]) o;
099                            args = new Method[ms.length+1];
100                            for(int i=0;i<ms.length;i++) {
101                                    args[i]=ms[i];
102                            }
103                            methodArgs.setEL(pmt.length+1,args);
104                    }
105                    args[args.length-1]=method;
106            }
107    }