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.SerializationUtil; 10 import com.tc.object.TCObject; 11 import com.tc.object.TraversedReferences; 12 import com.tc.object.bytecode.Manageable; 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.LogicalAction; 17 import com.tc.object.dna.api.PhysicalAction; 18 import com.tc.object.dna.impl.DNAEncoding; 19 import com.tc.object.tx.optimistic.OptimisticTransactionManager; 20 import com.tc.object.tx.optimistic.TCObjectClone; 21 import com.tc.util.Assert; 22 import com.tc.util.FieldUtils; 23 24 import java.io.IOException ; 25 import java.lang.reflect.Field ; 26 import java.util.Collection ; 27 import java.util.Comparator ; 28 import java.util.IdentityHashMap ; 29 import java.util.Iterator ; 30 import java.util.Map ; 31 import java.util.TreeMap ; 32 import java.util.Map.Entry; 33 34 public class TreeMapApplicator extends BaseApplicator { 35 36 static final String COMPARATOR_FIELDNAME = "java.util.TreeMap.comparator"; 37 private static final Field COMPARATOR_FIELD; 38 39 static { 40 try { 41 Field field = TreeMap .class.getDeclaredField("comparator"); 42 field.setAccessible(true); 43 COMPARATOR_FIELD = field; 44 } catch (Exception e) { 45 throw new RuntimeException (e); 46 } 47 } 48 49 public TreeMapApplicator(DNAEncoding encoding) { 50 super(encoding); 51 } 52 53 57 public Map connectedCopy(Object source, Object dest, Map visited, ClientObjectManager objectManager, 58 OptimisticTransactionManager txManager) { 59 Map cloned = new IdentityHashMap (); 60 61 Manageable sourceManageable = (Manageable) source; 62 Manageable destManaged = (Manageable) dest; 63 64 TreeMap sourceMap = (TreeMap ) source; 65 TreeMap destMap = (TreeMap ) dest; 66 67 for (Iterator i = sourceMap.entrySet().iterator(); i.hasNext();) { 68 Entry e = (Entry) i.next(); 69 70 Object k = e.getKey(); 71 Object v = e.getValue(); 72 73 Object copyKey = createCopyIfNecessary(objectManager, visited, cloned, k); 74 Object copyValue = createCopyIfNecessary(objectManager, visited, cloned, v); 75 76 destMap.put(copyKey, copyValue); 77 } 78 79 Comparator comparatorOrig = sourceMap.comparator(); 81 Comparator copyValue = (Comparator ) createCopyIfNecessary(objectManager, visited, cloned, comparatorOrig); 82 setComparator(destMap, copyValue); 84 85 destManaged.__tc_managed(new TCObjectClone(sourceManageable.__tc_managed(), txManager)); 86 87 return cloned; 88 } 89 90 public TraversedReferences getPortableObjects(Object pojo, TraversedReferences addTo) { 91 TreeMap treemap = (TreeMap ) pojo; 92 filterPortableObjects(treemap.keySet(), addTo); 93 filterPortableObjects(treemap.values(), addTo); 94 filterPortableObject(treemap.comparator(), addTo); 95 return addTo; 96 } 97 98 private void filterPortableObjects(Collection objects, TraversedReferences addTo) { 99 for (Iterator i = objects.iterator(); i.hasNext();) { 100 Object value = i.next(); 101 filterPortableObject(value, addTo); 102 } 103 } 104 105 private void filterPortableObject(Object value, TraversedReferences addTo) { 106 if (value != null && isPortableReference(value.getClass())) { 107 addTo.addAnonymousReference(value); 108 } 109 } 110 111 public void hydrate(ClientObjectManager objectManager, TCObject tcObject, DNA dna, Object po) throws IOException , 112 ClassNotFoundException { 113 Map m = (Map ) po; 114 DNACursor cursor = dna.getCursor(); 115 116 while (cursor.next(encoding)) { 117 Object action = cursor.getAction(); 118 if (action instanceof PhysicalAction) { 119 PhysicalAction pa = (PhysicalAction) action; 121 Assert.assertEquals(COMPARATOR_FIELDNAME, pa.getFieldName()); 122 Comparator c = (Comparator ) objectManager.lookupObject((ObjectID) pa.getObject()); 123 setComparator(po, c); 124 } else { 125 LogicalAction la = (LogicalAction) action; 126 int method = la.getMethod(); 127 Object [] params = la.getParameters(); 128 switch (method) { 129 case SerializationUtil.PUT: 130 Object k = params[0]; 131 Object v = params[1]; 132 Object pkey = k instanceof ObjectID ? objectManager.lookupObject((ObjectID) k) : k; 133 Object value = v instanceof ObjectID ? objectManager.lookupObject((ObjectID) v) : v; 134 m.put(pkey, value); 135 break; 136 case SerializationUtil.REMOVE: 137 Object rkey = params[0] instanceof ObjectID ? objectManager.lookupObject((ObjectID) params[0]) : params[0]; 138 m.remove(rkey); 139 break; 140 case SerializationUtil.CLEAR: 141 m.clear(); 142 break; 143 default: 144 throw new AssertionError ("invalid action:" + method); 145 } 146 } 147 } 148 } 149 150 private void setComparator(Object target, Object value) { 151 try { 152 FieldUtils.tcSet(target, value, COMPARATOR_FIELD); 153 } catch (Exception e) { 154 throw new RuntimeException (e); 155 } 156 } 157 158 public void dehydrate(ClientObjectManager objectManager, TCObject tcObject, DNAWriter writer, Object pojo) { 159 TreeMap map = (TreeMap ) pojo; 160 161 Comparator cmp = map.comparator(); 162 final Object cmpObj = getDehydratableObject(cmp, objectManager); 163 if (cmpObj != null) { 164 writer.addPhysicalAction(COMPARATOR_FIELDNAME, cmpObj); 165 } 166 167 for (Iterator i = map.entrySet().iterator(); i.hasNext();) { 168 Entry entry = (Entry) i.next(); 169 Object key = entry.getKey(); 170 Object value = entry.getValue(); 171 172 if (!objectManager.isPortableInstance(key)) { 173 continue; 174 } 175 if (!objectManager.isPortableInstance(value)) { 176 continue; 177 } 178 179 final Object addKey = getDehydratableObject(key, objectManager); 180 final Object addValue = getDehydratableObject(value, objectManager); 181 182 if (addKey == null || addValue == null) { 183 continue; 184 } 185 186 writer.addLogicalAction(SerializationUtil.PUT, new Object [] { addKey, addValue }); 187 } 188 189 } 190 191 public Object getNewInstance(ClientObjectManager objectManager, DNA dna) throws IOException , ClassNotFoundException { 192 DNACursor cursor = dna.getCursor(); 193 if (!cursor.next(encoding)) { throw new AssertionError ("Cursor is empty in TreeMap.getNewInstance()"); } 194 PhysicalAction physicalAction = cursor.getPhysicalAction(); 195 Assert.assertEquals(COMPARATOR_FIELDNAME, physicalAction.getFieldName()); 196 Comparator c = (Comparator ) objectManager.lookupObject((ObjectID) physicalAction.getObject()); 197 return (c == null ? new TreeMap () : new TreeMap (c)); 198 } 199 } 200 | Popular Tags |