FileDocCategorySizeDatePackage
DistributedPOJOState.javaAPI DocJBoss 4.2.111181Fri Jul 13 21:02:32 BST 2007org.jboss.aspects.versioned

DistributedPOJOState

public class DistributedPOJOState extends StateManager implements Externalizable, DistributedState
author
Bill Burke
version
$Revision: 57186 $

Fields Summary
private static final long
serialVersionUID
private static Logger
log
Logging instance
protected String
classname
protected HashMap
fieldMap
protected transient TransactionManager
tm
protected transient WeakReference
advisedRef
protected transient org.jboss.tm.TransactionLocal
txState
protected transient SynchronizationManager
synchManager
protected transient DistributedVersionManager
versionManager
Constructors Summary
public DistributedPOJOState()


     
public DistributedPOJOState(org.jboss.util.id.GUID daguid, long datimeout, org.jboss.aop.Advised advised, DistributedVersionManager versionManager, SynchronizationManager synchManager)

      super(daguid, datimeout);
      this.fieldMap = new HashMap();
      this.classname = advised.getClass().getName();
      InitialContext ctx = new InitialContext();
      this.tm = (TransactionManager)ctx.lookup("java:/TransactionManager");
      this.synchManager = synchManager;
      this.versionManager = versionManager;
      this.advisedRef = new WeakReference(advised);
   
Methods Summary
public org.jboss.aop.InstanceAdvisedbuildObject(SynchronizationManager manager, DistributedVersionManager versionManager)

      log.trace("building a " + classname + " of guid " + guid);
      this.versionManager = versionManager;
      this.synchManager = manager;
      Class clazz = Thread.currentThread().getContextClassLoader().loadClass(classname);
      Advised advised = (Advised)clazz.newInstance();
      this.advisedRef = new WeakReference(advised);
      versionManager.addVersioning(this, advised);
      manager.putState(guid, this);
      manager.putObject(guid, advised);

      Iterator it = fieldMap.values().iterator();
      while(it.hasNext())
      {
         DistributedFieldUpdate update = (DistributedFieldUpdate)it.next();
         ClassAdvisor advisor = (ClassAdvisor)advised._getAdvisor();
         log.trace("build field " + advisor.getAdvisedFields()[update.getFieldIndex()].getName());
         Object val = update.getNonDereferencedValue();
         if (val != null && (val instanceof VersionReference))
         {
            VersionReference ref = (VersionReference)val;
            log.trace("VersionReference.guid: " + ref.getGUID() + " for field " + advisor.getAdvisedFields()[update.getFieldIndex()].getName());
            val = manager.getObject(ref.getGUID());
            if (val == null)
            {
               DistributedState fieldVal = manager.getState(ref.getGUID());
               val = fieldVal.buildObject(manager, versionManager);
            }
            ref.set((InstanceAdvised)val);
         }
      }
      return advised;
   
public voidcheckOptimisticLock(javax.transaction.Transaction tx)

      // NOTE THIS CODE ASSUMES THAT A WRITELOCK HAS BEEN ACQUIRED!!!!
      HashMap state = getTxState(tx);
      Iterator it = state.entrySet().iterator();
      while (it.hasNext())
      {
         Map.Entry entry = (Map.Entry)it.next();
         Integer index = (Integer)entry.getKey();
         DistributedFieldUpdate update = (DistributedFieldUpdate)entry.getValue();
         DistributedFieldUpdate orig = (DistributedFieldUpdate)fieldMap.get(index);
         if (update.getVersionId() <= orig.getVersionId())
         {
            Advised advised = null;
            if (advisedRef != null)
            {
               advised = (Advised)advisedRef.get();
            }
            if (advised != null)
            {
               ClassAdvisor advisor = (ClassAdvisor)advised._getAdvisor();
               Field field = advisor.getAdvisedFields()[index.intValue()];
               throw new OptimisticLockFailure("optimistic lock failure for field " + field.getName()
                                               + " of class " + field.getDeclaringClass().getName());
            }
         }
      }
   
public DistributedUpdatecreateTxUpdate(javax.transaction.Transaction tx)

      HashMap state = getTxState(tx);
      return new DistributedPOJOUpdate(guid, state);
   
public booleanequals(java.lang.Object obj)

      if (!(obj instanceof DistributedPOJOState)) return false;
      DistributedPOJOState pojo = (DistributedPOJOState)obj;
      return guid.equals(pojo.guid);
   
public java.lang.ObjectfieldRead(org.jboss.aop.joinpoint.Invocation invocation)

      acquireReadLock();
      try
      {
         org.jboss.aop.joinpoint.FieldReadInvocation fieldInvocation = (org.jboss.aop.joinpoint.FieldReadInvocation)invocation;
         Integer index = new Integer(fieldInvocation.getIndex());
         HashMap map = getTxState();
         if (map == null)
         {
            map = fieldMap;
         }
         DistributedFieldUpdate update = (DistributedFieldUpdate)map.get(index);
         Object val = update.getValue();
         return val;
      }
      finally
      {
         releaseReadLock();
      }
   
public java.lang.ObjectfieldWrite(org.jboss.aop.joinpoint.Invocation invocation)

      org.jboss.aop.joinpoint.FieldWriteInvocation fieldInvocation = (org.jboss.aop.joinpoint.FieldWriteInvocation)invocation;
      Integer index = new Integer(fieldInvocation.getIndex());
      Object val = fieldInvocation.getValue();

      if (val instanceof Advised)
      {
         Advised advisedValue = (Advised)val;
         val = versionManager.makeVersioned(advisedValue);
      }

      Transaction tx = tm.getTransaction();
      if (tx == null)
      {
         acquireWriteLock();
         try
         {
            // REVISIT: Handle exception
            DistributedFieldUpdate update = (DistributedFieldUpdate)fieldMap.get(index);
            long versionId = update.getVersionId() + 1;
            update.setVersionId(versionId);
            update.setValue(val);
            HashMap fieldUpdates = new HashMap();
            fieldUpdates.put(index, update);
            synchManager.noTxUpdate(new DistributedPOJOUpdate(guid, fieldUpdates));
            return null;
         }
         finally
         {
            releaseWriteLock();
         }
      }

      acquireReadLock();
      try
      {
         HashMap map = (HashMap)txState.get();
         if (map == null)
         {
            map = new HashMap();
            DistributedFieldUpdate update = (DistributedFieldUpdate)fieldMap.get(index);
            DistributedFieldUpdate newUpdate = new DistributedFieldUpdate(val, update.getVersionId() + 1, index.intValue());
            synchManager.registerUpdate(tx, this);
            map.put(index, newUpdate);
            txState.set(tx, map);
         }
         else
         {
            DistributedFieldUpdate newUpdate = (DistributedFieldUpdate)map.get(index);
            if (newUpdate == null)
            {
               DistributedFieldUpdate update = (DistributedFieldUpdate)fieldMap.get(index);
               newUpdate = new DistributedFieldUpdate(val, update.getVersionId() + 1, index.intValue());
               map.put(index, newUpdate);
            }
            else
            {
               newUpdate.setValue(val);
            }
         }
      }
      finally
      {
         releaseReadLock();
      }

      return null;
   
public org.jboss.aop.InstanceAdvisedgetObject()

      if (advisedRef != null)
      {
         return (InstanceAdvised)advisedRef.get();
      }
      return null; 
   
public java.util.HashMapgetTxState()

      return (HashMap)txState.get();
   
public java.util.HashMapgetTxState(javax.transaction.Transaction tx)

      return (HashMap)txState.get(tx);
   
public inthashCode()

      return guid.hashCode();

   
public voidmergeState(javax.transaction.Transaction tx)

      HashMap newState = getTxState(tx);
      mergeState(newState);
   
public voidmergeState(DistributedUpdate update)

      HashMap newState = ((DistributedPOJOUpdate)update).fieldUpdates;
      mergeState(newState);
   
public voidmergeState(java.util.HashMap newState)

      // NOTE THIS CODE ASSUMES THAT A WRITELOCK HAS BEEN ACQUIRED!!!!
      Iterator it = newState.entrySet().iterator();
      while (it.hasNext())
      {
         Map.Entry entry = (Map.Entry)it.next();
         DistributedFieldUpdate update = (DistributedFieldUpdate)entry.getValue();
         if (update.getNonDereferencedValue() instanceof VersionReference)
         {
            VersionReference ref = (VersionReference)update.getNonDereferencedValue();
            if (ref.get() == null) ref.set((InstanceAdvised)synchManager.getObject(ref.getGUID()));
         }
      }
      fieldMap.putAll(newState); // overwrite old state
   
public voidreadExternal(java.io.ObjectInput in)

      super.readExternal(in);
      this.classname = (String)in.readObject();
      this.fieldMap = (HashMap)in.readObject();
      try
      {
         InitialContext ctx = new InitialContext();
         this.tm = (TransactionManager)ctx.lookup("java:/TransactionManager");
      }
      catch (Exception ex)
      {
         throw new RuntimeException(ex);
      }
      this.txState = new TransactionLocal();
   
public voidwriteExternal(java.io.ObjectOutput out)

      super.writeExternal(out);
      out.writeObject(classname);
      out.writeObject(fieldMap);