KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > object > TCObjectPhysical


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
3  * notice. All rights reserved.
4  */

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 JavaDoc;
16 import java.util.HashMap JavaDoc;
17 import java.util.Map JavaDoc;
18
19 public class TCObjectPhysical extends TCObjectImpl {
20   private Map references = null;
21
22   public TCObjectPhysical(ReferenceQueue JavaDoc queue, ObjectID id, Object JavaDoc 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 JavaDoc 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 JavaDoc checkArrayIndex(int index) {
62     Object JavaDoc[] po = (Object JavaDoc[]) getPeerObject();
63     if (index >= po.length || index < 0) {
64       //
65
return new ArrayIndexOutOfBoundsException JavaDoc(index);
66     }
67     return null;
68   }
69
70   public final void resolveArrayReference(int index) {
71     this.markAccessed();
72
73     Object JavaDoc[] po = (Object JavaDoc[]) 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 JavaDoc o;
83       try {
84         o = getObjectManager().lookupObject(id);
85       } catch (ClassNotFoundException JavaDoc e) {
86         throw new TCClassNotFoundException(e);
87       }
88       po[index] = o;
89     }
90   }
91
92   public void setReference(String JavaDoc fieldName, ObjectID id) {
93     synchronized (getResolveLock()) {
94       getReferences().put(fieldName, id);
95     }
96   }
97
98   public void clearReference(String JavaDoc fieldName) {
99     synchronized (getResolveLock()) {
100       if (hasReferences()) {
101         removeReference(fieldName);
102       }
103     }
104   }
105
106   public final void resolveReference(String JavaDoc fieldName) {
107     synchronized (getResolveLock()) {
108       this.markAccessed();
109       if (!hasReferences()) return;
110
111       Object JavaDoc 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       // Already resolved
119
if (id == null) { return; }
120
121       Object JavaDoc setObject = null;
122       if (id != null && !id.isNull()) {
123         try {
124           setObject = getObjectManager().lookupObject(id);
125         } catch (ClassNotFoundException JavaDoc 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 JavaDoc methodSignature, Object JavaDoc[] params) {
135     throw new UnsupportedOperationException JavaDoc();
136   }
137
138   public void literalValueChanged(Object JavaDoc newValue, Object JavaDoc oldValue) {
139     getObjectManager().getTransactionManager().literalValueChanged(this, newValue, oldValue);
140     setPeerObject(new WeakObjectReference(getObjectID(), newValue, getObjectManager().getReferenceQueue()));
141   }
142
143   /**
144    * Unlike literalValueChange, this method is not synchronized on getResolveLock() because this method is called by the
145    * applicator thread which has been synchronized on getResolveLock() in TCObjectImpl.hydrate().
146    */

147   public void setLiteralValue(Object JavaDoc 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 JavaDoc pojo, int toClear) {
156     if (tcClazz.isIndexed()) {
157       if (ClassUtils.isPrimitiveArray(pojo)) return 0;
158       return clearArrayReferences((Object JavaDoc[]) 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 JavaDoc[] array) {
167     int cleared = 0;
168     int l = array.length;
169     for (int i = 0; i < l; i++) {
170       Object JavaDoc 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         // lazy instantiation. TODO:: Add a new method in TransparentAccess __tc_getFieldNoResolve()
192
fieldValues = new HashMap();
193         ta.__tc_getallfields(fieldValues);
194       }
195       Object JavaDoc 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