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<Class,Struct> map=new ReferenceMap(ReferenceMap.SOFT,ReferenceMap.SOFT); 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 synchronized Method[] getMethods(Class clazz,Collection.Key methodName, int count) { 030 Struct methodsMap = map.get(clazz); 031 if(methodsMap==null) 032 methodsMap=store(clazz); 033 034 Object o = methodsMap.get(methodName,null); 035 if(o==null) return null; 036 Array methods=(Array) o; 037 o=methods.get(count+1,null); 038 if(o==null) return null; 039 return (Method[]) o; 040 } 041 042 043 /** 044 * store a class with his methods 045 * @param clazz 046 * @return returns stored struct 047 */ 048 private StructImpl store(Class clazz) { 049 Method[] methodsArr=clazz.getMethods(); 050 StructImpl methodsMap=new StructImpl(); 051 for(int i=0;i<methodsArr.length;i++) { 052 storeMethod(methodsArr[i],methodsMap); 053 054 } 055 map.put(clazz,methodsMap); 056 return methodsMap; 057 } 058 059 /** 060 * stores a single method 061 * @param method 062 * @param methodsMap 063 */ 064 private void storeMethod(Method method, StructImpl methodsMap) { 065 Key methodName = KeyImpl.init(method.getName()); 066 067 068 Object o=methodsMap.get(methodName,null); 069 Array methodArgs; 070 if(o==null) { 071 methodArgs=new ArrayImpl(); 072 methodsMap.setEL(methodName,methodArgs); 073 } 074 else methodArgs=(Array) o; 075 storeArgs(method,methodArgs); 076 //Modifier.isStatic(method.getModifiers()); 077 } 078 079 /** 080 * stores arguments of a method 081 * @param method 082 * @param methodArgs 083 */ 084 private void storeArgs(Method method, Array methodArgs) { 085 086 Class[] pmt = method.getParameterTypes(); 087 Object o=methodArgs.get(pmt.length+1,null); 088 Method[] args; 089 if(o==null) { 090 args=new Method[1]; 091 methodArgs.setEL(pmt.length+1,args); 092 } 093 else { 094 Method[] ms = (Method[]) o; 095 args = new Method[ms.length+1]; 096 for(int i=0;i<ms.length;i++) { 097 args[i]=ms[i]; 098 } 099 methodArgs.setEL(pmt.length+1,args); 100 } 101 args[args.length-1]=method; 102 } 103 }