1 4 package com.tc.object.tx.optimistic; 5 6 import com.tc.object.ClientObjectManager; 7 import com.tc.object.LiteralValues; 8 import com.tc.object.TCObject; 9 import com.tc.object.change.TCChangeBuffer; 10 import com.tc.object.change.TCChangeBufferEventVisitor; 11 import com.tc.object.change.event.ArrayElementChangeEvent; 12 import com.tc.object.change.event.LogicalChangeEvent; 13 import com.tc.object.change.event.PhysicalChangeEvent; 14 import com.tc.object.tx.ClientTransaction; 15 import com.tc.object.tx.ClientTransactionManager; 16 import com.tc.util.Assert; 17 import com.tc.util.ClassUtils; 18 19 import java.util.Iterator ; 20 import java.util.Map ; 21 22 public class OptimisticTransactionManagerImpl implements OptimisticTransactionManager { 23 private ThreadLocal transaction = new ThreadLocal (); 24 private ClientObjectManager objectManager; 25 private ClientTransactionManager clientTxManager; 26 private LiteralValues literalValues = new LiteralValues(); 27 28 public OptimisticTransactionManagerImpl(ClientObjectManager objectManager, ClientTransactionManager clientTxManager) { 29 this.objectManager = objectManager; 30 this.clientTxManager = clientTxManager; 31 Assert.eval(objectManager != null); 32 } 33 34 public void begin() { 35 if (getTransaction() != null) { throw new AssertionError ("Don't support nested optimistic transactions"); } 36 37 transaction.set(new OptimisticTransaction()); 38 } 39 40 public void objectFieldChanged(TCObjectClone clone, String classname, String fieldname, Object newValue, int index) { 41 getTransaction().objectFieldChanged(clone, classname, fieldname, newValue, index); 42 } 43 44 public void logicalInvoke(TCObjectClone clone, int method, String methodName, Object [] parameters) { 45 getTransaction().logicalInvoke(clone, method, parameters); 46 } 47 48 public void rollback() { 49 if (getTransaction() != null) { throw new AssertionError ("Can't rollback non-exsistent tx"); } 50 transaction.set(null); 51 } 52 53 public Object convertToParameter(Object obj) { 54 Object nv = null; 55 OptimisticTransaction ot = getTransaction(); 56 ClientTransaction ctx = clientTxManager.getTransaction(); 57 58 if (ot.hasClone(obj)) { 59 TCObject ctcobj = ot.getTCObjectFor(obj); 60 nv = ctcobj.getObjectID(); 61 } else if (literalValues.isLiteralInstance(obj)) { 62 nv = obj; 63 } else { 64 TCObject ctcobj = objectManager.lookupOrCreate(obj); 65 ctx.createObject(ctcobj); 66 nv = ctcobj.getObjectID(); 67 } 68 return nv; 69 } 70 71 public void commit() throws ClassNotFoundException { 72 OptimisticTransaction ot = getTransaction(); 73 final ClientTransaction ctx = clientTxManager.getTransaction(); 74 Map buffers = ot.getChangeBuffers(); 75 for (Iterator i = buffers.values().iterator(); i.hasNext();) { 76 TCChangeBuffer buf = (TCChangeBuffer) i.next(); 77 Assert.eval(buf.getTCObject() != null); 78 final TCObject tcobj = objectManager.lookup(buf.getTCObject().getObjectID()); 79 try { 80 tcobj.hydrate(new DNAToChangeBufferBridge(this, buf), true); 81 } catch (ClassNotFoundException e) { 82 throw e; 83 } 84 85 buf.accept(new TCChangeBufferEventVisitor() { 87 public void visitPhysicalChangeEvent(PhysicalChangeEvent pe) { 88 Object nv = convertToParameter(pe.getNewValue()); 89 Assert.eval(nv != null); 90 ctx.fieldChanged(tcobj, tcobj.getTCClass().getName(), pe.getFieldName(), nv, -1); 91 } 92 93 public void visitLogicalEvent(LogicalChangeEvent lce) { 94 Object [] params = lce.getParameters(); 95 Object [] newParams = new Object [params.length]; 96 for (int j = 0; j < newParams.length; j++) { 97 newParams[j] = convertToParameter(params[j]); 98 } 99 ctx.logicalInvoke(tcobj, lce.getMethodID(), newParams, ""); 100 } 101 102 public void visitArrayElementChangeEvent(ArrayElementChangeEvent ae) { 103 Object nv = ae.getValue(); 104 if (ae.isSubarray()) { 105 if (!ClassUtils.isPrimitiveArray(nv)) { 106 Object [] values = (Object []) nv; 107 for (int j = 0; j < values.length; j++) { 108 values[j] = convertToParameter(values[j]); 109 } 110 } 111 ctx.arrayChanged(tcobj, ae.getIndex(), nv, ae.getLength()); 112 } else { 113 ctx.fieldChanged(tcobj, tcobj.getTCClass().getName(), null, convertToParameter(nv), ae.getIndex()); 114 } 115 } 116 }); 117 } 118 transaction.set(null); 119 } 120 121 private OptimisticTransaction getTransaction() { 122 return (OptimisticTransaction) transaction.get(); 123 } 124 125 public void addClonesToTransaction(Map cloned) { 126 getTransaction().addAll(cloned); 127 } 128 129 } 130 | Popular Tags |