KickJava   Java API By Example, From Geeks To Geeks.

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


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 EDU.oswego.cs.dl.util.concurrent.FIFOSemaphore;
25 import org.jboss.aop.Advised;
26 import org.jboss.aop.util.MarshalledValue;
27 import org.jboss.tm.TransactionLocal;
28
29 import javax.transaction.Status JavaDoc;
30 import javax.transaction.Synchronization JavaDoc;
31 import javax.transaction.Transaction JavaDoc;
32
33 /**
34  * Manages transactional versions of an object
35  * versioned object must be Serializable or Cloneable
36  *
37  * @author <a HREF="mailto:bill@jboss.org">Bill Burke</a>
38  * @version $Revision: 37406 $
39  */

40 public class VersionedObject
41 {
42    FIFOSemaphore lock = new FIFOSemaphore(1);
43    TransactionLocal txLocal = new TransactionLocal();
44    long currentId = 0;
45    Object JavaDoc currentObject;
46    long versionIdGenerator = 0;
47
48    public VersionedObject(Object JavaDoc obj)
49    {
50       currentObject = obj;
51    }
52
53    public Object JavaDoc getVersion(Transaction JavaDoc tx)
54    {
55       if (tx == null) return currentObject;
56       return txLocal.get(tx);
57    }
58
59    public Object JavaDoc createVersion(Transaction JavaDoc tx) throws Exception JavaDoc
60    {
61       lock.acquire();
62       Object JavaDoc version = null;
63       long versionId;
64       try
65       {
66          version = new MarshalledValue(currentObject).get();
67          if (version instanceof Advised)
68          {
69             // REVISIT: Currently share the InstanceAdvisor between versions
70
Advised versionAdvised = (Advised)version;
71             Advised currentAdvised = (Advised)currentObject;
72             versionAdvised._setInstanceAdvisor(currentAdvised._getInstanceAdvisor());
73          }
74          versionId = ++versionIdGenerator;
75       }
76       finally
77       {
78          lock.release();
79       }
80
81       tx.registerSynchronization(new VersionSynchronization(tx, versionId, version));
82       txLocal.set(tx, version);
83       return version;
84    }
85
86    private final class VersionSynchronization implements Synchronization JavaDoc
87    {
88       long versionId;
89       Object JavaDoc version;
90       Transaction JavaDoc tx;
91
92       public VersionSynchronization(Transaction JavaDoc tx, long versionId, Object JavaDoc version)
93       {
94          this.tx = tx;
95          this.versionId = versionId;
96          this.version = version;
97       }
98       public void beforeCompletion()
99       {
100          try
101          {
102             lock.acquire();
103          }
104          catch (InterruptedException JavaDoc ignored)
105          {
106             throw new RuntimeException JavaDoc(ignored);
107          }
108          if (currentId >= versionId)
109          {
110             lock.release();
111             throw new OptimisticLockFailure();
112          }
113       }
114
115       public void afterCompletion(int status)
116       {
117          //possible status is committed and rolledback
118
if (status != Status.STATUS_ROLLEDBACK)
119          {
120             currentId = versionId;
121             currentObject = version;
122             lock.release();
123          }
124       }
125    }
126 }
127
Popular Tags