ozeigermann    2004/05/18 06:59:13

  Modified:    transaction/src/java/org/apache/commons/transaction/memory
                        TransactionalMapWrapper.java
  Log:
  - more transaction control

  - refactored context to be a pure structure
  
  Revision  Changes    Path
  1.5       +122 -73   
jakarta-commons-sandbox/transaction/src/java/org/apache/commons/transaction/memory/TransactionalMapWrapper.java
  
  Index: TransactionalMapWrapper.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons-sandbox/transaction/src/java/org/apache/commons/transaction/memory/TransactionalMapWrapper.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- TransactionalMapWrapper.java      18 May 2004 07:40:29 -0000      1.4
  +++ TransactionalMapWrapper.java      18 May 2004 13:59:13 -0000      1.5
  @@ -31,6 +31,8 @@
   import java.util.Map;
   import java.util.Set;
   
  +import javax.transaction.Status;
  +
   /**
    * Wrapper that adds transactional control to all kinds of maps that implement the 
[EMAIL PROTECTED] Map} interface.
    * <br>
  @@ -44,7 +46,7 @@
    * @author <a href="mailto:[EMAIL PROTECTED]">Oliver Zeigermann</a>
    * @version $Revision$
    */
  -public class TransactionalMapWrapper implements Map {
  +public class TransactionalMapWrapper implements Map, Status {
   
       protected Map wrapped;
   
  @@ -54,6 +56,28 @@
           this.wrapped = wrapped;
       }
   
  +    public synchronized boolean isReadOnly() {
  +        TxContext txContext = getActiveTx();
  +
  +        if (txContext == null) {
  +            throw new IllegalStateException(
  +                "Active thread " + Thread.currentThread() + " not associated with a 
transaction!");
  +        }
  +
  +        return txContext.readOnly;
  +    }
  +
  +    public synchronized boolean isTransactionMarkedForRollback() {
  +        TxContext txContext = getActiveTx();
  +
  +        if (txContext == null) {
  +            throw new IllegalStateException(
  +                "Active thread " + Thread.currentThread() + " not associated with a 
transaction!");
  +        }
  +
  +        return txContext.rollbackOnly;
  +    }
  +
       public synchronized void markTransactionForRollback() {
           TxContext txContext = getActiveTx();
   
  @@ -61,9 +85,9 @@
               throw new IllegalStateException(
                   "Active thread " + Thread.currentThread() + " not associated with a 
transaction!");
           }
  -        
  -        txContext.setRollbackOnly(true);
  -        
  +
  +        txContext.rollbackOnly = true;
  +
       }
   
       public synchronized TxContext suspendTransaction() {
  @@ -74,7 +98,7 @@
                   "Active thread " + Thread.currentThread() + " not associated with a 
transaction!");
           }
   
  -        activeTx.set(null);
  +        setActiveTx(null);
           return txContext;
       }
   
  @@ -88,7 +112,16 @@
               throw new IllegalStateException("No transaction to resume!");
           }
   
  -        activeTx.set(suspendedTx);
  +        setActiveTx(suspendedTx);
  +    }
  +
  +    public synchronized int getTransactionState() {
  +        TxContext txContext = getActiveTx();
  +
  +        if (txContext == null) {
  +            return Status.STATUS_NO_TRANSACTION;
  +        }
  +        return txContext.status;
       }
   
       public synchronized void startTransaction() {
  @@ -96,7 +129,7 @@
               throw new IllegalStateException(
                   "Active thread " + Thread.currentThread() + " already associated 
with a transaction!");
           }
  -        activeTx.set(new TxContext());
  +        setActiveTx(new TxContext());
       }
   
       public synchronized void rollbackTransaction() {
  @@ -108,7 +141,7 @@
           }
   
           // simply forget about tx
  -        activeTx.set(null);
  +        setActiveTx(null);
       }
   
       public synchronized void commitTransaction() {
  @@ -119,23 +152,26 @@
                   "Active thread " + Thread.currentThread() + " not associated with a 
transaction!");
           }
   
  -        if (txContext.isRollbackOnly()) {
  -            throw new IllegalStateException(
  -                "Active thread " + Thread.currentThread() + " is marked for 
rollback!");
  +        if (txContext.rollbackOnly) {
  +            throw new IllegalStateException("Active thread " + 
Thread.currentThread() + " is marked for rollback!");
           }
   
  -        for (Iterator it = txContext.getChanges().entrySet().iterator(); 
it.hasNext();) {
  +        if (txContext.cleared) {
  +            wrapped.clear();
  +        }
  +
  +        for (Iterator it = txContext.changes.entrySet().iterator(); it.hasNext();) {
               Map.Entry entry = (Map.Entry) it.next();
               wrapped.put(entry.getKey(), entry.getValue());
           }
   
  -        for (Iterator it = txContext.getDeletes().iterator(); it.hasNext();) {
  +        for (Iterator it = txContext.deletes.iterator(); it.hasNext();) {
               Object key = it.next();
               wrapped.remove(key);
           }
   
           // now forget about tx
  -        activeTx.set(null);
  +        setActiveTx(null);
       }
   
       //
  @@ -143,8 +179,15 @@
       // 
   
       public synchronized void clear() {
  -        wrapped.clear();
  -        activeTx.set(null);
  +        TxContext txContext = getActiveTx();
  +        if (txContext == null) {
  +            wrapped.clear();
  +        } else {
  +            txContext.readOnly = false;
  +            txContext.cleared = true;
  +            txContext.deletes.clear();
  +            txContext.changes.clear();
  +        }
       }
   
       public synchronized int size() {
  @@ -152,8 +195,11 @@
   
           TxContext txContext = getActiveTx();
           if (txContext != null) {
  -            size += txContext.getChanges().size();
               size -= txContext.deletes.size();
  +            if (txContext.cleared) {
  +                size = 0;
  +            }
  +            size += txContext.changes.size();
           }
           return size;
   
  @@ -161,7 +207,7 @@
   
       public synchronized boolean isEmpty() {
           TxContext txContext = getActiveTx();
  -        if (txContext != null) {
  +        if (txContext == null) {
               return wrapped.isEmpty();
           } else {
               return (size() > 0);
  @@ -174,7 +220,9 @@
           if (txContext == null) {
               return wrapped.containsKey(key);
           } else {
  -            return (!txContext.getDeletes().contains(key) && 
txContext.getChanges().containsKey(key));
  +            return (
  +                (!txContext.cleared && wrapped.containsKey(key) && 
!txContext.deletes.contains(key))
  +                    || txContext.changes.containsKey(key));
           }
       }
   
  @@ -213,16 +261,17 @@
               wrapped.putAll(map);
           } else {
               try {
  +                txContext.readOnly = false;
                   for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
                       Map.Entry entry = (Map.Entry) it.next();
  -                    txContext.getChanges().put(entry.getKey(), entry.getValue());
  -                    txContext.getDeletes().remove(entry.getKey());
  +                    txContext.changes.put(entry.getKey(), entry.getValue());
  +                    txContext.deletes.remove(entry.getKey());
                   }
               } catch (RuntimeException e) {
  -                txContext.setRollbackOnly(true);
  +                txContext.rollbackOnly = true;
                   throw e;
               } catch (Error e) {
  -                txContext.setRollbackOnly(true);
  +                txContext.rollbackOnly = true;
                   throw e;
               }
   
  @@ -247,36 +296,40 @@
       }
   
       public synchronized Set keySet() {
  -        Set keySet = wrapped.keySet();
   
           TxContext txContext = getActiveTx();
  -        if (txContext != null) {
  -            Set deleteSet = txContext.getDeletes();
  -            keySet.removeAll(deleteSet);
  -            Set changeSet = txContext.getChanges().keySet();
  -            keySet.addAll(changeSet);
  +
  +        if (txContext == null) {
  +            return wrapped.keySet();
  +        } else {
  +            Set keySet = (txContext.cleared ? new HashSet() : wrapped.keySet());
  +            keySet.removeAll(txContext.deletes);
  +            keySet.addAll(txContext.changes.keySet());
  +            return keySet;
           }
  -        return keySet;
       }
   
       public synchronized Object get(Object key) {
           TxContext txContext = getActiveTx();
   
           if (txContext != null) {
  -            if (txContext.getDeletes().contains(key)) {
  +            if (txContext.deletes.contains(key)) {
                   // reflects that entry has been deleted in this tx 
                   return null;
               }
   
  -            Object changed = txContext.getChanges().get(key);
  +            Object changed = txContext.changes.get(key);
               if (changed != null) {
                   // if object has been changed in this tx, get the local one
                   return changed;
               }
           }
   
  -        // as fall back return value from global cache (if present)
  -        return wrapped.get(key);
  +        if (txContext == null || !txContext.cleared) {
  +            // as fall back return value from global cache (if present)
  +            return wrapped.get(key);
  +        }
  +        return null;
       }
   
       public synchronized Object remove(Object key) {
  @@ -287,14 +340,16 @@
           if (txContext == null) {
               old = wrapped.remove(key);
           } else {
  +            old = get(key);
               try {
  -                old = txContext.getChanges().remove(key);
  -                txContext.getDeletes().add(key);
  +                txContext.readOnly = false;
  +                txContext.changes.remove(key);
  +                txContext.deletes.add(key);
               } catch (RuntimeException e) {
  -                txContext.setRollbackOnly(true);
  +                txContext.rollbackOnly = true;
                   throw e;
               } catch (Error e) {
  -                txContext.setRollbackOnly(true);
  +                txContext.rollbackOnly = true;
                   throw e;
               }
           }
  @@ -311,13 +366,14 @@
               wrapped.put(key, value);
           } else {
               try {
  -                txContext.getDeletes().remove(key);
  -                txContext.getChanges().put(key, value);
  +                txContext.readOnly = false;
  +                txContext.deletes.remove(key);
  +                txContext.changes.put(key, value);
               } catch (RuntimeException e) {
  -                txContext.setRollbackOnly(true);
  +                txContext.rollbackOnly = true;
                   throw e;
               } catch (Error e) {
  -                txContext.setRollbackOnly(true);
  +                txContext.rollbackOnly = true;
                   throw e;
               }
           }
  @@ -329,33 +385,8 @@
           return (TxContext) activeTx.get();
       }
   
  -    public static class TxContext {
  -        protected final Set deletes;
  -        protected final Map changes;
  -        protected boolean rollbackOnly;
  -
  -        protected TxContext() {
  -            deletes = new HashSet();
  -            changes = new HashMap();
  -            rollbackOnly = false;
  -        }
  -
  -        protected Map getChanges() {
  -            return changes;
  -        }
  -
  -        protected Set getDeletes() {
  -            return deletes;
  -        }
  -
  -        protected boolean isRollbackOnly() {
  -            return rollbackOnly;
  -        }
  -
  -        protected void setRollbackOnly(boolean rollbackOnly) {
  -            this.rollbackOnly = rollbackOnly;
  -        }
  -
  +    protected void setActiveTx(TxContext txContext) {
  +        activeTx.set(txContext);
       }
   
       // mostly copied from org.apache.commons.collections.map.AbstractHashedMap
  @@ -402,6 +433,24 @@
   
           public String toString() {
               return new 
StringBuffer().append(getKey()).append('=').append(getValue()).toString();
  +        }
  +    }
  +
  +    public static class TxContext {
  +        protected final Set deletes;
  +        protected final Map changes;
  +        protected boolean rollbackOnly;
  +        protected int status;
  +        protected boolean cleared;
  +        protected boolean readOnly;
  +
  +        protected TxContext() {
  +            deletes = new HashSet();
  +            changes = new HashMap();
  +            rollbackOnly = false;
  +            status = Status.STATUS_ACTIVE;
  +            cleared = false;
  +            readOnly = true;
           }
       }
   
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to