[jboss-svn-commits] JBL Code SVN: r37215 - in labs/jbosstm/workspace/mlittle/STM-Arjuna/src/main/java/org/jboss/stm/internal: reflect and 1 other directory.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Sun Jul 3 15:41:44 EDT 2011


Author: mark.little at jboss.com
Date: 2011-07-03 15:41:44 -0400 (Sun, 03 Jul 2011)
New Revision: 37215

Modified:
   labs/jbosstm/workspace/mlittle/STM-Arjuna/src/main/java/org/jboss/stm/internal/proxy/LockManagerProxy.java
   labs/jbosstm/workspace/mlittle/STM-Arjuna/src/main/java/org/jboss/stm/internal/reflect/InvocationHandler.java
Log:
Added initial automatic save/restore for transactional objects. Need to look at improving container determination.

Modified: labs/jbosstm/workspace/mlittle/STM-Arjuna/src/main/java/org/jboss/stm/internal/proxy/LockManagerProxy.java
===================================================================
--- labs/jbosstm/workspace/mlittle/STM-Arjuna/src/main/java/org/jboss/stm/internal/proxy/LockManagerProxy.java	2011-07-03 10:33:06 UTC (rev 37214)
+++ labs/jbosstm/workspace/mlittle/STM-Arjuna/src/main/java/org/jboss/stm/internal/proxy/LockManagerProxy.java	2011-07-03 19:41:44 UTC (rev 37215)
@@ -27,9 +27,11 @@
 import java.util.ArrayList;
 
 import org.jboss.stm.InvalidAnnotationException;
+import org.jboss.stm.RecoverableContainer;
 import org.jboss.stm.annotations.State;
 import org.jboss.stm.annotations.RestoreState;
 import org.jboss.stm.annotations.SaveState;
+import org.jboss.stm.annotations.Transactional;
 
 import com.arjuna.ats.arjuna.common.Uid;
 import com.arjuna.ats.arjuna.state.InputObjectState;
@@ -40,23 +42,40 @@
 {
     public LockManagerProxy (T candidate)
     {
-        this(candidate, com.arjuna.ats.arjuna.ObjectType.RECOVERABLE);
+        this(candidate, (RecoverableContainer<T>) null);
     }
     
+    public LockManagerProxy (T candidate, RecoverableContainer<T> cont)
+    {
+        this(candidate, com.arjuna.ats.arjuna.ObjectType.RECOVERABLE, cont);
+    }
+    
     public LockManagerProxy (T candidate, int ot)
     {
+        this(candidate, ot, null);
+
+    }
+    public LockManagerProxy (T candidate, int ot, RecoverableContainer<T> cont)
+    {
         super(ot);
         
         _theObject = candidate;
+        _container = cont;
     }
     
+    public LockManagerProxy (T candidate, Uid u)
+    {
+        this(candidate, u, null);
+    }
+    
     // if there's a Uid then this is a persistent object
     
-    public LockManagerProxy (T candidate, Uid u)
+    public LockManagerProxy (T candidate, Uid u, RecoverableContainer<T> cont)
     {
         super(u);  // TODO make configurable through annotation
         
         _theObject = candidate;
+        _container = cont;
     }
     
     public boolean save_state (OutputObjectState os, int ot)
@@ -274,6 +293,8 @@
                 os.packChar(((Character) afield.get(_theObject)).charValue());
             else if (afield.getType().equals(String.class))
                 os.packString((String) afield.get(_theObject));
+            else if (afield.getType().isAnnotationPresent(Transactional.class))
+                return packTransactionalInstance(afield, os);
             else
                 return false;
         }
@@ -287,6 +308,47 @@
         return true;
     }
     
+    /*
+     * This only works if this type and the types we're packing share the same container.
+     * So we need a way to specify (or determine) the container for all transactional
+     * instances.
+     */
+    
+    @SuppressWarnings("unchecked")
+    private boolean packTransactionalInstance (final Field afield, OutputObjectState os)
+    {
+        Object ptr = null;
+        
+        try
+        {
+            ptr = afield.get(_theObject);
+            
+            if (ptr == null)
+            {
+                os.packBoolean(false);
+            }
+            else
+            {
+                os.packBoolean(true);
+                _container.getUidForHandle((T) ptr).pack(os);
+            }
+        }
+        catch (final ClassCastException ex)
+        {
+            System.err.println("Field "+ptr+" is not a transactional instance!");
+            
+            return false;
+        }
+        catch (final Exception ex)
+        {
+            ex.printStackTrace();
+            
+            return false;
+        }
+        
+        return true;
+    }
+    
     private boolean saveState (OutputObjectState os) throws InvalidAnnotationException
     {
         boolean res = false;
@@ -447,6 +509,8 @@
                 afield.set(_theObject, new Character(os.unpackChar()));
             else if (afield.getType().equals(String.class))
                 afield.set(_theObject, os.unpackString());
+            else if (afield.getType().isAnnotationPresent(Transactional.class))
+                return unpackTransactionalInstance(afield, os);
             else
                 return false;
         }
@@ -466,6 +530,39 @@
         return true;
     }
     
+    /*
+     * This only works if this type and the types we're packing share the same container.
+     * So we need a way to specify (or determine) the container for all transactional
+     * instances.
+     */
+    
+    private boolean unpackTransactionalInstance (final Field afield, InputObjectState os)
+    {
+        Uid u = new Uid(Uid.nullUid());
+        
+        try
+        {
+            boolean ptr = os.unpackBoolean();
+            
+            if (!ptr)
+                afield.set(_theObject, null);
+            else
+            {
+                u.unpack(os);
+                
+                afield.set(_theObject, _container.getHandle(u));
+            }
+        }
+        catch (final Exception ex)
+        {
+            ex.printStackTrace();
+            
+            return false;
+        }
+        
+        return true;
+    }
+    
     // the object we are working on.
     
     private T _theObject;
@@ -475,6 +572,7 @@
     private boolean _checkSaveRestore = false;
     private Method _saveState = null;
     private Method _restoreState = null;
+    private RecoverableContainer<T> _container = null;
     
     private ArrayList<Field> _fields = null;
 }

Modified: labs/jbosstm/workspace/mlittle/STM-Arjuna/src/main/java/org/jboss/stm/internal/reflect/InvocationHandler.java
===================================================================
--- labs/jbosstm/workspace/mlittle/STM-Arjuna/src/main/java/org/jboss/stm/internal/reflect/InvocationHandler.java	2011-07-03 10:33:06 UTC (rev 37214)
+++ labs/jbosstm/workspace/mlittle/STM-Arjuna/src/main/java/org/jboss/stm/internal/reflect/InvocationHandler.java	2011-07-03 19:41:44 UTC (rev 37215)
@@ -67,9 +67,9 @@
         _theObject = obj;
         
         if (u != null)
-            _txObject = new LockManagerProxy<T>(obj, u);
+            _txObject = new LockManagerProxy<T>(obj, u, cont);
         else
-            _txObject = new LockManagerProxy<T>(obj, ot);  // recoverable or persistent
+            _txObject = new LockManagerProxy<T>(obj, ot, cont);  // recoverable or persistent
         
         _methods = obj.getClass().getDeclaredMethods();
         
@@ -193,9 +193,11 @@
                 if (lockType == null)
                     throw new LockException("Lock type is null!");
                 
-                if (_txObject.setlock(new Lock(lockType.intValue()), 0) != LockResult.GRANTED)
+                int result = _txObject.setlock(new Lock(lockType.intValue()), 0);
+                
+                if (result != LockResult.GRANTED)
                 {
-                    throw new LockException("Could not set "+LockMode.stringForm(lockType.intValue())+" lock.");
+                    throw new LockException("Could not set "+LockMode.stringForm(lockType.intValue())+" lock. Got: "+LockResult.stringForm(result));
                 }
             }
             



More information about the jboss-svn-commits mailing list