[jboss-cvs] JBossCache/src/org/jboss/cache/interceptors ...
Manik Surtani
manik at jboss.org
Fri Mar 30 10:02:09 EDT 2007
User: msurtani
Date: 07/03/30 10:02:09
Modified: src/org/jboss/cache/interceptors
OptimisticReplicationInterceptor.java
OptimisticNodeInterceptor.java
Log:
Final refactorings
Revision Changes Path
1.37 +6 -4 JBossCache/src/org/jboss/cache/interceptors/OptimisticReplicationInterceptor.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: OptimisticReplicationInterceptor.java
===================================================================
RCS file: /cvsroot/jboss/JBossCache/src/org/jboss/cache/interceptors/OptimisticReplicationInterceptor.java,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -b -r1.36 -r1.37
--- OptimisticReplicationInterceptor.java 29 Mar 2007 16:02:58 -0000 1.36
+++ OptimisticReplicationInterceptor.java 30 Mar 2007 14:02:09 -0000 1.37
@@ -264,7 +264,7 @@
// get the data version associated with this orig call.
// since these are all crud methods the Fqn is at arg subscript 1.
- Fqn fqn = (Fqn) origArgs[1];
+ Fqn fqn = (Fqn) origArgs[origCall.getMethodId() == MethodDeclarations.moveMethodLocal_id ? 0 : 1];
// now get a hold of the data version for this specific modification
DataVersion versionToBroadcast = getVersionToBroadcast(w, fqn);
@@ -301,6 +301,8 @@
DefaultDataVersion v = (DefaultDataVersion) n.getVersion();
if (log.isTraceEnabled())
log.trace("Fqn " + f + " has implicit versioning. Broadcasting an incremented version.");
+
+ // potential bug here - need to check if we *need* to increment at all, because of Configuration.isLockParentForChildInsertRemove()
return v.increment();
}
else
1.60 +202 -198 JBossCache/src/org/jboss/cache/interceptors/OptimisticNodeInterceptor.java
(In the diff below, changes in quantity of whitespace are not shown.)
Index: OptimisticNodeInterceptor.java
===================================================================
RCS file: /cvsroot/jboss/JBossCache/src/org/jboss/cache/interceptors/OptimisticNodeInterceptor.java,v
retrieving revision 1.59
retrieving revision 1.60
diff -u -b -r1.59 -r1.60
--- OptimisticNodeInterceptor.java 29 Mar 2007 16:02:58 -0000 1.59
+++ OptimisticNodeInterceptor.java 30 Mar 2007 14:02:09 -0000 1.60
@@ -17,6 +17,7 @@
import org.jboss.cache.config.Option;
import org.jboss.cache.marshall.MethodCall;
import org.jboss.cache.marshall.MethodDeclarations;
+import org.jboss.cache.notifications.Notifier;
import org.jboss.cache.optimistic.DataVersion;
import org.jboss.cache.optimistic.DefaultDataVersion;
import org.jboss.cache.optimistic.TransactionWorkspace;
@@ -24,87 +25,49 @@
import org.jboss.cache.transaction.GlobalTransaction;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.Map;
import java.util.SortedMap;
/**
- * Operations on nodes are done on the copies that exist in the workspace rather than passed down to the {@link org.jboss.cache.interceptors.CallInterceptor}
+ * Operations on nodes are done on the copies that exist in the workspace rather than passed down
+ * to the {@link org.jboss.cache.interceptors.CallInterceptor}. These operations happen in this interceptor.
*
* @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 OptimisticNodeInterceptor extends OptimisticInterceptor
{
+ /**
+ * Needed for the creation of workspace nodes based on underlying nodes in the cache.
+ */
private NodeFactory nodeFactory;
+ private Notifier notifier;
public void setCache(CacheSPI c)
{
super.setCache(c);
nodeFactory = c.getConfiguration().getRuntimeConfig().getNodeFactory();
+ notifier = cache.getNotifier();
}
public Object invoke(MethodCall m) throws Throwable
{
- // bypass for buddy group org method calls.
- if (MethodDeclarations.isBuddyGroupOrganisationMethod(m.getMethodId())) return super.invoke(m);
-
- if (trace) log.trace("Processing method call " + m);
-
InvocationContext ctx = cache.getInvocationContext();
Object[] args = m.getArgs();
Object result = null;
- GlobalTransaction gtx = ctx.getGlobalTransaction();
-
- TransactionWorkspace workspace = getTransactionWorkspace(gtx);
-
- if (MethodDeclarations.moveMethodLocal_id == m.getMethodId())
- {
- if (ctx.getOptionOverrides().getDataVersion() != null && ctx.isOriginLocal())
- {
- throw new CacheException("Setting a data version while performing a move() is not supported!!");
- }
-
- Fqn parentFqn = (Fqn) args[1], nodeFqn = (Fqn) args[0];
-
- if (trace)
- {
- log.trace("Adding nodes " + parentFqn + " and " + nodeFqn + " to the workspace.");
- }
-
- WorkspaceNode parent = getOrCreateWorkspaceNode(parentFqn, workspace, false);
- if (parent == null) throw new NodeNotExistsException("Node " + parentFqn + " does not exist!");
- WorkspaceNode node = getOrCreateWorkspaceNode(nodeFqn, workspace, true);
-
- if (trace)
- {
- log.trace("Parent: " + parent);
- log.trace("Node: " + node);
- log.trace("Workspace snapshot: " + workspace);
- }
-
- // be greedy about it - get children as well.
- greedyGetNodes(node, workspace);
-
- // now that we have all we need in the workspace, perform the move.
-
- doMove(parent, node, workspace);
-
- addToModificationList(gtx, m);
- }
- else if (MethodDeclarations.isCrudMethod(m.getMethodId()))
+ if (MethodDeclarations.isCrudMethod(m.getMethodId()))
{
- // assign a global transaction here if we need to - should do all
- // this in the transaction interceptor
- Fqn fqn = getFqn(args);
- WorkspaceNode workspaceNode = getOrCreateWorkspaceNode(fqn, workspace, true);
+ GlobalTransaction gtx = getGlobalTransaction();
+ TransactionWorkspace workspace = getTransactionWorkspace(gtx);
+ Fqn fqn = getFqn(args, m.getMethodId());
+ WorkspaceNode workspaceNode = fetchWorkspaceNode(fqn, workspace, true);
// in the case of a data gravitation cleanup, if the primary Fqn does not exist the backup one may.
if (workspaceNode == null && m.getMethodId() == MethodDeclarations.dataGravitationCleanupMethod_id)
{
- workspaceNode = getOrCreateWorkspaceNode(getBackupFqn(args), workspace, true);
+ workspaceNode = fetchWorkspaceNode(getBackupFqn(args), workspace, true);
}
if (workspaceNode != null)
@@ -112,6 +75,10 @@
// use explicit versioning
if (ctx.getOptionOverrides() != null && ctx.getOptionOverrides().getDataVersion() != null)
{
+ // if the method call is a move() then barf. Note that remove calls will set data versions explicitly, regardless.
+ if (ctx.isOriginLocal() && m.getMethodId() == MethodDeclarations.moveMethodLocal_id)
+ throw new CacheException("Setting a data version while performing a move() is not supported!!");
+
workspace.setVersioningImplicit(false);
DataVersion version = ctx.getOptionOverrides().getDataVersion();
@@ -131,57 +98,43 @@
// "fail-more-silently" patch thanks to Owen Taylor - JBCACHE-767
if ((ctx.getOptionOverrides() == null || !ctx.getOptionOverrides().isFailSilently()) && MethodDeclarations.isPutMethod(m.getMethodId()))
{
- throw new CacheException("Unable to set node version for " + getFqn(args) + ", node is null.");
+ throw new CacheException("Unable to set node version for " + fqn + ", node is null.");
}
}
switch (m.getMethodId())
{
+ case MethodDeclarations.moveMethodLocal_id:
+ Fqn parentFqn = (Fqn) args[1];
+ moveNodeAndNotify(parentFqn, workspaceNode, workspace);
+ break;
case MethodDeclarations.putDataMethodLocal_id:
Boolean erase = (Boolean) args[3];
- cache.getNotifier().notifyNodeModified(fqn, true, CacheListener.ModificationType.PUT_MAP, workspaceNode.getData(), false);
- putDataMap((Map<Object, Object>) args[2], erase, workspace, workspaceNode);
- cache.getNotifier().notifyNodeModified(fqn, false, CacheListener.ModificationType.PUT_MAP, workspaceNode.getData(), false);
+ putDataMapAndNotify((Map<Object, Object>) args[2], erase, workspace, workspaceNode);
break;
case MethodDeclarations.putDataEraseMethodLocal_id:
- cache.getNotifier().notifyNodeModified(fqn, true, CacheListener.ModificationType.PUT_MAP, workspaceNode.getData(), false);
- putDataMap((Map<Object, Object>) args[2], true, workspace, workspaceNode);
- cache.getNotifier().notifyNodeModified(fqn, false, CacheListener.ModificationType.PUT_MAP, workspaceNode.getData(), false);
+ putDataMapAndNotify((Map<Object, Object>) args[2], true, workspace, workspaceNode);
break;
case MethodDeclarations.putKeyValMethodLocal_id:
case MethodDeclarations.putForExternalReadMethodLocal_id:
Object key = args[2];
Object value = args[3];
- Map addedData = new HashMap();
- addedData.put(key, value);
-
- cache.getNotifier().notifyNodeModified(fqn, true, CacheListener.ModificationType.PUT_DATA, workspaceNode.getData(), false);
- result = putDataKeyValue(key, value, workspace, workspaceNode);
- cache.getNotifier().notifyNodeModified(fqn, false, CacheListener.ModificationType.PUT_DATA, addedData, false);
+ result = putDataKeyValueAndNotify(key, value, workspace, workspaceNode);
break;
case MethodDeclarations.removeNodeMethodLocal_id:
- cache.getNotifier().notifyNodeRemoved(fqn, true, workspaceNode == null ? null : workspaceNode.getData(), false);
- result = removeNode(workspace, workspaceNode);
- cache.getNotifier().notifyNodeRemoved(fqn, false, null, false);
+ result = removeNodeAndNotify(workspace, workspaceNode);
break;
case MethodDeclarations.removeKeyMethodLocal_id:
- cache.getNotifier().notifyNodeModified(fqn, true, CacheListener.ModificationType.REMOVE_DATA, workspaceNode == null ? null : workspaceNode.getData(), false);
Object removeKey = args[2];
- result = removeKey(removeKey, workspace, workspaceNode);
- Map removedData = new HashMap();
- removedData.put(removeKey, result);
- cache.getNotifier().notifyNodeModified(fqn, false, CacheListener.ModificationType.REMOVE_DATA, removedData, false);
+ result = removeKeyAndNotify(removeKey, workspace, workspaceNode);
break;
case MethodDeclarations.removeDataMethodLocal_id:
- Map data = workspaceNode == null ? null : new HashMap(workspaceNode.getData());
- cache.getNotifier().notifyNodeModified(fqn, true, CacheListener.ModificationType.REMOVE_DATA, data, false);
- removeData(workspace, workspaceNode);
- cache.getNotifier().notifyNodeModified(fqn, false, CacheListener.ModificationType.REMOVE_DATA, data, false);
+ removeDataAndNotify(workspace, workspaceNode);
break;
case MethodDeclarations.dataGravitationCleanupMethod_id:
result = super.invoke(m);
default:
- if (log.isInfoEnabled()) log.info("Cannot Handle Method " + m);
+ if (log.isWarnEnabled()) log.warn("Cannot handle CRUD method " + m);
break;
}
@@ -192,22 +145,19 @@
switch (m.getMethodId())
{
case MethodDeclarations.getKeyValueMethodLocal_id:
- result = getValueForKey(args, workspace);
+ result = getValueForKeyAndNotify(args, getTransactionWorkspace(getGlobalTransaction()));
break;
case MethodDeclarations.getKeysMethodLocal_id:
- result = getKeys(args, workspace);
+ result = getKeysAndNotify(args, getTransactionWorkspace(getGlobalTransaction()));
break;
case MethodDeclarations.getChildrenNamesMethodLocal_id:
- result = getChildNames(args, workspace);
+ result = getChildNamesAndNotify(args, getTransactionWorkspace(getGlobalTransaction()));
break;
case MethodDeclarations.getNodeMethodLocal_id:
- result = getNode(args, workspace);
+ result = getNodeAndNotify(args, getTransactionWorkspace(getGlobalTransaction()));
break;
default:
- if (log.isInfoEnabled())
- {
- log.info("read Method " + m + " called - don't know how to handle, passing on!");
- }
+ if (trace) log.trace("read Method " + m + " called - Not handling, passing on.");
result = super.invoke(m);
break;
}
@@ -215,11 +165,34 @@
return result;
}
+ /**
+ * Extracts the Fqn from the array of arguments passed in
+ *
+ * @param args array of args
+ * @return fqn
+ */
+ private Fqn getFqn(Object[] args, int methodId)
+ {
+ return (Fqn) args[methodId == MethodDeclarations.moveMethodLocal_id ? 0 : 1];
+ }
+
+ /**
+ * Retrieves a backup fqn in an array of arguments. This is typically used to parse arguments from a data gravitation cleanup method.
+ *
+ * @param args array of arguments to parse
+ * @return an Fqn
+ */
private Fqn getBackupFqn(Object[] args)
{
return (Fqn) args[2];
}
+ /**
+ * Adds a method call to the modification list of a given transaction's transaction entry
+ *
+ * @param gtx transaction
+ * @param m methodcall to add
+ */
private void addToModificationList(GlobalTransaction gtx, MethodCall m)
{
Option opt = cache.getInvocationContext().getOptionOverrides();
@@ -232,7 +205,21 @@
}
- public void doMove(WorkspaceNode parent, WorkspaceNode node, TransactionWorkspace ws)
+ // -----------------------------------------------------------------
+
+ // Methods that mimic core functionality in the cache, except that they work on WorkspaceNodes in the TransactionWorkspace.
+
+ // -----------------------------------------------------------------
+
+
+ /**
+ * Performs a move within the workspace.
+ *
+ * @param parentFqn parent under which the node is to be moved
+ * @param node node to move
+ * @param ws transaction workspace
+ */
+ private void moveNodeAndNotify(Fqn parentFqn, WorkspaceNode node, TransactionWorkspace ws)
{
Fqn nodeFqn = node.getFqn();
if (nodeFqn.isRoot())
@@ -240,134 +227,110 @@
log.warn("Attempting to move the root node. Not taking any action, treating this as a no-op.");
return;
}
- WorkspaceNode oldParent = getOrCreateWorkspaceNode(nodeFqn.getParent(), ws, false);
+ // retrieve parent
+ WorkspaceNode parent = fetchWorkspaceNode(parentFqn, ws, false);
+ if (parent == null) throw new NodeNotExistsException("Node " + parentFqn + " does not exist!");
+
+ WorkspaceNode oldParent = fetchWorkspaceNode(nodeFqn.getParent(), ws, false);
if (oldParent == null) throw new NodeNotExistsException("Node " + nodeFqn.getParent() + " does not exist!");
+
Object nodeName = nodeFqn.getLastElement();
// now that we have the parent and target nodes:
// first correct the pointers at the pruning point
oldParent.removeChild(new Fqn(nodeName));
- // parent.addChild(nodeName, node);
- // parent.createChild(nodeName, nodeFqn, parent.getNode(), ((TreeCacheProxyImpl)cache).cache, null);
// parent pointer is calculated on the fly using Fqns.
-
// now adjust Fqns of node and all children.
- // notify
Fqn nodeNewFqn = new Fqn(parent.getFqn(), nodeFqn.getLastElement());
- cache.getNotifier().notifyNodeMoved(nodeFqn, nodeNewFqn, true, false);
- moveFqns(node, parent.getFqn(), ws);
+
+ // pre-notify
+ notifier.notifyNodeMoved(nodeFqn, nodeNewFqn, true, false);
+ recursiveMoveNode(node, parent.getFqn(), ws);
// remove old nodes. this may mark some nodes which have already been moved as deleted
- removeNode(ws, node);
+ removeNodeAndNotify(ws, node);
- // notify
- cache.getNotifier().notifyNodeMoved(nodeFqn, nodeNewFqn, false, false);
+ // post-notify
+ notifier.notifyNodeMoved(nodeFqn, nodeNewFqn, false, false);
}
/**
* Moves a node to a new base.
+ *
+ * @param node node to move
+ * @param newBase new base Fqn under which the given node will now exist
+ * @param ws transaction workspace
*/
- private void moveFqns(WorkspaceNode node, Fqn newBase, TransactionWorkspace ws)
+ private void recursiveMoveNode(WorkspaceNode node, Fqn newBase, TransactionWorkspace ws)
{
Fqn newFqn = new Fqn(newBase, node.getFqn().getLastElement());
- WorkspaceNode movedNode = getOrCreateWorkspaceNode(newFqn, ws, true);
+ WorkspaceNode movedNode = fetchWorkspaceNode(newFqn, ws, true);
movedNode.putAll(node.getData());
// process children
for (Object n : node.getChildrenNames())
{
- WorkspaceNode child = getOrCreateWorkspaceNode(new Fqn(node.getFqn(), n), ws, false);
- if (child != null) moveFqns(child, newFqn, ws);
+ WorkspaceNode child = fetchWorkspaceNode(new Fqn(node.getFqn(), n), ws, false);
+ if (child != null) recursiveMoveNode(child, newFqn, ws);
}
}
- /**
- * performs a getOrCreateNode on all n's children, recursively.
- *
- * @param n
- */
- protected void greedyGetNodes(WorkspaceNode n, TransactionWorkspace ws)
- {
- Fqn myFqn = n.getFqn();
-
- for (Object child : n.getChildrenNames())
- {
- Fqn childFqn = new Fqn(myFqn, child);
- WorkspaceNode cn = getOrCreateWorkspaceNode(childFqn, ws, false);
- if (!ws.hasNode(childFqn)) ws.addNode(cn);
- greedyGetNodes(cn, ws);
- }
- }
-
- private Fqn getFqn(Object[] args)
- {
- return (Fqn) args[1];
- }
-
- private void putDataMap(Map<Object, Object> data, boolean eraseExisitng,
- TransactionWorkspace workspace, WorkspaceNode workspaceNode)
+ private void putDataMapAndNotify(Map<Object, Object> data, boolean eraseExisitng, TransactionWorkspace workspace, WorkspaceNode workspaceNode)
{
if (workspaceNode == null)
- {
- return;
- }
+ throw new NodeNotExistsException("optimisticCreateIfNotExistsInterceptor should have created this node!");
+ // pre-notify
+ notifier.notifyNodeModified(workspaceNode.getFqn(), true, CacheListener.ModificationType.PUT_MAP, workspaceNode.getData(), false);
if (eraseExisitng) workspaceNode.clearData();
workspaceNode.putAll(data);
workspace.addNode(workspaceNode);
+ // post-notify
+ notifier.notifyNodeModified(workspaceNode.getFqn(), false, CacheListener.ModificationType.PUT_MAP, workspaceNode.getData(), false);
}
- private Object putDataKeyValue(Object key, Object value, TransactionWorkspace workspace, WorkspaceNode workspaceNode)
+ private Object putDataKeyValueAndNotify(Object key, Object value, TransactionWorkspace workspace, WorkspaceNode workspaceNode)
{
if (workspaceNode == null)
- {
- return null;// this should be an exception
- }
+ throw new NodeNotExistsException("optimisticCreateIfNotExistsInterceptor should have created this node!");
+
+ Map addedData = new HashMap();
+ addedData.put(key, value);
+ // pre-notify
+ notifier.notifyNodeModified(workspaceNode.getFqn(), true, CacheListener.ModificationType.PUT_DATA, workspaceNode.getData(), false);
Object old = workspaceNode.put(key, value);
workspace.addNode(workspaceNode);
+
+ // post-notify
+ notifier.notifyNodeModified(workspaceNode.getFqn(), false, CacheListener.ModificationType.PUT_DATA, addedData, false);
+
return old;
}
- private boolean removeNode(TransactionWorkspace workspace, WorkspaceNode workspaceNode) throws CacheException
+ private boolean removeNodeAndNotify(TransactionWorkspace workspace, WorkspaceNode workspaceNode) throws CacheException
{
- if (trace) log.trace("removeNode " + workspace + " node=" + workspaceNode);
-
// it is already removed - we can ignore it
- if (workspaceNode == null)
- {
- return false;
- }
-
- boolean debug = log.isDebugEnabled();
+ if (workspaceNode == null) return false;
Fqn parentFqn = workspaceNode.getFqn().getParent();
- WorkspaceNode parentNode = getOrCreateWorkspaceNode(parentFqn, workspace, false);
- if (parentNode == null)
- {
- // chk if this has been removed in the same tx
- parentNode = workspace.getNode(parentFqn);
- if (parentNode == null || !parentNode.isDeleted())
- {
- throw new NodeNotExistsException("Unable to find parent node with Fqn " + parentFqn);
- }
- }
+ WorkspaceNode parentNode = fetchWorkspaceNode(parentFqn, workspace, true);
+ if (parentNode == null) throw new NodeNotExistsException("Unable to find parent node with fqn " + parentFqn);
+
+ // pre-notify
+ notifier.notifyNodeRemoved(workspaceNode.getFqn(), true, workspaceNode.getData(), false);
+
+ parentNode.removeChild(workspaceNode.getFqn().getLastElement());
- parentNode.removeChild(new Fqn(workspaceNode.getFqn().getLastElement()));
- workspace.addNode(parentNode);
- if (debug) log.debug("added parent node " + parentNode.getFqn() + " to workspace");
Fqn nodeFqn = workspaceNode.getFqn();
- // Mark this node and all children as deleted
- workspace.addNode(workspaceNode);// deleted below
- SortedMap tailMap = workspace.getNodesAfter(workspaceNode.getFqn());
+ SortedMap<Fqn, WorkspaceNode> tailMap = workspace.getNodesAfter(workspaceNode.getFqn());
- for (Iterator it = tailMap.entrySet().iterator(); it.hasNext();)
+ for (WorkspaceNode toDelete : tailMap.values())
{
- WorkspaceNode toDelete = (WorkspaceNode) ((Map.Entry) it.next()).getValue();
if (toDelete.getFqn().isChildOrEquals(nodeFqn))
{
- if (debug) log.debug("marking node " + toDelete.getFqn() + " as deleted");
+ if (trace) log.trace("marking node " + toDelete.getFqn() + " as deleted");
toDelete.markAsDeleted(true);
}
else
@@ -375,148 +338,189 @@
break;// no more children, we came to the end
}
}
+
+ // post-notify
+ notifier.notifyNodeRemoved(workspaceNode.getFqn(), false, null, false);
return true;
}
- private Object removeKey(Object removeKey, TransactionWorkspace workspace, WorkspaceNode workspaceNode)
- {
- if (workspaceNode == null)
+ private Object removeKeyAndNotify(Object removeKey, TransactionWorkspace workspace, WorkspaceNode workspaceNode)
{
- return null;
- }
+ if (workspaceNode == null) return null;
+
+ // pre-notify
+ notifier.notifyNodeModified(workspaceNode.getFqn(), true, CacheListener.ModificationType.REMOVE_DATA, workspaceNode.getData(), false);
Object old = workspaceNode.remove(removeKey);
workspace.addNode(workspaceNode);
+
+ Map removedData = new HashMap();
+ removedData.put(removeKey, old);
+ // post-notify
+ notifier.notifyNodeModified(workspaceNode.getFqn(), false, CacheListener.ModificationType.REMOVE_DATA, removedData, false);
+
return old;
}
- private void removeData(TransactionWorkspace workspace, WorkspaceNode workspaceNode)
- {
- if (workspaceNode == null)
+ private void removeDataAndNotify(TransactionWorkspace workspace, WorkspaceNode workspaceNode)
{
- return;
- }
+ if (workspaceNode == null) return;
+
+ Map data = new HashMap(workspaceNode.getData());
+
+ // pre-notify
+ notifier.notifyNodeModified(workspaceNode.getFqn(), true, CacheListener.ModificationType.REMOVE_DATA, data, false);
+
workspaceNode.clearData();
workspace.addNode(workspaceNode);
+
+ // post-notify
+ notifier.notifyNodeModified(workspaceNode.getFqn(), false, CacheListener.ModificationType.REMOVE_DATA, data, false);
}
- private Object getValueForKey(Object[] args, TransactionWorkspace workspace)
+ private Object getValueForKeyAndNotify(Object[] args, TransactionWorkspace workspace)
{
Fqn fqn = (Fqn) args[0];
Object key = args[1];
- WorkspaceNode workspaceNode = getOrCreateWorkspaceNode(fqn, workspace, false);
+ WorkspaceNode workspaceNode = fetchWorkspaceNode(fqn, workspace, false);
if (workspaceNode == null)
{
- if (log.isDebugEnabled()) log.debug("unable to find node " + fqn + " in workspace.");
+ if (trace) log.debug("Unable to find node " + fqn + " in workspace.");
return null;
}
else
{
//add this node into the wrokspace
- cache.getNotifier().notifyNodeVisited(fqn, true, false);
+ notifier.notifyNodeVisited(fqn, true, false);
Object val = workspaceNode.get(key);
workspace.addNode(workspaceNode);
- cache.getNotifier().notifyNodeVisited(fqn, false, false);
+ notifier.notifyNodeVisited(fqn, false, false);
return val;
}
}
- private Object getNode(Object[] args, TransactionWorkspace workspace)
+ private Object getNodeAndNotify(Object[] args, TransactionWorkspace workspace)
{
Fqn fqn = (Fqn) args[0];
- WorkspaceNode workspaceNode = getOrCreateWorkspaceNode(fqn, workspace, false);
+ WorkspaceNode workspaceNode = fetchWorkspaceNode(fqn, workspace, false);
if (workspaceNode == null)
{
- if (log.isDebugEnabled()) log.debug("unable to find node " + fqn + " in workspace.");
+ if (trace) log.trace("Unable to find node " + fqn + " in workspace.");
return null;
}
else
{
- cache.getNotifier().notifyNodeVisited(fqn, true, false);
+ notifier.notifyNodeVisited(fqn, true, false);
workspace.addNode(workspaceNode);
- cache.getNotifier().notifyNodeVisited(fqn, false, false);
+ notifier.notifyNodeVisited(fqn, false, false);
return workspaceNode.getNode();
}
}
- private Object getKeys(Object[] args, TransactionWorkspace workspace)
+ private Object getKeysAndNotify(Object[] args, TransactionWorkspace workspace)
{
Fqn fqn = (Fqn) args[0];
- WorkspaceNode workspaceNode = getOrCreateWorkspaceNode(fqn, workspace, false);
+ WorkspaceNode workspaceNode = fetchWorkspaceNode(fqn, workspace, false);
if (workspaceNode == null)
{
- if (log.isDebugEnabled()) log.debug("unable to find node " + fqn + " in workspace.");
+ if (trace) log.trace("unable to find node " + fqn + " in workspace.");
return null;
}
else
{
- cache.getNotifier().notifyNodeVisited(fqn, true, false);
+ notifier.notifyNodeVisited(fqn, true, false);
Object keySet = workspaceNode.getKeys();
workspace.addNode(workspaceNode);
- cache.getNotifier().notifyNodeVisited(fqn, false, false);
+ notifier.notifyNodeVisited(fqn, false, false);
return keySet;
}
}
- private Object getChildNames(Object[] args, TransactionWorkspace workspace)
+ private Object getChildNamesAndNotify(Object[] args, TransactionWorkspace workspace)
{
Fqn fqn = (Fqn) args[0];
- WorkspaceNode workspaceNode = getOrCreateWorkspaceNode(fqn, workspace, false);
+ WorkspaceNode workspaceNode = fetchWorkspaceNode(fqn, workspace, false);
if (workspaceNode == null)
{
- if (log.isDebugEnabled()) log.debug("unable to find node " + fqn + " in workspace.");
+ if (trace) log.trace("Unable to find node " + fqn + " in workspace.");
return null;
}
else
{
- cache.getNotifier().notifyNodeVisited(fqn, true, false);
+ notifier.notifyNodeVisited(fqn, true, false);
Object nameSet = workspaceNode.getChildrenNames();
workspace.addNode(workspaceNode);
- cache.getNotifier().notifyNodeVisited(fqn, false, false);
+ notifier.notifyNodeVisited(fqn, false, false);
return nameSet;
}
}
- private WorkspaceNode getOrCreateWorkspaceNode(Fqn fqn, TransactionWorkspace workspace, boolean undeleteIfNecessary)
+ // -----------------------------------------------------------------
+
+ // Methods to help retrieval of nodes from the transaction workspace.
+
+ // -----------------------------------------------------------------
+
+ /**
+ * Retrieves a node for a given Fqn from the workspace. If the node does not exist in the workspace it is retrieved
+ * from the cache's data structure. Note that at no point is a NEW node created in the underlying data structure.
+ * That is up to the {@link org.jboss.cache.interceptors.OptimisticCreateIfNotExistsInterceptor}.
+ * <p/>
+ * If the node requested is in the workspace but marked as deleted, this method will NOT retrieve it, unless undeleteIfNecessary
+ * is true, in which case the node's <tt>deleted</tt> property is set to false first before being retrieved.
+ *
+ * @param fqn Fqn of the node to retrieve
+ * @param workspace transaction workspace to look in
+ * @param undeleteIfNecessary if the node is in the workspace but marked as deleted, this meth
+ * @return a node, if found, or null if not.
+ */
+ private WorkspaceNode fetchWorkspaceNode(Fqn fqn, TransactionWorkspace workspace, boolean undeleteIfNecessary)
{
WorkspaceNode workspaceNode = workspace.getNode(fqn);
// if we do not have the node then we need to add it to the workspace
if (workspaceNode == null)
{
NodeSPI node = cache.peek(fqn, true);
- if (node == null)
- {
- return null;// seems to happen quite a bit
- }
+ if (node == null) return null;
+
+ // create new workspace node based on the node from the underlying data structure
workspaceNode = nodeFactory.createWorkspaceNode(node, workspace);
+
+ // and add the node to the workspace.
workspace.addNode(workspaceNode);
}
- // the node has been deleted dude!
+
+ // Check that the workspace node has been marked as deleted.
if (workspaceNode.isDeleted())
{
- if (log.isDebugEnabled()) log.debug("Node " + fqn + " has been deleted in the workspace.");
+ if (trace) log.trace("Node " + fqn + " has been deleted in the workspace.");
if (undeleteIfNecessary)
{
workspaceNode.markAsDeleted(false);
// re-add to parent
- WorkspaceNode parent = getOrCreateWorkspaceNode(fqn.getParent(), workspace, true);
+ WorkspaceNode parent = fetchWorkspaceNode(fqn.getParent(), workspace, true);
parent.addChild(workspaceNode);
}
else
{
+ // don't return deleted nodes if undeleteIfNecessary is false!
workspaceNode = null;
}
}
+ // set implicit node versioning flag.
if (workspaceNode != null && !(workspaceNode.getVersion() instanceof DefaultDataVersion))
+ {
workspaceNode.setVersioningImplicit(false);
+ }
+
return workspaceNode;
}
}
More information about the jboss-cvs-commits
mailing list