[jboss-cvs] JBossCache/src/org/jboss/cache/transaction ...

Elias Ross genman at noderunner.net
Wed Feb 7 17:06:44 EST 2007


  User: genman  
  Date: 07/02/07 17:06:44

  Added:       src/org/jboss/cache/transaction         
                        GenericTransactionManagerLookup.java
                        OptimisticTransactionEntry.java
                        TransactionTable.java
                        BatchModeTransactionManagerLookup.java
                        TransactionManagerLookup.java
                        JBossTransactionManagerLookup.java
                        GlobalTransaction.java TransactionEntry.java
                        DummyTransactionManagerLookup.java
  Log:
  JBCACHE-969 - Move transaction classes to org.jboss.cache.transaction
  
  Revision  Changes    Path
  1.1      date: 2007/02/07 22:06:44;  author: genman;  state: Exp;JBossCache/src/org/jboss/cache/transaction/GenericTransactionManagerLookup.java
  
  Index: GenericTransactionManagerLookup.java
  ===================================================================
  package org.jboss.cache.transaction;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  
  import javax.naming.InitialContext;
  import javax.naming.NamingException;
  import javax.transaction.TransactionManager;
  import java.lang.reflect.Method;
  
  /**
   * A transaction manager lookup class that attempts to locate a TransactionManager.
   * A variety of different classes and JNDI locations are tried, for servers
   * such as:
   * <ul>
   * <li> JBoss
   * <li> JRun4
   * <li> Resin
   * <li> Orion
   * <li> JOnAS
   * <li> BEA Weblogic
   * <li> Websphere 4.0, 5.0, 5.1, 6.0
   * <li> Sun, Glassfish
   * </ul>
   * If a transaction manager is not found, returns a {@link DummyTransactionManager}.
   *
   * @author Markus Plesser
   * @version $Id: GenericTransactionManagerLookup.java,v 1.1 2007/02/07 22:06:44 genman Exp $
   */
  public class GenericTransactionManagerLookup implements TransactionManagerLookup
  {
  
     private static Log log = LogFactory.getLog(GenericTransactionManagerLookup.class);
  
     /**
      * JNDI lookups performed?
      */
     private static boolean lookupDone = false;
  
     /**
      * No JNDI available?
      */
     private static boolean lookupFailed = false;
  
     /**
      * The JVM TransactionManager found.
      */
     private static TransactionManager tm = null;
  
     /**
      * JNDI locations for TransactionManagers we know of
      */
     private static String[][] knownJNDIManagers =
     {
        {"java:/TransactionManager", "JBoss, JRun4"},
        {"java:comp/TransactionManager", "Resin 3.x"},
        {"java:pm/TransactionManager", "Borland, Sun"},
        {"java:appserver/TransactionManager", "Sun Glassfish"},
        {"javax.transaction.TransactionManager", "BEA WebLogic"},
        {"java:comp/UserTransaction", "Resin, Orion, JOnAS (JOTM)"},
     };
     
     /**
      * WebSphere 5.1 and 6.0 TransactionManagerFactory
      */
     private static final String WS_FACTORY_CLASS_5_1 = "com.ibm.ws.Transaction.TransactionManagerFactory";
  
     /**
      * WebSphere 5.0 TransactionManagerFactory
      */
     private static final String WS_FACTORY_CLASS_5_0 = "com.ibm.ejs.jts.jta.TransactionManagerFactory";
  
     /**
      * WebSphere 4.0 TransactionManagerFactory
      */
     private static final String WS_FACTORY_CLASS_4 = "com.ibm.ejs.jts.jta.JTSXA";
  
     /**
      * Get the systemwide used TransactionManager
      *
      * @return TransactionManager
      */
     public TransactionManager getTransactionManager()
     {
        if (!lookupDone)
           doLookups();
        if (tm != null)
           return tm;
        if (lookupFailed)
        {
           //fall back to a dummy from JBossCache
           tm = DummyTransactionManager.getInstance();
           log.warn("Falling back to DummyTransactionManager from JBossCache");
        }
        return tm;
     }
  
     /**
      * Try to figure out which TransactionManager to use
      */
     private static void doLookups()
     {
        if (lookupFailed)
           return;
        InitialContext ctx;
        try
        {
           ctx = new InitialContext();
        }
        catch (NamingException e)
        {
           log.error("Failed creating initial JNDI context", e);
           lookupFailed = true;
           return;
        }
        //probe jndi lookups first
        for (int i = 0; i < knownJNDIManagers.length; i++)
        {
           Object jndiObject;
           try
           {
              if (log.isDebugEnabled())
                 log.debug("Trying to lookup TransactionManager for " + knownJNDIManagers[i][1]);
              jndiObject = ctx.lookup(knownJNDIManagers[i][0]);
           }
           catch (NamingException e)
           {
              log.info("Failed to perform a lookup for [" + knownJNDIManagers[i][0] + " (" + knownJNDIManagers[i][1]
                    + ")]");
              continue;
           }
           if (jndiObject instanceof TransactionManager)
           {
              tm = (TransactionManager) jndiObject;
              log.info("Found TransactionManager for " + knownJNDIManagers[i][1]);
              return;
           }
        }
        //try to find websphere lookups since we came here
        Class clazz;
        try
        {
           log.debug("Trying WebSphere 5.1: " + WS_FACTORY_CLASS_5_1);
           clazz = Class.forName(WS_FACTORY_CLASS_5_1);
           log.info("Found WebSphere 5.1: " + WS_FACTORY_CLASS_5_1);
        }
        catch (ClassNotFoundException ex)
        {
           try
           {
              log.debug("Trying WebSphere 5.0: " + WS_FACTORY_CLASS_5_0);
              clazz = Class.forName(WS_FACTORY_CLASS_5_0);
              log.info("Found WebSphere 5.0: " + WS_FACTORY_CLASS_5_0);
           }
           catch (ClassNotFoundException ex2)
           {
              try
              {
                 log.debug("Trying WebSphere 4: " + WS_FACTORY_CLASS_4);
                 clazz = Class.forName(WS_FACTORY_CLASS_4);
                 log.info("Found WebSphere 4: " + WS_FACTORY_CLASS_4);
              }
              catch (ClassNotFoundException ex3)
              {
                 log.debug("Couldn't find any WebSphere TransactionManager factory class, neither for WebSphere version 5.1 nor 5.0 nor 4");
                 lookupFailed = true;
                 return;
              }
           }
        }
        try
        {
           Class[] signature = null;
           Object[] args = null;
           Method method = clazz.getMethod("getTransactionManager", signature);
           tm = (TransactionManager) method.invoke(null, args);
        }
        catch (Exception ex)
        {
           log.error("Found WebSphere TransactionManager factory class [" + clazz.getName()
                 + "], but couldn't invoke its static 'getTransactionManager' method", ex);
        }
     }
  
  }
  
  
  
  1.1      date: 2007/02/07 22:06:44;  author: genman;  state: Exp;JBossCache/src/org/jboss/cache/transaction/OptimisticTransactionEntry.java
  
  Index: OptimisticTransactionEntry.java
  ===================================================================
  /*
   * JBoss, Home of Professional Open Source
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.cache.transaction;
  
  import org.jboss.cache.optimistic.TransactionWorkspace;
  import org.jboss.cache.optimistic.TransactionWorkspaceImpl;
  
  /**
   * Subclasses the {@link TransactionEntry} class to add a {@link TransactionWorkspace}.  Used with optimistic locking
   * where each call is assigned a trasnaction and a transaction workspace.
   *
   * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
   * @author <a href="mailto:stevew at jofti.com">Steve Woodcock (stevew at jofti.com)</a>
   */
  
  public class OptimisticTransactionEntry extends TransactionEntry
  {
  
     private TransactionWorkspace transactionWorkSpace = new TransactionWorkspaceImpl();
  
     public OptimisticTransactionEntry()
     {
     }
  
     public String toString()
     {
        StringBuffer sb = new StringBuffer(super.toString());
        sb.append("\nworkspace: ").append(transactionWorkSpace);
        return sb.toString();
     }
  
     /**
      * @return Returns the transactionWorkSpace.
      */
     public TransactionWorkspace getTransactionWorkSpace()
     {
        return transactionWorkSpace;
     }
  
     /**
      * @param transactionWorkSpace The transactionWorkSpace to set.
      */
     public void setTransactionWorkSpace(TransactionWorkspace transactionWorkSpace)
     {
        this.transactionWorkSpace = transactionWorkSpace;
     }
  
  }
  
  
  
  1.1      date: 2007/02/07 22:06:44;  author: genman;  state: Exp;JBossCache/src/org/jboss/cache/transaction/TransactionTable.java
  
  Index: TransactionTable.java
  ===================================================================
  /*
   * JBoss, the OpenSource J2EE webOS
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.cache.transaction;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.jboss.cache.lock.NodeLock;
  import org.jboss.cache.marshall.MethodCall;
  
  import javax.transaction.Transaction;
  import java.util.Collection;
  import java.util.Iterator;
  import java.util.Map;
  import java.util.concurrent.ConcurrentHashMap;
  
  /**
   * Maintains the mapping between a local {@link Transaction} and a {@link GlobalTransaction}.
   * Also stores {@link TransactionEntry} instances under a given transaction.
   *
   * @author <a href="mailto:bela at jboss.org">Bela Ban</a> Apr 14, 2003
   * @version $Revision: 1.1 $
   */
  public class TransactionTable
  {
  
     /**
      * Mapping between local (javax.transaction.Transaction)
      * and GlobalTransactions.
      * New: a local TX can have a number of GTXs 
      */
     protected Map<Transaction, GlobalTransaction> tx_map = new ConcurrentHashMap<Transaction, GlobalTransaction>();
  
     /** 
      * Mappings between GlobalTransactions and modifications. 
      */
     protected Map<GlobalTransaction, TransactionEntry> txs = new ConcurrentHashMap<GlobalTransaction, TransactionEntry>();
  
     /** our logger */
     private static final Log log = LogFactory.getLog(TransactionTable.class);
  
     /**
      * Constructs a new table.
      */
     public TransactionTable()
     {
     }
  
     /**
      * Returns the number of local transactions.
      */
     public int getNumLocalTransactions()
     {
        return tx_map.size();
     }
  
     /**
      * Returns the number of global transactions.
      */
     public int getNumGlobalTransactions()
     {
        return txs.size();
     }
  
     /**
      * Returns the global transaction associated with the local transaction.
      * Returns null if tx is null or it was not found.
      */
     public GlobalTransaction get(Transaction tx)
     {
        if (tx == null)
           return null;
        return tx_map.get(tx);
     }
  
     /** 
      * Returns the local transaction associated with a GlobalTransaction. Not
      * very efficient as the values have to be iterated over, don't use
      * frequently
      *
      * @param gtx The GlobalTransaction
      * @return Transaction. The local transaction associated with a given
      * GlobalTransaction). This will be null if no local transaction is
      * associated with a given GTX
      */
     public Transaction getLocalTransaction(GlobalTransaction gtx)
     {
        Map.Entry entry;
        Transaction local_tx;
        GlobalTransaction global_tx;
  
        if (gtx == null)
           return null;
        for (Iterator it = tx_map.entrySet().iterator(); it.hasNext();)
        {
           entry = (Map.Entry) it.next();
           local_tx = (Transaction) entry.getKey();
           global_tx = (GlobalTransaction) entry.getValue();
           if (gtx.equals(global_tx))
           {
              return local_tx;
           }
        }
        return null;
     }
  
     /**
      * Associates the global transaction with the local transaction.
      */
     public void put(Transaction tx, GlobalTransaction gtx)
     {
        if (tx == null)
        {
           log.error("key (Transaction) is null");
           return;
        }
        tx_map.put(tx, gtx);
     }
  
     /**
      * Returns the local transaction entry for the global transaction.
      * Returns null if tx is null or it was not found.
      */
     public TransactionEntry get(GlobalTransaction gtx)
     {
        return gtx != null ? txs.get(gtx) : null;
     }
  
     /**
      * Associates the global transaction with a transaction entry.
      */
     public void put(GlobalTransaction tx, TransactionEntry entry)
     {
        if (tx == null)
        {
           log.error("key (GlobalTransaction) is null");
           return;
        }
        txs.put(tx, entry);
     }
  
     /**
      * Removes a global transation, returns the old transaction entry.
      */
     public TransactionEntry remove(GlobalTransaction tx)
     {
        return txs.remove(tx);
     }
  
     /**
      * Removes a local transation, returns the global transaction entry.
      */
     public GlobalTransaction remove(Transaction tx)
     {
        if (tx == null)
           return null;
        return tx_map.remove(tx);
     }
  
     /**
      * Adds a motification to the global transaction.
      */
     public void addModification(GlobalTransaction gtx, MethodCall m)
     {
        TransactionEntry entry = get(gtx);
        if (entry == null)
        {
           log.error("transaction not found (gtx=" + gtx + ")");
           return;
        }
        entry.addModification(m);
     }
  
     public void addCacheLoaderModification(GlobalTransaction gtx, MethodCall m)
     {
        TransactionEntry entry = get(gtx);
        if (entry == null)
        {
           log.error("transaction not found (gtx=" + gtx + ")");
           return;
        }
        entry.addCacheLoaderModification(m);
     }
  
     /**
      * Adds an undo operation to the global transaction.
      */
     public void addUndoOperation(GlobalTransaction gtx, MethodCall m)
     {
        TransactionEntry entry = get(gtx);
        if (entry == null)
        {
           log.error("transaction not found (gtx=" + gtx + ")");
           return;
        }
        entry.addUndoOperation(m);
     }
  
     /**
      * Adds a lock to the global transaction.
      */
     public void addLock(GlobalTransaction gtx, NodeLock l)
     {
        TransactionEntry entry = get(gtx);
        if (entry == null)
        {
           log.error("transaction entry not found for (gtx=" + gtx + ")");
           return;
        }
        entry.addLock(l);
     }
  
     /**
      * Adds a collection of locks to the global transaction.
      */
     public void addLocks(GlobalTransaction gtx, Collection locks)
     {
        TransactionEntry entry = get(gtx);
        if (entry == null)
        {
           log.error("transaction entry not found for (gtx=" + gtx + ")");
           return;
        }
        entry.addLocks(locks);
     }
  
     /**
      * Returns summary debug information.
      */
     public String toString()
     {
        StringBuffer sb = new StringBuffer();
        sb.append(tx_map.size()).append(" mappings, ");
        sb.append(txs.size()).append(" transactions");
        return sb.toString();
     }
  
     /**
      * Returns detailed debug information.
      */
     public String toString(boolean print_details)
     {
        if (!print_details)
           return toString();
        StringBuffer sb = new StringBuffer();
        Map.Entry entry;
        sb.append("LocalTransactions: ").append(tx_map.size()).append("\n");
        sb.append("GlobalTransactions: ").append(txs.size()).append("\n");
        sb.append("tx_map:\n");
        for (Iterator it = tx_map.entrySet().iterator(); it.hasNext();)
        {
           entry = (Map.Entry) it.next();
           sb.append(entry.getKey()).append(": ").append(entry.getValue()).append("\n");
        }
        sb.append("txs:\n");
        for (Iterator it = txs.entrySet().iterator(); it.hasNext();)
        {
           entry = (Map.Entry) it.next();
           sb.append(entry.getKey()).append(": ").append(entry.getValue()).append("\n");
        }
        return sb.toString();
     }
  
  }
  
  
  
  1.1      date: 2007/02/07 22:06:44;  author: genman;  state: Exp;JBossCache/src/org/jboss/cache/transaction/BatchModeTransactionManagerLookup.java
  
  Index: BatchModeTransactionManagerLookup.java
  ===================================================================
  package org.jboss.cache.transaction;
  
  
  import javax.transaction.TransactionManager;
  
  
  /**
   * Returns an instance of {@link BatchModeTransactionManager}.
   *
   * @author Bela Ban Sept 5 2003
   * @version $Id: BatchModeTransactionManagerLookup.java,v 1.1 2007/02/07 22:06:44 genman Exp $
   */
  public class BatchModeTransactionManagerLookup implements TransactionManagerLookup {
  
     public TransactionManager getTransactionManager() throws Exception {
        return BatchModeTransactionManager.getInstance();
     }
  }
  
  
  
  1.1      date: 2007/02/07 22:06:44;  author: genman;  state: Exp;JBossCache/src/org/jboss/cache/transaction/TransactionManagerLookup.java
  
  Index: TransactionManagerLookup.java
  ===================================================================
  package org.jboss.cache.transaction;
  
  import javax.transaction.TransactionManager;
  
  import org.jboss.cache.Cache;
  import org.jboss.cache.config.Configuration;
  
  /**
   * Factory interface, allows {@link Cache} to use different transactional systems.
   * Names of implementors of this class can be configured using
   * {@link Configuration#setTransactionManagerLookupClass}.
   *
   * @author Bela Ban, Aug 26 2003
   * @version $Id: TransactionManagerLookup.java,v 1.1 2007/02/07 22:06:44 genman Exp $
   */
  public interface TransactionManagerLookup
  {
  
     /**
      * Returns a new TransactionManager.
      *
      * @throws Exception if lookup failed
      */
     TransactionManager getTransactionManager() throws Exception;
  
  }
  
  
  
  1.1      date: 2007/02/07 22:06:44;  author: genman;  state: Exp;JBossCache/src/org/jboss/cache/transaction/JBossTransactionManagerLookup.java
  
  Index: JBossTransactionManagerLookup.java
  ===================================================================
  package org.jboss.cache.transaction;
  
  import javax.naming.InitialContext;
  import javax.transaction.TransactionManager;
  
  
  /**
   * Uses JNDI to look-up the
   * {@link TransactionManager} instance from "java:/TransactionManager".
   *
   * @author Bela Ban, Aug 26 2003
   * @version $Id: JBossTransactionManagerLookup.java,v 1.1 2007/02/07 22:06:44 genman Exp $
   */
  public class JBossTransactionManagerLookup implements TransactionManagerLookup {
  
     public JBossTransactionManagerLookup() {
     }
  
     public TransactionManager getTransactionManager() throws Exception {
        return (TransactionManager)new InitialContext().lookup("java:/TransactionManager");
     }
  
  }
  
  
  
  1.1      date: 2007/02/07 22:06:44;  author: genman;  state: Exp;JBossCache/src/org/jboss/cache/transaction/GlobalTransaction.java
  
  Index: GlobalTransaction.java
  ===================================================================
  /*
   * JBoss, the OpenSource J2EE webOS
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.cache.transaction;
  
  
  import org.jgroups.Address;
  
  import java.io.Externalizable;
  import java.io.IOException;
  import java.io.ObjectInput;
  import java.io.ObjectOutput;
  
  
  /**
   * Uniquely identifies a transaction that spans all nodes in a cluster. This is used when
   * replicating all modifications in a transaction; the PREPARE and COMMIT (or ROLLBACK)
   * messages have to have a unique identifier to associate the changes with<br>
   *
   * @author <a href="mailto:bela at jboss.org">Bela Ban</a> Apr 12, 2003
   * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
   * @version $Revision: 1.1 $
   */
  public class GlobalTransaction implements Externalizable
  {
  
     private static final long serialVersionUID = 8011434781266976149L;
  
     private static long sid = 0;
  
     private Address addr = null;
     private long id = -1;
     private transient boolean remote = false;
  
     // cache the hashcode
     private transient int hash_code = -1;  // in the worst case, hashCode() returns 0, then increases, so we're safe here
  
     /**
      * empty ctor used by externalization
      */
     public GlobalTransaction()
     {
     }
  
     private GlobalTransaction(Address addr)
     {
        this.addr = addr;
        id = newId();
     }
  
     private static synchronized long newId()
     {
        return ++sid;
     }
  
     public static GlobalTransaction create(Address addr)
     {
        return new GlobalTransaction(addr);
     }
  
     public Object getAddress()
     {
        return addr;
     }
  
     public void setAddress(Address address)
     {
        addr = address;
     }
  
     public long getId()
     {
        return id;
     }
  
     public int hashCode()
     {
        if (hash_code == -1)
        {
           hash_code = (addr != null ? addr.hashCode() : 0) + (int) id;
        }
        return hash_code;
     }
  
     public boolean equals(Object other)
     {
        if (this == other)
           return true;
        if (!(other instanceof GlobalTransaction))
           return false;
  
        GlobalTransaction otherGtx = (GlobalTransaction) other;
  
        return ((addr == null && otherGtx.addr == null) || (addr != null && otherGtx.addr != null && addr.compareTo(otherGtx.addr) == 0)) &&
                id == otherGtx.id;
     }
  
     public String toString()
     {
        StringBuffer sb = new StringBuffer();
        sb.append("GlobalTransaction:<").append(addr).append(">:").append(id);
        return sb.toString();
     }
  
     public void writeExternal(ObjectOutput out) throws IOException
     {
        out.writeObject(addr);
        out.writeLong(id);
        // out.writeInt(hash_code);
     }
  
     public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
     {
        addr = (Address) in.readObject();
        id = in.readLong();
        hash_code = -1;
     }
  
     /**
      * @return Returns the remote.
      */
     public boolean isRemote()
     {
        return remote;
     }
  
     /**
      * @param remote The remote to set.
      */
     public void setRemote(boolean remote)
     {
        this.remote = remote;
     }
  
  
     public void setId(long id)
     {
        this.id = id;
     }
  }
  
  
  
  1.1      date: 2007/02/07 22:06:44;  author: genman;  state: Exp;JBossCache/src/org/jboss/cache/transaction/TransactionEntry.java
  
  Index: TransactionEntry.java
  ===================================================================
  /*
   * JBoss, the OpenSource J2EE webOS
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.cache.transaction;
  
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.jboss.cache.CacheSPI;
  import org.jboss.cache.Fqn;
  import org.jboss.cache.Modification;
  import org.jboss.cache.config.Option;
  import org.jboss.cache.lock.IdentityLock;
  import org.jboss.cache.lock.NodeLock;
  import org.jboss.cache.marshall.MethodCall;
  
  import javax.transaction.Transaction;
  import java.util.ArrayList;
  import java.util.Collection;
  import java.util.Iterator;
  import java.util.LinkedHashSet;
  import java.util.LinkedList;
  import java.util.List;
  import java.util.ListIterator;
  
  /**
   * Information associated with a {@link GlobalTransaction} about the transaction state.
   * <p/>
   * A TransactionEntry maintains:
   * <ul>
   * <li>Handle to local Transactions: there can be more than 1 local TX associated with a GlobalTransaction
   * <li>List of modifications ({@link Modification})
   * <li>List of nodes that were created as part of lock acquisition. These nodes can be
   * safely deleted when a transaction is rolled back
   * <li>List of locks ({@link IdentityLock}) that have been acquired by
   * this transaction so far
   * </ul>
   *
   * @author <a href="mailto:bela at jboss.org">Bela Ban</a> Apr 14, 2003
   * @version $Revision: 1.1 $
   */
  public class TransactionEntry
  {
  
     private static Log log = LogFactory.getLog(TransactionEntry.class);
  
     /**
      * Local transaction
      */
     private Transaction ltx = null;
     private Option option;
  
     /**
      * List<MethodCall> of modifications ({@link MethodCall}). They will be replicated on TX commit
      */
     private List<MethodCall> modification_list = new LinkedList<MethodCall>();
     private List<MethodCall> cl_mod_list = new LinkedList<MethodCall>();
  
     /**
      * List<MethodCall>. List of compensating {@link org.jboss.cache.marshall.MethodCall} objects
      * which revert the ones in <tt>modification_list</tt>. For each entry in the modification list,
      * we have a corresponding entry in this list. A rollback will simply iterate over this list in
      * reverse to undo the modifications. Note that these undo-ops will never be replicated.
      */
     private List undo_list = new LinkedList();
  
     /**
      * LinkedHashSet<IdentityLock> of locks acquired by the transaction. We use
      * a LinkedHashSet because we need efficient Set semantics (same lock can
      * be added multiple times) but also need guaranteed ordering for use
      * by lock release code (see JBCCACHE-874).
      */
     private LinkedHashSet locks = new LinkedHashSet();
  
     /**
      * A list of dummy uninitialised nodes created by the cache loader interceptor to load data for a
      * given node in this tx.
      */
     private List dummyNodesCreatedByCacheLoader;
  
     /**
      * List<Fqn> of nodes that have been removed by the transaction
      */
     private List<Fqn> removedNodes = new LinkedList<Fqn>();
     private List<MethodCall> cacheListenerEvents = new LinkedList<MethodCall>();
  
     /**
      * Constructs a new TransactionEntry.
      */
     public TransactionEntry()
     {
     }
  
     /**
      * Adds a modification to the modification list.
      */
     public void addModification(MethodCall m)
     {
        if (m == null) return;
        modification_list.add(m);
     }
  
     public void addCacheLoaderModification(MethodCall m)
     {
        if (m != null) cl_mod_list.add(m);
     }
  
  
     /**
      * Returns all modifications.
      */
     public List<MethodCall> getModifications()
     {
        return modification_list;
     }
  
     public List<MethodCall> getCacheLoaderModifications()
     {
        return cl_mod_list;
     }
  
     /**
      * Adds an undo operation to the undo list.
      *
      * @see #undoOperations
      */
     public void addUndoOperation(MethodCall m)
     {
        undo_list.add(m);
     }
  
     /**
      * Adds the node that has been removed.
      *
      * @param fqn
      */
     public void addRemovedNode(Fqn fqn)
     {
        removedNodes.add(fqn);
     }
  
     /**
      * Gets the list of removed nodes.
      */
     public List<Fqn> getRemovedNodes()
     {
        return new ArrayList(removedNodes);
     }
  
     /**
      * Returns the undo operations in use.
      * Note:  This list may be concurrently modified.
      */
     public List getUndoOperations()
     {
        return undo_list;
     }
  
     /**
      * Sets the local transaction for this entry.
      */
     public void setTransaction(Transaction tx)
     {
        ltx = tx;
     }
  
     /**
      * Returns a local transaction associated with this TransactionEntry
      */
     public Transaction getTransaction()
     {
        return ltx;
     }
  
     /**
      * Adds a lock to the end of the lock list, if it isn't already present.
      */
     public void addLock(NodeLock l)
     {
        if (l != null)
        {
           synchronized (locks)
           {
              locks.add(l);
           }
        }
     }
  
     /**
      * Add multiple locks to the lock list.
      *
      * @param newLocks Collection<IdentityLock>
      */
     public void addLocks(Collection newLocks)
     {
        if (newLocks != null)
        {
           synchronized (locks)
           {
              locks.addAll(newLocks);
           }
        }
     }
  
     /**
      * Returns the locks in use.
      *
      * @return a defensive copy of the internal data structure.
      */
     public List getLocks()
     {
        synchronized (locks)
        {
           return new ArrayList(locks);
        }
     }
  
     /**
      * Calls {@link #releaseAllLocksFIFO}.
      *
      * @deprecated don't think this is used anymore
      */
     public void releaseAllLocks(Object owner)
     {
        releaseAllLocksFIFO(owner);
        synchronized (locks)
        {
           locks.clear();
        }
     }
  
     /**
      * Releases all locks held by the owner, in reverse order of creation.
      * Clears the list of locks held.
      */
     public void releaseAllLocksLIFO(Object owner)
     {
  
        synchronized (locks)
        {
           // Copying out to an array is faster than creating an ArrayList and iterating,
           // since list creation will just copy out to an array internally
           IdentityLock[] lockArray = (IdentityLock[]) locks.toArray(new IdentityLock[locks.size()]);
           for (int i = lockArray.length - 1; i >= 0; i--)
           {
              if (log.isTraceEnabled())
              {
                 log.trace("releasing lock for " + lockArray[i].getFqn() + " (" + lockArray[i] + ")");
              }
              lockArray[i].release(owner);
           }
           locks.clear();
        }
     }
  
     /**
      * Releases all locks held by the owner, in order of creation.
      * Does not clear the list of locks held.
      */
     public void releaseAllLocksFIFO(Object owner)
     {
        // I guess a copy would work as well
        // This seems fairly safe though
        synchronized (locks)
        {
           for (Iterator i = locks.iterator(); i.hasNext();)
           {
              IdentityLock lock = (IdentityLock) i.next();
              lock.release(owner);
              if (log.isTraceEnabled())
              {
                 log.trace("releasing lock for " + lock.getFqn() + " (" + lock + ")");
              }
           }
        }
     }
  
     /**
      * Posts all undo operations to the CacheImpl.
      */
     public void undoOperations(CacheSPI cache)
     {
        if (log.isTraceEnabled())
        {
           log.trace("undoOperations " + undo_list);
        }
        ArrayList l;
        synchronized (undo_list)
        {
           l = new ArrayList(undo_list);
        }
        for (ListIterator i = l.listIterator(l.size()); i.hasPrevious();)
        {
           MethodCall undo_op = (MethodCall) i.previous();
           undo(undo_op, cache);
        }
     }
  
     private void undo(MethodCall undo_op, CacheSPI cache)
     {
        try
        {
           Object retval = undo_op.invoke(cache);
           if (retval instanceof Throwable)
           {
              throw (Throwable) retval;
           }
        }
        catch (Throwable t)
        {
           log.error("undo operation failed, error=" + t);
           log.trace(t, t);
        }
     }
  
     /**
      * Returns debug information about this transaction.
      */
     public String toString()
     {
        StringBuffer sb = new StringBuffer();
        sb.append("\nmodification_list: ").append(modification_list);
        synchronized (undo_list)
        {
           sb.append("\nundo_list: ").append(undo_list);
        }
        synchronized (locks)
        {
           sb.append("\nlocks: ").append(locks);
        }
        return sb.toString();
     }
  
     public void loadUninitialisedNode(Fqn fqn)
     {
        if (dummyNodesCreatedByCacheLoader == null)
           dummyNodesCreatedByCacheLoader = new LinkedList();
        dummyNodesCreatedByCacheLoader.add(fqn);
     }
  
     public List getDummyNodesCreatedByCacheLoader()
     {
        return dummyNodesCreatedByCacheLoader;
     }
  
     /**
      * Sets a transaction-scope option override
      *
      * @param o
      */
     public void setOption(Option o)
     {
        this.option = o;
     }
  
     /**
      * Retrieves a transaction scope option override
      */
     public Option getOption()
     {
        return this.option;
     }
  
     public void addCacheListenerEvents(List<MethodCall> cacheListenerEvents)
     {
        this.cacheListenerEvents.addAll(cacheListenerEvents);
     }
  
     public List<MethodCall> getCacheListenerEvents()
     {
        return cacheListenerEvents;
     }
  }
  
  
  
  1.1      date: 2007/02/07 22:06:44;  author: genman;  state: Exp;JBossCache/src/org/jboss/cache/transaction/DummyTransactionManagerLookup.java
  
  Index: DummyTransactionManagerLookup.java
  ===================================================================
  package org.jboss.cache.transaction;
  
  
  import javax.transaction.TransactionManager;
  
  
  /**
   * Returns an instance of {@link DummyTransactionManager}.
   *
   * @author Bela Ban Sept 5 2003
   * @version $Id: DummyTransactionManagerLookup.java,v 1.1 2007/02/07 22:06:44 genman Exp $
   */
  public class DummyTransactionManagerLookup implements TransactionManagerLookup {
  
     public TransactionManager getTransactionManager() throws Exception {
        return DummyTransactionManager.getInstance();
     }
  }
  
  
  



More information about the jboss-cvs-commits mailing list