1 5 package com.tc.object; 6 7 import com.tc.exception.TCClassNotFoundException; 8 import com.tc.object.bytecode.TransparentAccess; 9 import com.tc.object.field.TCField; 10 import com.tc.util.Assert; 11 import com.tc.util.ClassUtils; 12 13 import gnu.trove.THashMap; 14 15 import java.lang.ref.ReferenceQueue ; 16 import java.util.HashMap ; 17 import java.util.Map ; 18 19 public class TCObjectPhysical extends TCObjectImpl { 20 private Map references = null; 21 22 public TCObjectPhysical(ReferenceQueue queue, ObjectID id, Object peer, TCClass tcc) { 23 super(queue, id, peer, tcc); 24 } 25 26 private Map getReferences() { 27 synchronized (getResolveLock()) { 28 if (references == null) { 29 references = new THashMap(0); 30 } 31 return references; 32 } 33 } 34 35 private boolean hasReferences() { 36 return references != null && !references.isEmpty(); 37 } 38 39 private ObjectID removeReference(String fieldName) { 40 synchronized (getResolveLock()) { 41 ObjectID rv = (ObjectID) references.remove(fieldName); 42 if (references.isEmpty()) { 43 references = null; 44 } 45 return rv; 46 } 47 } 48 49 public void resolveAllReferences() { 50 TCClass tcc = getTCClass(); 51 52 while (tcc != null) { 53 TCField[] fields = tcc.getPortableFields(); 54 for (int i = 0; i < fields.length; i++) { 55 if (fields[i].canBeReference()) resolveReference(fields[i].getName()); 56 } 57 tcc = tcc.getSuperclass(); 58 } 59 } 60 61 public ArrayIndexOutOfBoundsException checkArrayIndex(int index) { 62 Object [] po = (Object []) getPeerObject(); 63 if (index >= po.length || index < 0) { 64 return new ArrayIndexOutOfBoundsException (index); 66 } 67 return null; 68 } 69 70 public final void resolveArrayReference(int index) { 71 this.markAccessed(); 72 73 Object [] po = (Object []) getPeerObject(); 74 if (!hasReferences()) return; 75 76 ObjectID id = removeReference(Integer.toString(index)); 77 78 if (id == null) return; 79 if (id.isNull()) { 80 po[index] = null; 81 } else { 82 Object o; 83 try { 84 o = getObjectManager().lookupObject(id); 85 } catch (ClassNotFoundException e) { 86 throw new TCClassNotFoundException(e); 87 } 88 po[index] = o; 89 } 90 } 91 92 public void setReference(String fieldName, ObjectID id) { 93 synchronized (getResolveLock()) { 94 getReferences().put(fieldName, id); 95 } 96 } 97 98 public void clearReference(String fieldName) { 99 synchronized (getResolveLock()) { 100 if (hasReferences()) { 101 removeReference(fieldName); 102 } 103 } 104 } 105 106 public final void resolveReference(String fieldName) { 107 synchronized (getResolveLock()) { 108 this.markAccessed(); 109 if (!hasReferences()) return; 110 111 Object po = getPeerObject(); 112 TCClass tcClass = getTCClass(); 113 Assert.eval(tcClass != null); 114 TCField field = tcClass.getField(fieldName); 115 if (!field.canBeReference()) { return; } 116 117 ObjectID id = (ObjectID) getReferences().get(fieldName); 118 if (id == null) { return; } 120 121 Object setObject = null; 122 if (id != null && !id.isNull()) { 123 try { 124 setObject = getObjectManager().lookupObject(id); 125 } catch (ClassNotFoundException e) { 126 throw new TCClassNotFoundException(e); 127 } 128 } 129 removeReference(fieldName); 130 ((TransparentAccess) po).__tc_setfield(field.getName(), setObject); 131 } 132 } 133 134 public void logicalInvoke(int method, String methodSignature, Object [] params) { 135 throw new UnsupportedOperationException (); 136 } 137 138 public void literalValueChanged(Object newValue, Object oldValue) { 139 getObjectManager().getTransactionManager().literalValueChanged(this, newValue, oldValue); 140 setPeerObject(new WeakObjectReference(getObjectID(), newValue, getObjectManager().getReferenceQueue())); 141 } 142 143 147 public void setLiteralValue(Object newValue) { 148 setPeerObject(new WeakObjectReference(getObjectID(), newValue, getObjectManager().getReferenceQueue())); 149 } 150 151 protected boolean isEvictable() { 152 return true; 153 } 154 155 protected int clearReferences(Object pojo, int toClear) { 156 if (tcClazz.isIndexed()) { 157 if (ClassUtils.isPrimitiveArray(pojo)) return 0; 158 return clearArrayReferences((Object []) pojo); 159 } else if (pojo instanceof TransparentAccess) { 160 return clearObjectReferences((TransparentAccess) pojo); 161 } else { 162 return 0; 163 } 164 } 165 166 private int clearArrayReferences(Object [] array) { 167 int cleared = 0; 168 int l = array.length; 169 for (int i = 0; i < l; i++) { 170 Object o = array[i]; 171 if (o == null) continue; 172 if (getObjectManager().isManaged(o)) { 173 ObjectID lid = getObjectManager().lookupExistingObjectID(o); 174 setReference(Integer.toString(i), lid); 175 array[i] = null; 176 cleared++; 177 } 178 } 179 return cleared; 180 } 181 182 private int clearObjectReferences(TransparentAccess ta) { 183 TCField[] fields = tcClazz.getPortableFields(); 184 if (fields.length == 0) { return 0; } 185 Map fieldValues = null; 186 int cleared = 0; 187 for (int i = 0; i < fields.length; i++) { 188 TCField field = fields[i]; 189 if (field.isFinal() || !field.canBeReference()) continue; 190 if (fieldValues == null) { 191 fieldValues = new HashMap(); 193 ta.__tc_getallfields(fieldValues); 194 } 195 Object obj = fieldValues.get(field.getName()); 196 if (obj == null) continue; 197 TCObject tobj = getObjectManager().lookupExistingOrNull(obj); 198 if (tobj != null) { 199 ObjectID lid = tobj.getObjectID(); 200 setValue(field.getName(), lid); 201 cleared++; 202 } 203 } 204 return cleared; 205 } 206 } 207 | Popular Tags |