KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > dynaop > ProxyInvocationHandler


1 package dynaop;
2
3 import java.io.IOException JavaDoc;
4 import java.io.ObjectInputStream JavaDoc;
5 import java.io.ObjectOutputStream JavaDoc;
6 import java.io.Serializable JavaDoc;
7 import java.lang.reflect.Method JavaDoc;
8 import java.util.HashMap JavaDoc;
9 import java.util.Map JavaDoc;
10
11 import dynaop.util.*;
12 import dynaop.util.ArrayObject;
13
14 /**
15  *
16  *
17  * @author Bob Lee (crazybob@crazybob.org)
18  */

19 abstract class ProxyInvocationHandler implements ProxyContext, Serializable JavaDoc {
20
21     static Interceptor[] NO_INTERCEPTORS = new Interceptor[0];
22
23     static long serialVersionUID = 0;
24     
25     ProxyType proxyType;
26     Proxy proxy;
27     
28     Map JavaDoc factoryToInterceptor = new HashMap JavaDoc();
29     Map JavaDoc interceptors;
30     
31     ProxyInvocationHandler(ProxyType proxyType) {
32         this.proxyType = proxyType;
33         
34         try {
35             interceptors = (Map JavaDoc) mapClass.newInstance();
36         }
37         catch (Exception JavaDoc e) {
38             throw NestedException.wrap(e);
39         }
40     }
41
42     /**
43      * Must be called after proxy creation.
44      */

45     void setProxy(Proxy proxy) {
46         this.proxy = proxy;
47     }
48     
49     /**
50      * Only calls factory once per proxy instance.
51      */

52     Interceptor createInterceptor(InterceptorFactory factory) {
53         Interceptor interceptor =
54             (Interceptor) factoryToInterceptor.get(factory);
55         if (interceptor == null) {
56             interceptor = factory.create(this.getProxy());
57             factoryToInterceptor.put(factory, interceptor);
58         }
59         return interceptor;
60     }
61     
62     /**
63      * Creates interceptor chain from chain of factories.
64      */

65     Interceptor[] createInterceptors(Object JavaDoc proxy,
66             InterceptorFactory[] factories) {
67         if (factories == null)
68             return NO_INTERCEPTORS;
69
70         Interceptor[] chain = new Interceptor[factories.length];
71         for (int i = 0; i < factories.length; i++)
72             chain[i] = createInterceptor(factories[i]);
73         
74         return chain;
75     }
76
77     class GetProxyContextInterceptor implements Interceptor, Serializable JavaDoc {
78         public Object JavaDoc intercept(Invocation invocation) throws Throwable JavaDoc {
79             return ProxyInvocationHandler.this;
80         }
81     }
82     
83     /**
84      * Gets interceptor chain for given method without performing a defensive
85      * copy.
86      */

87     synchronized Interceptor[] getInternalInterceptors(Method JavaDoc method) {
88         Interceptor[] chain = (Interceptor[]) this.interceptors.get(method);
89
90         if (chain == null) {
91             if (method.getDeclaringClass().equals(Proxy.class)) {
92                 chain = new Interceptor[] { new GetProxyContextInterceptor() };
93             }
94             else {
95                 chain = createInterceptors(
96                     proxy, this.proxyType.getInterceptorFactories(method));
97             }
98             
99             this.interceptors.put(method, chain);
100         }
101
102         return chain;
103     }
104     
105     Object JavaDoc invoke(Object JavaDoc proxy, Object JavaDoc target, Method JavaDoc method,
106             Object JavaDoc[] arguments) throws Throwable JavaDoc {
107         Interceptor[] interceptors = getInternalInterceptors(method);
108         
109         if (interceptors.length == 0)
110             return InvocationImpl.invokeTarget(proxy, target, method, arguments,
111                 isClassProxy());
112         
113         InvocationImpl invocation = new InvocationImpl();
114         
115         invocation.setTarget(target);
116         invocation.setProxy((Proxy) proxy);
117         invocation.setMethod(method);
118         invocation.setArguments(arguments);
119         invocation.setInterceptors(interceptors);
120         invocation.setClassProxy(isClassProxy());
121         
122         return invocation.proceed();
123     }
124     
125     //********************************************************************
126
// serialization methods.
127
//********************************************************************
128

129     private void writeObject(ObjectOutputStream JavaDoc out)
130             throws IOException JavaDoc {
131         out.writeObject(proxyType);
132         out.writeObject(getHandle());
133         out.writeObject(factoryToInterceptor);
134         out.writeObject(MethodHandle.handleMethodKeys(this.interceptors));
135     }
136
137     private void readObject(ObjectInputStream JavaDoc in)
138             throws ClassNotFoundException JavaDoc, IOException JavaDoc {
139         this.proxyType = (ProxyType) in.readObject();
140         this.proxy = ((Handle) in.readObject()).getProxy();
141         this.factoryToInterceptor = (Map JavaDoc) in.readObject();
142         this.interceptors = MethodHandle.unhandleMethodKeys(
143                 (Map JavaDoc) in.readObject());
144     }
145
146     //********************************************************************
147
// ProxyContext methods.
148
//********************************************************************
149

150     public Interceptor[] getInterceptors(Method JavaDoc method) {
151         return (Interceptor[]) ArrayObject.clone(
152             getInternalInterceptors(method));
153     }
154
155     public Proxy getProxy() {
156         return this.proxy;
157     }
158
159     public ProxyType getProxyType() {
160         return this.proxyType;
161     }
162
163     Handle handle;
164         
165     public final synchronized Handle getHandle() {
166         if (this.handle == null)
167             this.handle = createHandle();
168         return this.handle;
169     }
170
171     protected abstract Handle createHandle();
172     
173     // defaults to HashMap. Tries to use IdentityHashMap for performance.
174
static Class JavaDoc mapClass = HashMap JavaDoc.class;
175     static {
176         try {
177             mapClass = Class.forName("java.util.IdentityHashMap");
178         }
179         catch (ClassNotFoundException JavaDoc e) {}
180     }
181 }
182
Popular Tags