[jboss-cvs] JBossCache/src/org/jboss/cache/aop/statetransfer ...

Brian Stansberry brian.stansberry at jboss.com
Thu Jul 20 17:58:22 EDT 2006


  User: bstansberry
  Date: 06/07/20 17:58:22

  Added:       src/org/jboss/cache/aop/statetransfer    
                        PojoStateTransferFactory.java
                        PojoStateTransferManager.java
                        PojoStateTransferIntegrator_200.java
                        PojoStateTransferGenerator_200.java
  Log:
  [JBCACHE-465] Extract the state transfer code out of TreeCache
  
  Revision  Changes    Path
  1.1      date: 2006/07/20 21:58:22;  author: bstansberry;  state: Exp;JBossCache/src/org/jboss/cache/aop/statetransfer/PojoStateTransferFactory.java
  
  Index: PojoStateTransferFactory.java
  ===================================================================
  /*
   * JBoss, the OpenSource J2EE webOS
   * 
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.cache.aop.statetransfer;
  
  import java.io.ByteArrayInputStream;
  import java.io.IOException;
  
  import org.jboss.cache.Fqn;
  import org.jboss.cache.TreeCache;
  import org.jboss.cache.Version;
  import org.jboss.cache.statetransfer.StateTransferGenerator;
  import org.jboss.cache.statetransfer.StateTransferIntegrator;
  import org.jboss.invocation.MarshalledValueInputStream;
  
  /**
   * Factory class able to create {@link StateTransferGenerator} and 
   * {@link StateTransferIntegrator} instances.
   * 
   * @author <a href="brian.stansberry at jboss.com">Brian Stansberry</a>
   * @version $Revision: 1.1 $
   */
  public abstract class PojoStateTransferFactory
  {
     private static final short RV_200 = Version.getVersionShort("2.0.0");
     
     /**
      * Gets the StateTransferGenerator able to handle the given cache instance.
      * 
      * @param cache the cache
      * 
      * @return the {@link StateTransferGenerator}
      * 
      * @throws IllegalStateException if the cache's ReplicationVersion is < 2.0.0
      */
     public static StateTransferGenerator 
           getStateTransferGenerator(TreeCache cache)
     {
        short version = cache.getConfiguration().getReplicationVersion();
        
        // Compiler won't let me use a switch
        
        if (version < RV_200 && version > 0) // <= 0 is actually a version > 15.31.63
           throw new IllegalStateException("State transfer with cache replication version < 2.0.0 not supported");
        else
           return new PojoStateTransferGenerator_200(cache); // current default
     }
     
     /**
      * Gets a StateTransferIntegrator able to handle the given state.
      * 
      * @param state      the state
      * @param targetFqn  Fqn of the node to which the state will be bound
      * @param cache      cache in which the state will be stored
      * @return           the {@link StateTransferIntegrator}.
      * 
      * @throws IllegalStateException if the cache's ReplicationVersion is < 2.0.0
      * @throws Exception
      */
     public static StateTransferIntegrator 
        getStateTransferIntegrator(byte[] state, Fqn targetFqn, TreeCache cache) 
           throws Exception
     {
        ByteArrayInputStream bais = new ByteArrayInputStream(state);
        bais.mark(1024);      
        
        short version = 0;
        MarshalledValueInputStream in = new MarshalledValueInputStream(bais);
        try {
           try
           {
              version = in.readShort();
           }
           catch (IOException io)
           {
              // No short at the head of the stream means version 123
              throw new IllegalStateException("State transfer with cache replication version < 2.0.0 not supported");
           }
           
           // Compiler won't let me use a switch
           
           if (version < RV_200 && version > 0) // <= 0 is actually a version > 15.31.63
              throw new IllegalStateException("State transfer with cache replication version < 2.0.0 not supported");
           else
              return new PojoStateTransferIntegrator_200(state, targetFqn, cache); // current default
                   
        }
        finally {
           try {
              in.close();         
           }
           catch (IOException io) {}
        }
     }
  }
  
  
  
  1.1      date: 2006/07/20 21:58:22;  author: bstansberry;  state: Exp;JBossCache/src/org/jboss/cache/aop/statetransfer/PojoStateTransferManager.java
  
  Index: PojoStateTransferManager.java
  ===================================================================
  package org.jboss.cache.aop.statetransfer;
  
  import java.util.Iterator;
  import java.util.Map;
  
  import org.jboss.cache.CacheException;
  import org.jboss.cache.DataNode;
  import org.jboss.cache.Fqn;
  import org.jboss.cache.TreeCache;
  import org.jboss.cache.aop.InternalDelegate;
  import org.jboss.cache.aop.util.ObjectUtil;
  import org.jboss.cache.statetransfer.StateTransferGenerator;
  import org.jboss.cache.statetransfer.StateTransferIntegrator;
  import org.jboss.cache.statetransfer.StateTransferManager;
  
  public class PojoStateTransferManager extends StateTransferManager
  {
     public PojoStateTransferManager(TreeCache cache)
     {
        super(cache);
     }   
     
     protected StateTransferGenerator getStateTransferGenerator()
     {
        return PojoStateTransferFactory.getStateTransferGenerator(getTreeCache());
     }
     
     protected StateTransferIntegrator getStateTransferIntegrator(byte[] state, Fqn targetFqn)
           throws Exception
     {
        return PojoStateTransferFactory.getStateTransferIntegrator(state, targetFqn, getTreeCache());
     }
  
     /**
      * Overrides the superclass version by additionally acquiring locks
      * on the internal reference map nodes used for tracking shared objects.
      */
     protected void acquireLocksForStateTransfer(DataNode root,
                                                 Object lockOwner,
                                                 long timeout,
                                                 boolean force)
           throws Exception
     {
        
        super.acquireLocksForStateTransfer(root, lockOwner, timeout, true, force);
        Fqn fqn = root.getFqn();
  
        if (fqn.size() > 0 &&
              !fqn.isChildOf(InternalDelegate.JBOSS_INTERNAL))
        {
           DataNode refMapNode = getTreeCache().get(InternalDelegate.JBOSS_INTERNAL_MAP);
           if (refMapNode != null)
           {
  
              // Lock the internal map node but not its children to
              // prevent the addition of other children
              super.acquireLocksForStateTransfer(refMapNode, lockOwner, timeout,
                    false, force);
  
              // Walk through the children, and lock any whose name starts
              // with the string version of our root node's Fqn
              Map children = refMapNode.getChildren();
              if (children != null)
              {
  
                 String targetFqn = ObjectUtil.getIndirectFqn(fqn);
  
                 Map.Entry entry;
                 for (Iterator iter = children.entrySet().iterator();
                      iter.hasNext();)
                 {
                    entry = (Map.Entry) iter.next();
                    if (((String) entry.getKey()).startsWith(targetFqn))
                    {
                       super.acquireLocksForStateTransfer((DataNode) entry.getValue(),
                             lockOwner, timeout,
                             false, force);
                    }
                 }
              }
           }
        }
     }
  
     /**
      * Overrides the superclass version by additionally releasing locks
      * on the internal reference map nodes used for tracking shared objects.
      */
     protected void releaseStateTransferLocks(DataNode root, Object lockOwner)
     {
        boolean releaseInternal = true;
        try
        {
           super.releaseStateTransferLocks(root, lockOwner, true);
           Fqn fqn = root.getFqn();
           releaseInternal = (fqn.size() > 0 &&
                 !fqn.isChildOf(InternalDelegate.JBOSS_INTERNAL));
        }
        finally
        {
           if (releaseInternal)
           {
              try
              {
                 DataNode refMapNode = getTreeCache().get(InternalDelegate.JBOSS_INTERNAL_MAP);
                 if (refMapNode != null)
                 {
                    // Rather than going to the effort of identifying which
                    // child nodes we locked before, just release all children
                    super.releaseStateTransferLocks(refMapNode, lockOwner, true);
                 }
              }
              catch (CacheException ce)
              {
                 log.error("Caught exception releasing locks on internal RefMap", ce);
              }
           }
        }
     }
     
  }
  
  
  
  1.1      date: 2006/07/20 21:58:22;  author: bstansberry;  state: Exp;JBossCache/src/org/jboss/cache/aop/statetransfer/PojoStateTransferIntegrator_200.java
  
  Index: PojoStateTransferIntegrator_200.java
  ===================================================================
  /*
   * JBoss, the OpenSource J2EE webOS
   * 
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.cache.aop.statetransfer;
  
  import java.io.ByteArrayInputStream;
  import java.io.EOFException;
  
  import org.jboss.cache.DataNode;
  import org.jboss.cache.Fqn;
  import org.jboss.cache.TreeCache;
  import org.jboss.cache.TreeNode;
  import org.jboss.cache.aop.InternalDelegate;
  import org.jboss.cache.factories.NodeFactory;
  import org.jboss.cache.statetransfer.StateTransferIntegrator_200;
  import org.jboss.invocation.MarshalledValueInputStream;
  
  class PojoStateTransferIntegrator_200 extends StateTransferIntegrator_200
  {
       
     
     protected PojoStateTransferIntegrator_200(byte[] state, Fqn targetFqn,  
                                 TreeCache cache) throws Exception
     {
        super(state, targetFqn, cache);
     }
     
     protected void integrateAssociatedState() throws Exception
     {
        if (getAssociatedSize() > 0) {
           
           TreeCache cache = getCache();
           DataNode refMapNode = cache.get(InternalDelegate.JBOSS_INTERNAL_MAP);
  
           ByteArrayInputStream in_stream=new ByteArrayInputStream(getState(), HEADER_LENGTH + getTransientSize(), getAssociatedSize());
           MarshalledValueInputStream in=new MarshalledValueInputStream(in_stream);
           
           try {
              Object[] nameValue;
              NodeFactory factory = getFactory();
              while ((nameValue = (Object[]) in.readObject()) != null) {
                 TreeNode target = refMapNode.getChild(nameValue[0]);
                 
                 if (target == null) {
                    // Create the node
                    Fqn fqn = new Fqn(InternalDelegate.JBOSS_INTERNAL_MAP, nameValue[0]);
                    target = factory.createDataNode(getNodeType(), 
                                                    nameValue[0], 
                                                    fqn, 
                                                    refMapNode, 
                                                    null, 
                                                    true,
                                                    cache);
                    refMapNode.addChild(nameValue[0], target);
                 }
                 
                 target.put(nameValue[0], nameValue[1]);
              }
           }
           catch (EOFException eof) {
              // all done
           }
           
           if (log.isTraceEnabled())
              log.trace("associated state successfully integrated for " + getTargetFqn());
        }
        else if (log.isTraceEnabled()) {
           log.trace("No need to integrate associated state for " + getTargetFqn());
        }
     }
  }
  
  
  
  1.1      date: 2006/07/20 21:58:22;  author: bstansberry;  state: Exp;JBossCache/src/org/jboss/cache/aop/statetransfer/PojoStateTransferGenerator_200.java
  
  Index: PojoStateTransferGenerator_200.java
  ===================================================================
  /*
   * JBoss, the OpenSource J2EE webOS
   * 
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.cache.aop.statetransfer;
  
  import java.io.OutputStream;
  import java.util.Iterator;
  import java.util.Map;
  
  import org.jboss.cache.DataNode;
  import org.jboss.cache.Fqn;
  import org.jboss.cache.TreeCache;
  import org.jboss.cache.aop.InternalDelegate;
  import org.jboss.cache.aop.util.ObjectUtil;
  import org.jboss.cache.statetransfer.StateTransferGenerator_200;
  import org.jboss.invocation.MarshalledValueOutputStream;
  
  class PojoStateTransferGenerator_200 extends StateTransferGenerator_200
  {
     protected PojoStateTransferGenerator_200(TreeCache cache)
     {
        super(cache);
     }
     
     /**
      * For each node in the internal reference map that is associated with the 
      * given Fqn, writes an Object[] to the stream containing the node's
      * name and the value of its sole attribute.  Does nothing if the Fqn is the 
      * root node (i.e. "/") or if it is in the internal reference area itself.
      */
     protected void marshallAssociatedState(Fqn fqn, OutputStream baos) 
           throws Exception
     {
        if (fqn == null 
              || fqn.size() == 0 
              || fqn.isChildOf(InternalDelegate.JBOSS_INTERNAL))
           return;
  
        MarshalledValueOutputStream out = new MarshalledValueOutputStream(baos);
        
        DataNode refMapNode = getTreeCache().get(InternalDelegate.JBOSS_INTERNAL_MAP);
        
        Map children = null;
        if (refMapNode != null && (children = refMapNode.getChildren()) != null) {
           
           String targetFqn = ObjectUtil.getIndirectFqn(fqn.toString());
           
           Map.Entry entry;
           String key;
           DataNode value;
           for (Iterator iter = children.entrySet().iterator(); iter.hasNext();) {
              entry = (Map.Entry) iter.next();
              key = (String) entry.getKey();
              if (key.startsWith(targetFqn)) {
                 value = (DataNode) entry.getValue();
                 out.writeObject(new Object[] { key, value.get(key) });
              }
           }
        }
        
        out.close();
        
     }
  }
  
  
  



More information about the jboss-cvs-commits mailing list