1 /************************************************* 2 * Copyright (c) Shen Li. All rights reserved. * 3 * http://joyaop.sourceforge.net * 4 * -------------------------------------------- * 5 * Distributable under LGPL license. * 6 * See terms of license at gnu.org. * 7 ************************************************/ 8 package net.sf.joyaop.impl; 9 10 import net.sf.cglib.proxy.Callback; 11 import net.sf.cglib.proxy.CallbackFilter; 12 import net.sf.cglib.proxy.Enhancer; 13 import net.sf.cglib.proxy.Factory; 14 import net.sf.joyaop.AspectRuntimeException; 15 import net.sf.joyaop.util.ClassUtils; 16 17 import java.io.IOException; 18 import java.io.ObjectInputStream; 19 import java.io.ObjectOutputStream; 20 import java.io.Serializable; 21 import java.lang.reflect.Field; 22 import java.lang.reflect.Modifier; 23 import java.util.ArrayList; 24 import java.util.Iterator; 25 import java.util.List; 26 27 /*** 28 * @author Shen Li 29 */ 30 public class SerializableProxy implements Serializable { 31 private static final long serialVersionUID = 0; 32 private Object proxy; 33 private Class[] interfaceClasses; 34 private CallbackFilter callbackFilter; 35 36 public SerializableProxy(Object proxy, Class[] interfaceClasses, CallbackFilter callbackFilter) { 37 this.proxy = proxy; 38 this.interfaceClasses = interfaceClasses; 39 this.callbackFilter = callbackFilter; 40 } 41 42 public Object readResolve() { 43 return proxy; 44 } 45 46 private void writeObject(ObjectOutputStream out) throws IOException { 47 out.writeObject(((Factory) proxy).getCallbacks()); 48 out.writeObject(proxy.getClass().getSuperclass()); 49 out.writeObject(getSuperClassFields()); 50 out.writeObject(interfaceClasses); 51 out.writeObject(callbackFilter); 52 } 53 54 private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { 55 Callback[] callbacks = (Callback[]) in.readObject(); 56 Class superClass = (Class) in.readObject(); 57 List fieldValues = (List) in.readObject(); 58 Factory factory = ClassUtils.getProxyFactory(superClass); 59 if (factory == null) { 60 Class[] interfaceClasses = (Class[]) in.readObject(); 61 CallbackFilter callbackFilter = (CallbackFilter) in.readObject(); 62 Enhancer enhancer = new Enhancer(); 63 enhancer.setSuperclass(superClass); 64 enhancer.setInterfaces(interfaceClasses); 65 enhancer.setCallbacks(callbacks); 66 enhancer.setCallbackFilter(callbackFilter); 67 enhancer.setClassLoader(ClassUtils.getClassLoader()); 68 proxy = enhancer.create(); 69 ClassUtils.putProxyFactory(superClass, (Factory) proxy); 70 } 71 proxy = factory.newInstance(callbacks); 72 setSuperClassFields(fieldValues); 73 } 74 75 private List getSuperClassFields() { 76 final List fields = new ArrayList(); 77 visitSuperClassFields(new FieldVisitor() { 78 public void visit(Field field) { 79 try { 80 fields.add(field.get(proxy)); 81 } catch (IllegalAccessException e) { 82 throw new AspectRuntimeException(e); 83 } 84 } 85 }); 86 return fields; 87 } 88 89 private void setSuperClassFields(List fields) { 90 final Iterator i = fields.iterator(); 91 visitSuperClassFields(new FieldVisitor() { 92 public void visit(Field field) { 93 try { 94 field.set(proxy, (Object) i.next()); 95 } catch (IllegalAccessException e) { 96 throw new AspectRuntimeException(e); 97 } 98 } 99 }); 100 } 101 102 private void visitSuperClassFields(FieldVisitor visitor) { 103 Class clazz = proxy.getClass().getSuperclass(); 104 while (!clazz.equals(Object.class)) { 105 Field[] fields = clazz.getDeclaredFields(); 106 for (int i = 0; i < fields.length; i++) { 107 fields[i].setAccessible(true); 108 int modifiers = fields[i].getModifiers(); 109 if (!Modifier.isFinal(modifiers) && !Modifier.isStatic(modifiers)) { 110 visitor.visit(fields[i]); 111 } 112 } 113 clazz = clazz.getSuperclass(); 114 } 115 } 116 117 private static interface FieldVisitor { 118 void visit(Field field); 119 } 120 }