[Proxool-cvs] proxool/src/java/org/logicalcobwebs/proxool/proxy InvokerFacade.java,NONE,1.1 MethodMa
UNMAINTAINED!
Brought to you by:
billhorsman
From: <bil...@us...> - 2004-06-02 20:44:02
|
Update of /cvsroot/proxool/proxool/src/java/org/logicalcobwebs/proxool/proxy In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18586/src/java/org/logicalcobwebs/proxool/proxy Added Files: InvokerFacade.java MethodMapper.java Log Message: New classes to support injectable interfaces --- NEW FILE: InvokerFacade.java --- /* * This software is released under a licence similar to the Apache Software Licence. * See org.logicalcobwebs.proxool.package.html for details. * The latest version is available at http://proxool.sourceforge.net */ package org.logicalcobwebs.proxool.proxy; import org.logicalcobwebs.proxool.ProxoolException; import java.util.Map; import java.util.HashMap; import java.lang.reflect.Method; /** * Invokes a method using a cached method. * @version $Revision: 1.1 $, $Date: 2004/06/02 20:43:53 $ * @author billhorsman * @author $Author: billhorsman $ (current maintainer) * @since Proxool 0.9 */ public class InvokerFacade { private static Map methodMappers = new HashMap(); /** * Returns the method in the concrete class with an indentical signature to that passed * @param concreteClass the class that we want to invoke methods on. It should either implement all methods on * the injectable interface, or provide methods with an identical signature. * @param injectableMethod provides signature that we are trying to match * @return the method in the concrete class that we can invoke as if it were in the interface * @throws org.logicalcobwebs.proxool.ProxoolException if the method is not found. */ public static Method getConcreteMethod(Class concreteClass, Method injectableMethod) throws ProxoolException { Object key = concreteClass.getName() + ":" + injectableMethod.getName(); MethodMapper methodMapper = (MethodMapper) methodMappers.get(key); if (methodMapper == null) { methodMapper = new MethodMapper(concreteClass); methodMappers.put(key, methodMapper); } return methodMapper.getConcreteMethod(injectableMethod); } } /* Revision history: $Log: InvokerFacade.java,v $ Revision 1.1 2004/06/02 20:43:53 billhorsman New classes to support injectable interfaces */ --- NEW FILE: MethodMapper.java --- /* * This software is released under a licence similar to the Apache Software Licence. * See org.logicalcobwebs.proxool.package.html for details. * The latest version is available at http://proxool.sourceforge.net */ package org.logicalcobwebs.proxool.proxy; import org.logicalcobwebs.proxool.ProxoolException; import java.lang.reflect.Method; import java.util.Map; import java.util.HashMap; /** * Handles the mapping between methods with identical signatures but that are not related * by inheritance. This allows you to invoke a method on a class using an interface that * it doesn't actually implement. It caches the result of its reflective lookup to save time. * If the concreteClass does in fact implement the injectable interface then it quickly * returns the method without the penalty of mapping using reflection. * * @author <a href="mailto:bi...@lo...">Bill Horsman</a> * @author $Author: billhorsman $ (current maintainer) * @version $Revision: 1.1 $, $Date: 2004/06/02 20:43:53 $ * @since Proxool 0.9 */ public class MethodMapper { private Class concreteClass; private Map cachedConcreteMethods = new HashMap(); ; /** * @param concreteClass the class that we want to invoke methods on. It should either implement all methods on * the injectable interface, or provide methods with an identical signature. */ public MethodMapper(Class concreteClass) { this.concreteClass = concreteClass; } /** * Returns the method in the concrete class with an indentical signature to that passed * as a parameter * * @param injectableMethod provides signature that we are trying to match * @return the method in the concrete class that we can invoke as if it were in the interface * @throws org.logicalcobwebs.proxool.ProxoolException * if the method is not found. */ protected Method getConcreteMethod(Method injectableMethod) throws ProxoolException { // Do we have a cached reference? Method concreteMethod = (Method) cachedConcreteMethods.get(injectableMethod); if (concreteMethod == null) { // Look it up Method[] candidateMethods = concreteClass.getMethods(); for (int i = 0; i < candidateMethods.length; i++) { Method candidateMethod = candidateMethods[i]; // First pass: does the name, parameter count and return type match? if (candidateMethod.getName().equals(injectableMethod.getName()) && candidateMethod.getParameterTypes().length == injectableMethod.getParameterTypes().length && candidateMethod.getReturnType().equals(injectableMethod.getReturnType())) { // Let's check each parameter type boolean matches = true; Class[] candidateTypes = candidateMethod.getParameterTypes(); Class[] injectableTypes = injectableMethod.getParameterTypes(); for (int j = 0; j < candidateTypes.length; j++) { if (!candidateTypes[j].equals(injectableTypes[j])) { matches = false; break; } } if (matches) { concreteMethod = candidateMethod; break; } } } // Success? if (concreteMethod == null) { throw new ProxoolException("Couldn't match injectable method " + injectableMethod + " with any of those " + "found in " + concreteClass.getName()); } // Remember it cachedConcreteMethods.put(injectableMethod, concreteMethod); } return concreteMethod; } } /* Revision history: $Log: MethodMapper.java,v $ Revision 1.1 2004/06/02 20:43:53 billhorsman New classes to support injectable interfaces */ |