[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