@SuppressWarnings("unchecked")
private void commitTransaction(InvocationContext ctx)
{
GlobalTransaction gtx = getGlobalTransaction(ctx);
TransactionWorkspace workspace;
workspace = getTransactionWorkspace(ctx);
if (log.isDebugEnabled()) log.debug("Commiting successfully validated changes for GlobalTransaction " + gtx);
Collection<WorkspaceNode> workspaceNodes = workspace.getNodes().values();
for (WorkspaceNode workspaceNode : workspaceNodes)
{
NodeSPI underlyingNode = workspaceNode.getNode();
// short circuit if this node is deleted?
if (workspaceNode.isRemoved())
{
if (trace) log.trace("Workspace node " + workspaceNode.getFqn() + " deleted; removing");
if (underlyingNode.getFqn().isRoot())
{
throw new CacheException("An illegal attempt to delete the root node!");
}
else
{
// mark it as invalid so any direct references are marked as such
underlyingNode.setValid(false, true);
// we need to update versions here, too
performVersionUpdate(underlyingNode, workspaceNode);
if (!useTombstones)
{
// don't retain the tombstone
NodeSPI parent = underlyingNode.getParentDirect();
if (parent == null)
{
throw new CacheException("Underlying node " + underlyingNode + " has no parent");
}
parent.removeChildDirect(underlyingNode.getFqn().getLastElement());
}
}
}
else
{
boolean updateVersion = false;
if (workspaceNode.isChildrenModified() || workspaceNode.isResurrected()) // if it is newly created make sure we remove all underlying children that may exist, to solve a remove-and-create-in-tx condition
{
if (trace) log.trace("Updating children since node has modified children");
// merge children.
List<Set<Fqn>> deltas = workspaceNode.getMergedChildren();
if (trace) log.trace("Applying children deltas to parent node " + underlyingNode.getFqn());
if (workspaceNode.isResurrected())
{
// mark it as invalid so any direct references are marked as such
Map childNode = underlyingNode.getChildrenMapDirect();
for (Object o : childNode.values())
{
NodeSPI cn = (NodeSPI) o;
cn.setValid(false, true);
if (!useTombstones) underlyingNode.removeChildDirect(cn.getFqn().getLastElement());
}
}
for (Fqn child : deltas.get(0))
{
NodeSPI childNode = workspace.getNode(child).getNode();
underlyingNode.addChildDirect(childNode);
childNode.setValid(true, false);
}
for (Fqn child : deltas.get(1))