01: /*
02: * This software is released under a licence similar to the Apache Software Licence.
03: * See org.logicalcobwebs.proxool.package.html for details.
04: * The latest version is available at http://proxool.sourceforge.net
05: */
06: package org.logicalcobwebs.proxool.proxy;
07:
08: import org.logicalcobwebs.proxool.ProxoolException;
09:
10: import java.util.Map;
11: import java.util.HashMap;
12: import java.lang.reflect.Method;
13: import java.lang.reflect.Modifier;
14:
15: /**
16: * Invokes a method using a cached method.
17: * @version $Revision: 1.3 $, $Date: 2004/07/13 21:13:14 $
18: * @author billhorsman
19: * @author $Author: billhorsman $ (current maintainer)
20: * @since Proxool 0.9
21: */
22: public class InvokerFacade {
23:
24: private static Map methodMappers = new HashMap();
25:
26: /**
27: * Returns the method in the concrete class with an indentical signature to that passed
28: * @param concreteClass the class that we want to invoke methods on. It should either implement all methods on
29: * the injectable interface, or provide methods with an identical signature.
30: * @param injectableMethod provides signature that we are trying to match
31: * @return the method in the concrete class that we can invoke as if it were in the interface
32: * @throws org.logicalcobwebs.proxool.ProxoolException if the method is not found.
33: */
34: public static Method getConcreteMethod(Class concreteClass,
35: Method injectableMethod) throws ProxoolException {
36: // Unless the concrete class is public we can't do anything
37: if (Modifier.isPublic(concreteClass.getModifiers())) {
38: Object key = concreteClass.getName() + ":"
39: + injectableMethod.getName();
40: MethodMapper methodMapper = (MethodMapper) methodMappers
41: .get(key);
42: if (methodMapper == null) {
43: methodMapper = new MethodMapper(concreteClass);
44: methodMappers.put(key, methodMapper);
45: }
46: return methodMapper.getConcreteMethod(injectableMethod);
47: } else {
48: return injectableMethod;
49: }
50: }
51:
52: /**
53: * Override the method provided by the {@link #getConcreteMethod(java.lang.Class, java.lang.reflect.Method)}. Use this
54: * if you decide that the concrete method provided wasn't any good. For instance, if you get an IllegalAccessException
55: * whilst invoking the concrete method then you should perhaps try using the proxy supplied method instead.
56: * @param concreteClass the class we are invoking upon
57: * @param injectableMethod the method supplied by the proxy
58: * @param overridenMethod the one we are going to use (probably the same as injectrableMethod actually)
59: */
60: public static void overrideConcreteMethod(Class concreteClass,
61: Method injectableMethod, Method overridenMethod) {
62: Object key = concreteClass.getName() + ":"
63: + injectableMethod.getName();
64: MethodMapper methodMapper = (MethodMapper) methodMappers
65: .get(key);
66: if (methodMapper == null) {
67: methodMapper = new MethodMapper(concreteClass);
68: methodMappers.put(key, methodMapper);
69: }
70: methodMapper.overrideConcreteMethod(injectableMethod,
71: overridenMethod);
72: }
73:
74: }
75: /*
76: Revision history:
77: $Log: InvokerFacade.java,v $
78: Revision 1.3 2004/07/13 21:13:14 billhorsman
79: Optimise using injectable interfaces on methods that are declared in non-public classes by not bothering to use concrete methods at all (it's not possible).
80:
81: Revision 1.2 2004/07/13 21:06:16 billhorsman
82: Fix problem using injectable interfaces on methods that are declared in non-public classes.
83:
84: Revision 1.1 2004/06/02 20:43:53 billhorsman
85: New classes to support injectable interfaces
86:
87: */
|