KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > dynaop > CglibProxyHandle


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.Field JavaDoc;
8 import java.lang.reflect.Method JavaDoc;
9 import java.lang.reflect.Modifier JavaDoc;
10 import java.util.ArrayList JavaDoc;
11 import java.util.Arrays JavaDoc;
12 import java.util.Iterator JavaDoc;
13 import java.util.List JavaDoc;
14
15 import dynaop.util.Classes;
16 import dynaop.util.Closure;
17 import dynaop.util.NestedException;
18
19 import net.sf.cglib.Enhancer;
20 import net.sf.cglib.Factory;
21 import net.sf.cglib.MethodInterceptor;
22 import net.sf.cglib.MethodProxy;
23
24 /**
25  * Serializable handle for cglib proxies. Creates unproxied version and
26  * serializes method interceptor and recreates proxy on the other end.
27  *
28  * @author Bob Lee (crazybob@crazybob.org)
29  */

30 class CglibProxyHandle implements Handle, Serializable JavaDoc {
31
32     static long serialVersionUID = 0;
33
34     static MethodInterceptor MOCK_INTERCEPTOR = new MethodInterceptor() {
35         public Object JavaDoc intercept(Object JavaDoc proxy, Method JavaDoc method, Object JavaDoc[] arguments,
36                 MethodProxy methodProxy) throws Throwable JavaDoc {
37             throw new IllegalStateException JavaDoc(
38                 "Cannot invoke proxy during deserialization.");
39         }
40     };
41     
42     transient Proxy proxy;
43     
44     CglibProxyHandle(Proxy proxy) {
45         this.proxy = proxy;
46     }
47
48     public Proxy getProxy() {
49         return this.proxy;
50     }
51     
52     private void writeObject(ObjectOutputStream JavaDoc out) throws IOException JavaDoc {
53         // write interfaces.
54
List JavaDoc interfaces =
55             filterInterfaces(this.proxy.getClass().getInterfaces());
56         out.writeInt(interfaces.size());
57         for (Iterator JavaDoc i = interfaces.iterator(); i.hasNext();)
58             out.writeUTF(((Class JavaDoc) i.next()).getName());
59         
60         out.writeUTF(proxy.getClass().getSuperclass().getName());
61         
62         // write method interceptor.
63
out.writeObject(Enhancer.getMethodInterceptor(this.proxy));
64
65         out.writeObject(unwrap());
66     }
67     
68     Object JavaDoc unwrap() {
69         Object JavaDoc unwrapped;
70         try {
71             unwrapped = proxy.getClass().getSuperclass().newInstance();
72         }
73         catch (Exception JavaDoc e) {
74             throw NestedException.wrap(e);
75         }
76         execute(fieldCopier(this.proxy, unwrapped), unwrapped.getClass());
77         
78         return unwrapped;
79     }
80     
81     private void readObject(ObjectInputStream JavaDoc in) throws IOException JavaDoc,
82             ClassNotFoundException JavaDoc {
83         // read interfaces.
84
int size = in.readInt();
85         List JavaDoc interfaces = new ArrayList JavaDoc();
86         for (int i = 0; i < size; i++)
87             interfaces.add(Classes.getClassLoader().loadClass(in.readUTF()));
88         
89         Class JavaDoc unproxiedClass = Classes.getClassLoader().loadClass(in.readUTF());
90         
91         // create proxy.
92
List JavaDoc allClasses = new ArrayList JavaDoc(interfaces);
93         allClasses.add(unproxiedClass);
94         this.proxy = (Proxy) Enhancer.enhance(
95             unproxiedClass,
96             (Class JavaDoc[]) interfaces.toArray(new Class JavaDoc[interfaces.size()]),
97             MOCK_INTERCEPTOR,
98             Classes.commonLoader(allClasses),
99             null,
100             ClassProxyCreator.METHOD_FILTER
101         );
102         
103         // read method interceptor.
104
MethodInterceptor interceptor = (MethodInterceptor) in.readObject();
105         
106         // read unproxied version.
107
Object JavaDoc unproxied = in.readObject();
108
109         execute(fieldCopier(unproxied, this.proxy),
110             unproxied.getClass());
111
112         ((Factory) this.proxy).interceptor(interceptor);
113     }
114     
115     /**
116      * Executes closure against every field in clazz.
117      */

118     void execute(Closure closure, Class JavaDoc clazz) {
119         while (!clazz.equals(Object JavaDoc.class)) {
120             Field JavaDoc[] fields = clazz.getDeclaredFields();
121             for (int i = 0; i < fields.length; i++) {
122                 fields[i].setAccessible(true);
123                 
124                 // we can't set final fields. :(
125
if (Modifier.isFinal(fields[i].getModifiers()))
126                     continue;
127                 
128                 closure.execute(fields[i]);
129             }
130             clazz = clazz.getSuperclass();
131         }
132     }
133
134     /**
135      * Filters out cglib interfaces.
136      */

137     static List JavaDoc filterInterfaces(Class JavaDoc[] interfaces) {
138         List JavaDoc interfaceList = new ArrayList JavaDoc(Arrays.asList(interfaces));
139         for (Iterator JavaDoc i = interfaceList.iterator(); i.hasNext();)
140             if (((Class JavaDoc) i.next()).getName().startsWith("net.sf.cglib."))
141                 i.remove();
142         return interfaceList;
143     }
144     
145     Closure fieldCopier(final Object JavaDoc src, final Object JavaDoc dst) {
146         return new Closure() {
147             public void execute(Object JavaDoc o) {
148                 Field JavaDoc field = (Field JavaDoc) o;
149                 try {
150                     field.set(dst, field.get(src));
151                 }
152                 catch (Exception JavaDoc e) {
153                     throw NestedException.wrap(e);
154                 }
155             }
156         };
157     }
158 }
159
Popular Tags