1 5 package com.tc.object.applicator; 6 7 import com.tc.object.ClientObjectManager; 8 import com.tc.object.ObjectID; 9 import com.tc.object.TCObject; 10 import com.tc.object.TraversedReferences; 11 import com.tc.object.bytecode.ManagerUtil; 12 import com.tc.object.bytecode.hook.impl.ArrayManager; 13 import com.tc.object.dna.api.DNA; 14 import com.tc.object.dna.api.DNACursor; 15 import com.tc.object.dna.api.DNAWriter; 16 import com.tc.object.dna.api.PhysicalAction; 17 import com.tc.object.dna.impl.DNAEncoding; 18 import com.tc.object.tx.optimistic.OptimisticTransactionManager; 19 import com.tc.object.tx.optimistic.TCObjectClone; 20 import com.tc.util.Assert; 21 import com.tc.util.ClassUtils; 22 23 import java.io.IOException ; 24 import java.lang.reflect.Array ; 25 import java.util.Collections ; 26 import java.util.IdentityHashMap ; 27 import java.util.Map ; 28 29 32 public class ArrayApplicator extends BaseApplicator { 33 34 public ArrayApplicator(DNAEncoding encoding) { 35 super(encoding); 36 } 37 38 public TraversedReferences getPortableObjects(Object pojo, TraversedReferences addTo) { 39 if (ClassUtils.isPrimitiveArray(pojo)) { return addTo; } 40 41 Object [] array = (Object []) pojo; 42 43 for (int i = 0, len = array.length; i < len; i++) { 44 Object o = array[i]; 45 if (o != null && isPortableReference(o.getClass())) { 46 addTo.addAnonymousReference(o); 47 } 48 } 49 return addTo; 50 } 51 52 public void hydrate(ClientObjectManager objectManager, TCObject tcObject, DNA dna, Object po) throws IOException , 53 IllegalArgumentException , ClassNotFoundException { 54 DNACursor cursor = dna.getCursor(); 55 56 while (cursor.next(encoding)) { 57 PhysicalAction a = cursor.getPhysicalAction(); 58 59 if (a.isArrayElement()) { 60 setArrayElement(a.getArrayIndex(), a.getObject(), tcObject, po); 61 } else if (a.isEntireArray() || a.isSubArray()) { 62 Object array = a.getObject(); 63 int offset = a.isEntireArray() ? 0 : a.getArrayIndex(); 64 65 if (ClassUtils.isPrimitiveArray(array)) { 66 System.arraycopy(array, 0, po, offset, Array.getLength(array)); 67 } else { 68 hydrateNonPrimitiveArray((Object []) array, tcObject, po, offset); 69 } 70 } else { 71 throw Assert.failure("Invalid physical action for array"); 72 } 73 } 74 } 75 76 private static void hydrateNonPrimitiveArray(Object [] source, TCObject tcObject, Object pojo, int offset) { 77 for (int i = 0, n = source.length; i < n; i++) { 78 setArrayElement(offset + i, source[i], tcObject, pojo); 79 } 80 } 81 82 private static void setArrayElement(int index, Object value, TCObject tcObject, Object pojo) { 83 String fieldName = String.valueOf(index); 84 if (value instanceof ObjectID) { 85 tcObject.setReference(fieldName, (ObjectID) value); 86 } else { 87 tcObject.clearReference(fieldName); 88 Array.set(pojo, index, value); 91 } 92 } 93 94 public void dehydrate(ClientObjectManager objectManager, TCObject tcObject, DNAWriter writer, Object pojo) { 95 writer.setArrayLength(Array.getLength(pojo)); 96 97 if (ClassUtils.isPrimitiveArray(pojo)) { 98 writer.addEntireArray(pojo); 99 } else { 100 Object [] array = (Object []) pojo; 101 Object [] toEncode = new Object [array.length]; 102 103 for (int i = 0, n = array.length; i < n; i++) { 105 Object element = array[i]; 106 if (!objectManager.isPortableInstance(element)) { 107 toEncode[i] = ObjectID.NULL_ID; 108 continue; 109 } 110 111 final Object obj = getDehydratableObject(element, objectManager); 112 if (obj == null) { 113 toEncode[i] = ObjectID.NULL_ID; 114 } else { 115 toEncode[i] = obj; 116 } 117 } 118 119 writer.addEntireArray(toEncode); 120 } 121 } 122 123 public Object getNewInstance(ClientObjectManager objectManager, DNA dna) { 124 throw new UnsupportedOperationException (); 125 } 126 127 public Map connectedCopy(Object source, Object dest, Map visited, ClientObjectManager objectManager, 128 OptimisticTransactionManager txManager) { 129 if (source.getClass().getComponentType().isPrimitive()) { 130 System.arraycopy(source, 0, dest, 0, Array.getLength(dest)); 131 return Collections.EMPTY_MAP; 132 } 133 134 Map cloned = new IdentityHashMap (); 135 136 Object [] da = (Object []) dest; 137 Object [] sa = (Object []) source; 138 int len = da.length; 139 for (int i = 0; i < len; i++) { 140 Object v = sa[i]; 141 da[i] = createCopyIfNecessary(objectManager, visited, cloned, v); 142 } 143 144 ManagerUtil.register(dest, new TCObjectClone(ArrayManager.getCloneObject(source), txManager, len)); 146 return cloned; 147 } 148 } 149 | Popular Tags |