1 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 ; 30 import javax.transaction.Synchronization ; 31 import javax.transaction.Transaction ; 32 33 40 public class VersionedObject 41 { 42 FIFOSemaphore lock = new FIFOSemaphore(1); 43 TransactionLocal txLocal = new TransactionLocal(); 44 long currentId = 0; 45 Object currentObject; 46 long versionIdGenerator = 0; 47 48 public VersionedObject(Object obj) 49 { 50 currentObject = obj; 51 } 52 53 public Object getVersion(Transaction tx) 54 { 55 if (tx == null) return currentObject; 56 return txLocal.get(tx); 57 } 58 59 public Object createVersion(Transaction tx) throws Exception 60 { 61 lock.acquire(); 62 Object version = null; 63 long versionId; 64 try 65 { 66 version = new MarshalledValue(currentObject).get(); 67 if (version instanceof Advised) 68 { 69 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 87 { 88 long versionId; 89 Object version; 90 Transaction tx; 91 92 public VersionSynchronization(Transaction tx, long versionId, Object 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 ignored) 105 { 106 throw new RuntimeException (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 if (status != Status.STATUS_ROLLEDBACK) 119 { 120 currentId = versionId; 121 currentObject = version; 122 lock.release(); 123 } 124 } 125 } 126 } 127 | Popular Tags |