KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > aspects > versioned > DistributedPOJOState


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.aspects.versioned;
23
24 import org.jboss.aop.Advised;
25 import org.jboss.aop.ClassAdvisor;
26 import org.jboss.aop.InstanceAdvised;
27 import org.jboss.logging.Logger;
28 import org.jboss.tm.TransactionLocal;
29 import org.jboss.util.id.GUID;
30
31 import javax.naming.InitialContext JavaDoc;
32 import javax.transaction.Transaction JavaDoc;
33 import javax.transaction.TransactionManager JavaDoc;
34
35 import java.lang.ref.WeakReference JavaDoc;
36 import java.lang.reflect.Field JavaDoc;
37 import java.util.HashMap JavaDoc;
38 import java.util.Iterator JavaDoc;
39 import java.util.Map JavaDoc;
40
41
42 /**
43  *
44  * @author <a HREF="mailto:bill@jboss.org">Bill Burke</a>
45  * @version $Revision: 43756 $
46  */

47 public class DistributedPOJOState extends StateManager implements DistributedState, java.io.Externalizable JavaDoc
48 {
49    private static final long serialVersionUID = 7640633352012924284L;
50
51    /**
52     * Logging instance
53     */

54    private static Logger log = Logger.getLogger(DistributedPOJOState.class);
55
56    protected String JavaDoc classname;
57    protected HashMap JavaDoc fieldMap;
58    transient protected TransactionManager JavaDoc tm;
59    transient protected WeakReference JavaDoc advisedRef;
60    transient protected TransactionLocal txState = new TransactionLocal();
61    transient protected SynchronizationManager synchManager;
62    transient protected DistributedVersionManager versionManager;
63
64    public DistributedPOJOState() {}
65
66    public DistributedPOJOState(GUID daguid, long datimeout, Advised advised, DistributedVersionManager versionManager, SynchronizationManager synchManager)
67       throws Exception JavaDoc
68    {
69       super(daguid, datimeout);
70       this.fieldMap = new HashMap JavaDoc();
71       this.classname = advised.getClass().getName();
72       InitialContext JavaDoc ctx = new InitialContext JavaDoc();
73       this.tm = (TransactionManager JavaDoc)ctx.lookup("java:/TransactionManager");
74       this.synchManager = synchManager;
75       this.versionManager = versionManager;
76       this.advisedRef = new WeakReference JavaDoc(advised);
77    }
78
79    public InstanceAdvised getObject()
80    {
81       if (advisedRef != null)
82       {
83          return (InstanceAdvised)advisedRef.get();
84       }
85       return null;
86    }
87
88    public boolean equals(Object JavaDoc obj)
89    {
90       if (!(obj instanceof DistributedPOJOState)) return false;
91       DistributedPOJOState pojo = (DistributedPOJOState)obj;
92       return guid.equals(pojo.guid);
93    }
94
95    public int hashCode()
96    {
97       return guid.hashCode();
98
99    }
100
101    public InstanceAdvised buildObject(SynchronizationManager manager, DistributedVersionManager versionManager)
102       throws Exception JavaDoc
103    {
104       log.trace("building a " + classname + " of guid " + guid);
105       this.versionManager = versionManager;
106       this.synchManager = manager;
107       Class JavaDoc clazz = Thread.currentThread().getContextClassLoader().loadClass(classname);
108       Advised advised = (Advised)clazz.newInstance();
109       this.advisedRef = new WeakReference JavaDoc(advised);
110       versionManager.addVersioning(this, advised);
111       manager.putState(guid, this);
112       manager.putObject(guid, advised);
113
114       Iterator JavaDoc it = fieldMap.values().iterator();
115       while(it.hasNext())
116       {
117          DistributedFieldUpdate update = (DistributedFieldUpdate)it.next();
118          ClassAdvisor advisor = (ClassAdvisor)advised._getAdvisor();
119          log.trace("build field " + advisor.getAdvisedFields()[update.getFieldIndex()].getName());
120          Object JavaDoc val = update.getNonDereferencedValue();
121          if (val != null && (val instanceof VersionReference))
122          {
123             VersionReference ref = (VersionReference)val;
124             log.trace("VersionReference.guid: " + ref.getGUID() + " for field " + advisor.getAdvisedFields()[update.getFieldIndex()].getName());
125             val = manager.getObject(ref.getGUID());
126             if (val == null)
127             {
128                DistributedState fieldVal = manager.getState(ref.getGUID());
129                val = fieldVal.buildObject(manager, versionManager);
130             }
131             ref.set((InstanceAdvised)val);
132          }
133       }
134       return advised;
135    }
136
137    public HashMap JavaDoc getTxState()
138    {
139       return (HashMap JavaDoc)txState.get();
140    }
141
142    public HashMap JavaDoc getTxState(Transaction JavaDoc tx)
143    {
144       return (HashMap JavaDoc)txState.get(tx);
145    }
146
147    public Object JavaDoc fieldRead(org.jboss.aop.joinpoint.Invocation invocation) throws Throwable JavaDoc
148    {
149       acquireReadLock();
150       try
151       {
152          org.jboss.aop.joinpoint.FieldReadInvocation fieldInvocation = (org.jboss.aop.joinpoint.FieldReadInvocation)invocation;
153          Integer JavaDoc index = new Integer JavaDoc(fieldInvocation.getIndex());
154          HashMap JavaDoc map = getTxState();
155          if (map == null)
156          {
157             map = fieldMap;
158          }
159          DistributedFieldUpdate update = (DistributedFieldUpdate)map.get(index);
160          Object JavaDoc val = update.getValue();
161          return val;
162       }
163       finally
164       {
165          releaseReadLock();
166       }
167    }
168
169    public Object JavaDoc fieldWrite(org.jboss.aop.joinpoint.Invocation invocation) throws Throwable JavaDoc
170    {
171       org.jboss.aop.joinpoint.FieldWriteInvocation fieldInvocation = (org.jboss.aop.joinpoint.FieldWriteInvocation)invocation;
172       Integer JavaDoc index = new Integer JavaDoc(fieldInvocation.getIndex());
173       Object JavaDoc val = fieldInvocation.getValue();
174
175       if (val instanceof Advised)
176       {
177          Advised advisedValue = (Advised)val;
178          val = versionManager.makeVersioned(advisedValue);
179       }
180
181       Transaction JavaDoc tx = tm.getTransaction();
182       if (tx == null)
183       {
184          acquireWriteLock();
185          try
186          {
187             // REVISIT: Handle exception
188
DistributedFieldUpdate update = (DistributedFieldUpdate)fieldMap.get(index);
189             long versionId = update.getVersionId() + 1;
190             update.setVersionId(versionId);
191             update.setValue(val);
192             HashMap JavaDoc fieldUpdates = new HashMap JavaDoc();
193             fieldUpdates.put(index, update);
194             synchManager.noTxUpdate(new DistributedPOJOUpdate(guid, fieldUpdates));
195             return null;
196          }
197          finally
198          {
199             releaseWriteLock();
200          }
201       }
202
203       acquireReadLock();
204       try
205       {
206          HashMap JavaDoc map = (HashMap JavaDoc)txState.get();
207          if (map == null)
208          {
209             map = new HashMap JavaDoc();
210             DistributedFieldUpdate update = (DistributedFieldUpdate)fieldMap.get(index);
211             DistributedFieldUpdate newUpdate = new DistributedFieldUpdate(val, update.getVersionId() + 1, index.intValue());
212             synchManager.registerUpdate(tx, this);
213             map.put(index, newUpdate);
214             txState.set(tx, map);
215          }
216          else
217          {
218             DistributedFieldUpdate newUpdate = (DistributedFieldUpdate)map.get(index);
219             if (newUpdate == null)
220             {
221                DistributedFieldUpdate update = (DistributedFieldUpdate)fieldMap.get(index);
222                newUpdate = new DistributedFieldUpdate(val, update.getVersionId() + 1, index.intValue());
223                map.put(index, newUpdate);
224             }
225             else
226             {
227                newUpdate.setValue(val);
228             }
229          }
230       }
231       finally
232       {
233          releaseReadLock();
234       }
235
236       return null;
237    }
238
239    public DistributedUpdate createTxUpdate(Transaction JavaDoc tx)
240    {
241       HashMap JavaDoc state = getTxState(tx);
242       return new DistributedPOJOUpdate(guid, state);
243    }
244
245    public void checkOptimisticLock(Transaction JavaDoc tx)
246    {
247       // NOTE THIS CODE ASSUMES THAT A WRITELOCK HAS BEEN ACQUIRED!!!!
248
HashMap JavaDoc state = getTxState(tx);
249       Iterator JavaDoc it = state.entrySet().iterator();
250       while (it.hasNext())
251       {
252          Map.Entry JavaDoc entry = (Map.Entry JavaDoc)it.next();
253          Integer JavaDoc index = (Integer JavaDoc)entry.getKey();
254          DistributedFieldUpdate update = (DistributedFieldUpdate)entry.getValue();
255          DistributedFieldUpdate orig = (DistributedFieldUpdate)fieldMap.get(index);
256          if (update.getVersionId() <= orig.getVersionId())
257          {
258             Advised advised = null;
259             if (advisedRef != null)
260             {
261                advised = (Advised)advisedRef.get();
262             }
263             if (advised != null)
264             {
265                ClassAdvisor advisor = (ClassAdvisor)advised._getAdvisor();
266                Field JavaDoc field = advisor.getAdvisedFields()[index.intValue()];
267                throw new OptimisticLockFailure("optimistic lock failure for field " + field.getName()
268                                                + " of class " + field.getDeclaringClass().getName());
269             }
270          }
271       }
272    }
273
274    public void mergeState(Transaction JavaDoc tx) throws Exception JavaDoc
275    {
276       HashMap JavaDoc newState = getTxState(tx);
277       mergeState(newState);
278    }
279
280    public void mergeState(DistributedUpdate update) throws Exception JavaDoc
281    {
282       HashMap JavaDoc newState = ((DistributedPOJOUpdate)update).fieldUpdates;
283       mergeState(newState);
284    }
285
286    public void mergeState(HashMap JavaDoc newState) throws Exception JavaDoc
287    {
288       // NOTE THIS CODE ASSUMES THAT A WRITELOCK HAS BEEN ACQUIRED!!!!
289
Iterator JavaDoc it = newState.entrySet().iterator();
290       while (it.hasNext())
291       {
292          Map.Entry JavaDoc entry = (Map.Entry JavaDoc)it.next();
293          DistributedFieldUpdate update = (DistributedFieldUpdate)entry.getValue();
294          if (update.getNonDereferencedValue() instanceof VersionReference)
295          {
296             VersionReference ref = (VersionReference)update.getNonDereferencedValue();
297             if (ref.get() == null) ref.set((InstanceAdvised)synchManager.getObject(ref.getGUID()));
298          }
299       }
300       fieldMap.putAll(newState); // overwrite old state
301
}
302
303    public void writeExternal(java.io.ObjectOutput JavaDoc out)
304       throws java.io.IOException JavaDoc
305    {
306       super.writeExternal(out);
307       out.writeObject(classname);
308       out.writeObject(fieldMap);
309    }
310
311    public void readExternal(java.io.ObjectInput JavaDoc in)
312       throws java.io.IOException JavaDoc, ClassNotFoundException JavaDoc
313    {
314       super.readExternal(in);
315       this.classname = (String JavaDoc)in.readObject();
316       this.fieldMap = (HashMap JavaDoc)in.readObject();
317       try
318       {
319          InitialContext JavaDoc ctx = new InitialContext JavaDoc();
320          this.tm = (TransactionManager JavaDoc)ctx.lookup("java:/TransactionManager");
321       }
322       catch (Exception JavaDoc ex)
323       {
324          throw new RuntimeException JavaDoc(ex);
325       }
326       this.txState = new TransactionLocal();
327    }
328
329 }
330
Popular Tags