/** * * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see <http://www.gnu.org/licenses/>. * **/ package lucee.runtime.reflection.storage; import static org.apache.commons.collections4.map.AbstractReferenceMap.ReferenceStrength.SOFT; import java.lang.reflect.Method; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import lucee.runtime.type.Array; import lucee.runtime.type.ArrayImpl; import lucee.runtime.type.Collection; import lucee.runtime.type.Collection.Key; import lucee.runtime.type.KeyImpl; import org.apache.commons.collections4.map.ReferenceMap; /** * Method Storage Class */ public final class SoftMethodStorage { private Map<Class,Map<Key,Array>> map=new ReferenceMap<Class,Map<Key,Array>>(SOFT,SOFT); /** * returns a methods matching given criteria or null if method doesn't exist * @param clazz clazz to get methods from * @param methodName Name of the Method to get * @param count wished count of arguments * @return matching Methods as Array */ public Method[] getMethods(Class clazz,Collection.Key methodName, int count) { Map<Key,Array> methodsMap = map.get(clazz); if(methodsMap==null) methodsMap=store(clazz); Array methods = methodsMap.get(methodName); if(methods==null) return null; Object o = methods.get(count+1,null); if(o==null) return null; return (Method[]) o; } /** * store a class with his methods * @param clazz * @return returns stored struct */ private Map<Key,Array> store(Class clazz) { Method[] methods=clazz.getMethods(); Map<Key,Array> methodsMap=new ConcurrentHashMap<Key, Array>(); for(int i=0;i<methods.length;i++) { storeMethod(methods[i],methodsMap); } map.put(clazz,methodsMap); return methodsMap; } /** * stores a single method * @param method * @param methodsMap */ private synchronized void storeMethod(Method method, Map<Key,Array> methodsMap) { Key methodName = KeyImpl.init(method.getName()); Array methodArgs=methodsMap.get(methodName); if(methodArgs==null) { methodArgs=new ArrayImpl(); methodsMap.put(methodName,methodArgs); } storeArgs(method,methodArgs); //Modifier.isStatic(method.getModifiers()); } /** * stores arguments of a method * @param method * @param methodArgs */ private void storeArgs(Method method, Array methodArgs) { Class[] pmt = method.getParameterTypes(); Object o=methodArgs.get(pmt.length+1,null); Method[] args; if(o==null) { args=new Method[1]; methodArgs.setEL(pmt.length+1,args); } else { Method[] ms = (Method[]) o; args = new Method[ms.length+1]; for(int i=0;i<ms.length;i++) { args[i]=ms[i]; } methodArgs.setEL(pmt.length+1,args); } args[args.length-1]=method; } }