1 4 package com.tc.object.applicator; 5 6 import com.tc.object.ClientObjectManager; 7 import com.tc.object.ObjectID; 8 import com.tc.object.TCObject; 9 import com.tc.object.TraversedReferences; 10 import com.tc.object.bytecode.Manageable; 11 import com.tc.object.bytecode.TransparentAccess; 12 import com.tc.object.dna.api.DNA; 13 import com.tc.object.dna.api.DNACursor; 14 import com.tc.object.dna.api.DNAWriter; 15 import com.tc.object.dna.api.PhysicalAction; 16 import com.tc.object.dna.impl.DNAEncoding; 17 import com.tc.object.tx.optimistic.OptimisticTransactionManager; 18 import com.tc.object.tx.optimistic.TCObjectClone; 19 import com.tc.util.Assert; 20 21 import java.io.IOException ; 22 import java.lang.reflect.InvocationHandler ; 23 import java.lang.reflect.Proxy ; 24 import java.util.IdentityHashMap ; 25 import java.util.Map ; 26 27 30 public class ProxyApplicator extends BaseApplicator { 31 private static final String CLASSLOADER_FIELD_NAME = "java.lang.reflect.Proxy.loader"; 32 private static final String INTERFACES_FIELD_NAME = "java.lang.reflect.Proxy.interfaces"; 33 private static final String INVOCATION_HANDLER_FIELD_NAME = "java.lang.reflect.Proxy.h"; 34 35 public ProxyApplicator(DNAEncoding encoding) { 36 super(encoding); 37 } 38 39 public TraversedReferences getPortableObjects(Object pojo, TraversedReferences addTo) { 40 addTo.addAnonymousReference(Proxy.getInvocationHandler(pojo)); 41 return addTo; 42 } 43 44 public void hydrate(ClientObjectManager objectManager, TCObject tcObject, DNA dna, Object po) throws IOException , 45 IllegalArgumentException , ClassNotFoundException { 46 DNACursor cursor = dna.getCursor(); 51 String fieldName; 52 Object fieldValue; 53 54 while (cursor.next(encoding)) { 55 PhysicalAction a = cursor.getPhysicalAction(); 56 Assert.eval(a.isTruePhysical()); 57 fieldName = a.getFieldName(); 58 fieldValue = a.getObject(); 59 60 if (fieldName.equals(INVOCATION_HANDLER_FIELD_NAME)) { 61 fieldValue = objectManager.lookupObject((ObjectID) fieldValue); 62 ((TransparentAccess) po).__tc_setfield(fieldName, fieldValue); 63 } 64 } 65 } 66 67 public void dehydrate(ClientObjectManager objectManager, TCObject tcObject, DNAWriter writer, Object pojo) { 68 InvocationHandler handler = Proxy.getInvocationHandler(pojo); 69 Object dehydratableHandler = getDehydratableObject(handler, objectManager); 70 71 writer.addClassLoaderAction(CLASSLOADER_FIELD_NAME, pojo.getClass().getClassLoader()); 73 writer.addPhysicalAction(INTERFACES_FIELD_NAME, pojo.getClass().getInterfaces()); 74 writer.addPhysicalAction(INVOCATION_HANDLER_FIELD_NAME, dehydratableHandler); 75 } 76 77 public Object getNewInstance(ClientObjectManager objectManager, DNA dna) throws IOException , ClassNotFoundException { 78 DNACursor cursor = dna.getCursor(); 79 Assert.assertEquals(3, cursor.getActionCount()); 80 81 cursor.next(encoding); 82 PhysicalAction a = cursor.getPhysicalAction(); 83 ClassLoader loader = (ClassLoader ) a.getObject(); 84 85 cursor.next(encoding); 86 a = cursor.getPhysicalAction(); 87 Object [] values = (Object []) a.getObject(); 88 Class [] interfaces = new Class [values.length]; 89 System.arraycopy(values, 0, interfaces, 0, values.length); 90 91 cursor.next(encoding); 92 a = cursor.getPhysicalAction(); 93 Object handler = a.getObject(); 94 95 handler = objectManager.lookupObject((ObjectID) handler); 96 97 return Proxy.newProxyInstance(loader, interfaces, (InvocationHandler ) handler); 98 } 99 100 public Map connectedCopy(Object source, Object dest, Map visited, ClientObjectManager objectManager, 101 OptimisticTransactionManager txManager) { 102 Map cloned = new IdentityHashMap (); 103 104 Proxy srcProxy = (Proxy ) source; 105 Proxy destProxy = (Proxy ) dest; 106 107 InvocationHandler handler = Proxy.getInvocationHandler(srcProxy); 108 InvocationHandler clonedHandler = (InvocationHandler ) createCopyIfNecessary(objectManager, visited, cloned, handler); 109 110 ((TransparentAccess)destProxy).__tc_setfield(INVOCATION_HANDLER_FIELD_NAME, clonedHandler); 111 112 TCObject srcTCObject = ((Manageable)srcProxy).__tc_managed(); 113 ((Manageable)destProxy).__tc_managed(new TCObjectClone(srcTCObject, txManager)); 114 115 return cloned; 116 } 117 } 118 | Popular Tags |