transfer service : ALF-4128 alien nodes.

- unit test of multiple invasion
   - unit test move alien node via transfer.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@21685 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Mark Rogers 2010-08-09 15:04:22 +00:00
parent f79c9fc0e3
commit b51e8ef744
8 changed files with 935 additions and 801 deletions

View File

@ -208,14 +208,8 @@
<aspect name="trx:alien">
<title>Alien Node</title>
<description>Nodes with this aspect are either alien nodes or have been invaded by alien content</description>
<description>Nodes with this aspect are either alien nodes or have been invaded by other alien nodes</description>
<properties>
<property name="trx:alien">
<title>Alien Content</title>
<type>d:boolean</type>
<mandatory enforced="false">false</mandatory>
<default>false</default>
</property>
<property name="trx:invadedBy">
<title>The repositories that have invaded this node</title>
<type>d:text</type>

View File

@ -148,7 +148,7 @@ public class AlienProcessorImpl implements AlienProcessor
public void beforeDeleteAlien(NodeRef deletedNodeRef)
{
log.debug("on delete node - need to check for transferred node");
log.debug("before delete node - need to check for alien invaders");
List<String>stuff = (List<String>)nodeService.getProperty(deletedNodeRef, TransferModel.PROP_INVADED_BY);
@ -272,12 +272,18 @@ public class AlienProcessorImpl implements AlienProcessor
return nodeService.hasAspect(nodeRef, TransferModel.ASPECT_ALIEN);
}
public void pruneNode(NodeRef parentNodeRef, String fromRepositoryId)
public void pruneNode(NodeRef nodeToPrune, String fromRepositoryId)
{
Stack<NodeRef> nodesToPrune = new Stack<NodeRef>();
Stack<NodeRef> foldersToRecalculate = new Stack<NodeRef>();
nodesToPrune.add(parentNodeRef);
nodesToPrune.add(nodeToPrune);
ChildAssociationRef startingParent = nodeService.getPrimaryParent(nodeToPrune);
Stack<NodeRef> foldersToRecalculate = new Stack<NodeRef>();
/**
* Now go and do the pruning.
*/
while(!nodesToPrune.isEmpty())
{
/**
@ -297,6 +303,7 @@ public class AlienProcessorImpl implements AlienProcessor
List<String>invadedBy = (List<String>)getNodeService().getProperty(currentNodeRef, TransferModel.PROP_INVADED_BY);
if(invadedBy.contains(fromRepositoryId))
{
// Yes we are invaded by fromRepositoryId
if(invadedBy.size() == 1)
{
// we are invaded by a single repository which must be fromRepositoryId
@ -307,23 +314,24 @@ public class AlienProcessorImpl implements AlienProcessor
{
log.debug("folder has multiple invaders");
// multiple invasion - so it must be a folder
//TODO replace with a more efficient query
List<ChildAssociationRef> refs = getNodeService().getChildAssocs(parentNodeRef);
List<ChildAssociationRef> refs = getNodeService().getChildAssocs(currentNodeRef);
for(ChildAssociationRef ref : refs)
{
if(log.isDebugEnabled())
{
log.debug("will need to check child:" + ref);
}
nodesToPrune.push(ref.getChildRef());
/**
* This folder can't be deleted so its invaded flag needs to be re-calculated
*/
if(!foldersToRecalculate.contains(ref.getParentRef()))
{
foldersToRecalculate.push(ref.getParentRef());
}
nodesToPrune.push(ref.getChildRef());
}
/**
* Yes we might do something to the children of this node.
*/
if(!foldersToRecalculate.contains(currentNodeRef))
{
foldersToRecalculate.push(currentNodeRef);
}
}
}
@ -353,9 +361,9 @@ public class AlienProcessorImpl implements AlienProcessor
/**
* This folder can't be deleted so its invaded flag needs to be re-calculated
*/
if(!foldersToRecalculate.contains(ref.getParentRef()))
if(!foldersToRecalculate.contains(currentNodeRef))
{
foldersToRecalculate.push(ref.getParentRef());
foldersToRecalculate.push(currentNodeRef);
}
}
}
@ -379,44 +387,52 @@ public class AlienProcessorImpl implements AlienProcessor
}
/**
* Now ripple the "invadedBy" flag upwards.
* Now recalculate the "invadedBy" flag for those folders we could not delete.
*/
while(!foldersToRecalculate.isEmpty())
{
NodeRef folderNodeRef = foldersToRecalculate.pop();
log.debug("recalculate invadedBy :" + folderNodeRef);
List<String>folderInvadedBy = (List<String>)getNodeService().getProperty(folderNodeRef, TransferModel.PROP_INVADED_BY);
boolean stillInvaded = false;
//TODO need a more efficient query here
List<ChildAssociationRef> refs = getNodeService().getChildAssocs(folderNodeRef);
for(ChildAssociationRef ref : refs)
recalcInvasion(folderNodeRef, fromRepositoryId);
}
/**
* Now ripple up the invaded flag - may be a alien retreat.
*/
log.debug("now ripple upwards");
ChildAssociationRef ripple = startingParent;
while(ripple != null)
{
if(log.isDebugEnabled())
{
NodeRef childNode = ref.getChildRef();
List<String>childInvadedBy = (List<String>)getNodeService().getProperty(childNode, TransferModel.PROP_INVADED_BY);
if(childInvadedBy.contains(fromRepositoryId))
log.debug("Checking parent:" + ripple);
}
if(nodeService.hasAspect(ripple.getParentRef(), TransferModel.ASPECT_ALIEN))
{
if(recalcInvasion(ripple.getParentRef(), fromRepositoryId))
{
log.debug("folder is still invaded");
stillInvaded = true;
break;
log.debug("parent is still invaded");
ripple = null;
}
else
{
log.debug("parent is no longer invaded");
ripple = nodeService.getPrimaryParent(ripple.getParentRef());
}
}
if(!stillInvaded)
else
{
List<String> newInvadedBy = new ArrayList<String>(folderInvadedBy);
folderInvadedBy.remove(fromRepositoryId);
getNodeService().setProperty(folderNodeRef, TransferModel.PROP_INVADED_BY, (Serializable)newInvadedBy);
}
ripple = null;
}
}
log.debug("pruneNode: end");
}
/**
* Is this node invaded ?
* @param nodeRef
@ -436,9 +452,9 @@ public class AlienProcessorImpl implements AlienProcessor
}
/**
* Mark the specified node as an alien node, invadedby the invader.
* @param newAlien
* @param invader
* Mark the specified node as an alien node, invaded by the specified invader.
* @param newAlien node that has been invaded.
* @param invader the repository id of the invading repo.
*/
private void setAlien(NodeRef newAlien, String invader)
{
@ -448,23 +464,70 @@ public class AlienProcessorImpl implements AlienProcessor
if(invadedBy == null)
{
nodeService.setProperty(newAlien, TransferModel.PROP_ALIEN, Boolean.TRUE);
invadedBy = new ArrayList<String>(1);
}
invadedBy.add(invader);
if(!invadedBy.contains(invader))
{
invadedBy.add(invader);
}
/**
* Set the invaded by property
*/
nodeService.setProperty(newAlien, TransferModel.PROP_INVADED_BY, (Serializable) invadedBy);
// /**
// * Experiment with a residual property
// */
// nodeService.setProperty(newAlien, QName.createQName(TransferModel.TRANSFER_MODEL_1_0_URI,
// "invader" + invader), Boolean.TRUE);
nodeService.setProperty(newAlien, TransferModel.PROP_INVADED_BY, (Serializable) invadedBy);
}
/**
* Recalculate the whether this node is invaded by the specified repository
* @param folderNodeRef the node to re-calculate
* @param fromRepositoryId the repository who is transferring.
*
* @return true - still invaded, false, no longer invaded
*/
private boolean recalcInvasion(NodeRef folderNodeRef, String fromRepositoryId)
{
List<String>folderInvadedBy = (List<String>)nodeService.getProperty(folderNodeRef, TransferModel.PROP_INVADED_BY);
boolean stillInvaded = false;
//TODO need a more efficient query here
List<ChildAssociationRef> refs = nodeService.getChildAssocs(folderNodeRef);
for(ChildAssociationRef ref : refs)
{
NodeRef childNode = ref.getChildRef();
List<String>childInvadedBy = (List<String>)getNodeService().getProperty(childNode, TransferModel.PROP_INVADED_BY);
if(childInvadedBy != null && childInvadedBy.contains(fromRepositoryId))
{
log.debug("folder is still invaded");
stillInvaded = true;
break;
}
}
if(!stillInvaded)
{
log.debug("folder is no longer invaded by this repo:" + folderNodeRef);
folderInvadedBy.remove(fromRepositoryId);
if(folderInvadedBy.size() > 0)
{
if(log.isDebugEnabled())
{
log.debug("still invaded by:" + folderInvadedBy);
}
getNodeService().setProperty(folderNodeRef, TransferModel.PROP_INVADED_BY, (Serializable)folderInvadedBy);
}
else
{
log.debug("no longer alien:" + folderNodeRef);
getNodeService().removeAspect(folderNodeRef, TransferModel.ASPECT_ALIEN);
}
}
return stillInvaded;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;

View File

@ -69,6 +69,7 @@ public class DefaultManifestProcessorFactoryImpl implements ManifestProcessorFac
RepoTertiaryManifestProcessorImpl tertiaryProcessor = new RepoTertiaryManifestProcessorImpl(receiver, transferId);
tertiaryProcessor.setNodeService(nodeService);
tertiaryProcessor.setAlienProcessor(getAlienProcessor());
tertiaryProcessor.setNodeResolver(nodeResolver);
processors.add(tertiaryProcessor);
return processors;

View File

@ -136,63 +136,35 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
// If we can find a corresponding node then we'll delete it.
// If we can't find a corresponding node then we'll do nothing.
logProgress("Processing incoming deleted node: " + node.getNodeRef());
if (!nodeService.exists(node.getNodeRef()))
ChildAssociationRef origPrimaryParent = node.getPrimaryParentAssoc();
NodeRef origNodeRef = new NodeRef(origPrimaryParent.getParentRef().getStoreRef(), node.getNodeRef().getId());
CorrespondingNodeResolver.ResolvedParentChildPair resolvedNodes = nodeResolver.resolveCorrespondingNode(
origNodeRef, origPrimaryParent, node.getParentPath());
// Does a corresponding node exist in this repo?
if (resolvedNodes.resolvedChild != null)
{
// It's not in our archive store. Check to see if we can find it in
// its original store...
ChildAssociationRef origPrimaryParent = node.getPrimaryParentAssoc();
NodeRef origNodeRef = new NodeRef(origPrimaryParent.getParentRef().getStoreRef(), node.getNodeRef().getId());
CorrespondingNodeResolver.ResolvedParentChildPair resolvedNodes = nodeResolver.resolveCorrespondingNode(
origNodeRef, origPrimaryParent, node.getParentPath());
// Does a corresponding node exist in this repo?
if (resolvedNodes.resolvedChild != null)
NodeRef exNode = resolvedNodes.resolvedChild;
// Yes, it does. Delete it.
if (log.isDebugEnabled())
{
NodeRef exNode = resolvedNodes.resolvedChild;
// Yes, it does. Delete it.
if (log.isDebugEnabled())
{
log.debug("Incoming deleted noderef " + node.getNodeRef()
+ " has been resolved to existing local noderef " + exNode
+ " - deleting");
}
//TODO : do we have a business rule that only the "from" repo can delete a node? Yes we do.
if(alienProcessor.isAlien(exNode))
{
logProgress("Pruning local node: " + exNode);
if (log.isDebugEnabled())
{
log.debug("Node to be deleted is alien prune rather than delete: " + exNode);
}
alienProcessor.pruneNode(exNode, header.getRepositoryId());
}
else
{
// TODO Need to restrict to the "from" repo Id.
// Not alien - delete it.
logProgress("Deleting local node: " + exNode);
nodeService.deleteNode(exNode);
if (log.isDebugEnabled())
{
log.debug("Deleted local node: " + exNode);
}
}
}
else
{
logProgress("Unable to find corresponding node for incoming deleted node: " + node.getNodeRef());
if (log.isDebugEnabled())
{
log.debug("Incoming deleted noderef has no corresponding local noderef: " + node.getNodeRef()
+ " - ignoring");
}
log.debug("Incoming deleted noderef " + node.getNodeRef()
+ " has been resolved to existing local noderef " + exNode
+ " - deleting");
}
delete(exNode);
}
else
{
logProgress("Incoming deleted node is already in the local archive store - ignoring: " + node.getNodeRef());
logProgress("Unable to find corresponding node for incoming deleted node: " + node.getNodeRef());
if (log.isDebugEnabled())
{
log.debug("Incoming deleted noderef has no corresponding local noderef: " + node.getNodeRef()
+ " - ignoring");
}
}
}
@ -372,6 +344,51 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
// Is the node that we've just added the parent of any orphans that
// we've found earlier?
checkOrphans(newNode.getChildRef());
}
/**
* Delete this node
* @param exNode
*/
protected void delete(NodeRef nodeToDelete)
{
if(alienProcessor.isAlien(nodeToDelete))
{
logProgress("Pruning local node: " + nodeToDelete);
if (log.isDebugEnabled())
{
log.debug("Node to be deleted is alien prune rather than delete: " + nodeToDelete);
}
alienProcessor.pruneNode(nodeToDelete, header.getRepositoryId());
}
else
{
/**
* Check that if the destination is "from" the transferring repo if it is "from" another repo then ignore
*/
if(nodeService.hasAspect(nodeToDelete, TransferModel.ASPECT_TRANSFERRED))
{
String fromRepository = (String)nodeService.getProperty(nodeToDelete, TransferModel.PROP_FROM_REPOSITORY_ID);
String transferringRepo = header.getRepositoryId();
if(fromRepository != null && transferringRepo != null)
{
if(!fromRepository.equalsIgnoreCase(transferringRepo))
{
logProgress("Not deleting local node (not from the transferring repository): " + nodeToDelete);
return;
}
}
}
// Not alien or from another repo - delete it.
logProgress("Deleting local node: " + nodeToDelete);
nodeService.deleteNode(nodeToDelete);
if (log.isDebugEnabled())
{
log.debug("Deleted local node: " + nodeToDelete);
}
}
}
private void checkOrphans(NodeRef parentNode)
@ -410,7 +427,26 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
ChildAssociationRef primaryParentAssoc)
{
NodeRef nodeToUpdate = resolvedNodes.resolvedChild;
/**
* Check that if the destination is "from" the transferring repo if it is "from" another repo then ignore
*/
if(nodeService.hasAspect(nodeToUpdate, TransferModel.ASPECT_TRANSFERRED))
{
String fromRepository = (String)nodeService.getProperty(nodeToUpdate, TransferModel.PROP_FROM_REPOSITORY_ID);
String transferringRepo = header.getRepositoryId();
if(fromRepository != null && transferringRepo != null)
{
if(!fromRepository.equalsIgnoreCase(transferringRepo))
{
logProgress("Not updating local node (not from the transferring repository): " + node.getNodeRef());
return;
}
}
}
logProgress("Updating local node: " + node.getNodeRef());
QName parentAssocType = primaryParentAssoc.getTypeQName();
QName parentAssocName = primaryParentAssoc.getQName();
@ -425,7 +461,8 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
parentAssocType = tempLocation.getTypeQName();
parentAssocName = tempLocation.getQName();
storeOrphanNode(primaryParentAssoc);
}
}
// First of all, do we need to move the node? If any aspect of the
// primary parent association has changed
// then the answer is "yes"
@ -438,9 +475,9 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
/**
* Yes, the parent assoc has changed so we need to move the node
*/
// the parent node may no longer be an alien
if(nodeService.hasAspect(parentNodeRef, TransferModel.ASPECT_ALIEN))
if(nodeService.hasAspect(currentParent.getParentRef(), TransferModel.ASPECT_ALIEN))
{
// old parent node ref may be alien
alienProcessor.beforeDeleteAlien(node.getNodeRef());
}

View File

@ -19,23 +19,16 @@
package org.alfresco.repo.transfer;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import org.alfresco.repo.transfer.manifest.TransferManifestDeletedNode;
import org.alfresco.repo.transfer.manifest.TransferManifestHeader;
import org.alfresco.repo.transfer.manifest.TransferManifestNodeHelper;
import org.alfresco.repo.transfer.manifest.TransferManifestNormalNode;
import org.alfresco.service.cmr.repository.AssociationRef;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.transfer.TransferReceiver;
import org.alfresco.service.namespace.RegexQNamePattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@ -53,6 +46,7 @@ public class RepoTertiaryManifestProcessorImpl extends AbstractManifestProcessor
{
private NodeService nodeService;
private AlienProcessor alienProcessor;
CorrespondingNodeResolver nodeResolver;
private static final Log log = LogFactory.getLog(RepoTertiaryManifestProcessorImpl.class);
@ -83,38 +77,48 @@ public class RepoTertiaryManifestProcessorImpl extends AbstractManifestProcessor
protected void processNode(TransferManifestNormalNode node)
{
NodeRef nodeRef = node.getNodeRef();
log.debug("processNode : " + nodeRef);
if(isSync)
if (log.isDebugEnabled())
{
List<ChildAssociationRef> expectedChildren = node.getChildAssocs();
List<NodeRef> expectedChildNodeRefs = new ArrayList<NodeRef>();
for(ChildAssociationRef ref : expectedChildren)
{
if(log.isDebugEnabled())
{
log.debug("expecting child" + ref);
}
expectedChildNodeRefs.add(ref.getChildRef());
}
log.debug("Processing node with incoming noderef of " + node.getNodeRef());
}
logProgress("Processing incoming node: " + node.getNodeRef() + " -- Source path = " + node.getParentPath() + "/" + node.getPrimaryParentAssoc().getQName());
// TODO Do we need to worry about path based nodes ? Assuming no at the moment.
/**
* This processor only does processes sync requests.
*/
if(isSync)
{
ChildAssociationRef primaryParentAssoc = node.getPrimaryParentAssoc();
CorrespondingNodeResolver.ResolvedParentChildPair resolvedNodes = nodeResolver.resolveCorrespondingNode(node
.getNodeRef(), primaryParentAssoc, node.getParentPath());
NodeRef nodeRef = resolvedNodes.resolvedChild;
if(nodeService.exists(nodeRef))
{
log.debug("destination node exists");
log.debug("destination node exists - check the children");
//TODO Use more efficient query here.
List<ChildAssociationRef> expectedChildren = node.getChildAssocs();
List<NodeRef> expectedChildNodeRefs = new ArrayList<NodeRef>();
for(ChildAssociationRef ref : expectedChildren)
{
if(log.isDebugEnabled())
{
log.debug("expecting child node" + ref);
}
expectedChildNodeRefs.add(ref.getChildRef());
}
/**
* yes this node exists in the destination.
*/
List<ChildAssociationRef> actualChildren = nodeService.getChildAssocs(nodeRef);
/**
* For each destination child association
* For each actual child association
*/
for(ChildAssociationRef child : actualChildren)
{
@ -131,46 +135,56 @@ public class RepoTertiaryManifestProcessorImpl extends AbstractManifestProcessor
{
/**
* An unexpected child - if this node has been transferred then
* it needs to be deleted.
* it may need to be deleted.
*
* another repository then we have to prune the alien children
* If from another repository then we have to prune the alien children
* rather than deleting it.
*/
log.debug("an unexpected child node:" + child);
if(nodeService.hasAspect(childNodeRef, TransferModel.ASPECT_TRANSFERRED))
{
log.debug("an unexpected transferred child node:" + child);
String fromRepositoryId = (String)nodeService.getProperty(childNodeRef, TransferModel.PROP_FROM_REPOSITORY_ID);
// Yes this is a transferred node. When syncing we only delete nodes that are "from"
// the system that is transferring to this repo.
if(fromRepositoryId != null && manifestRepositoryId != null)
{
if(manifestRepositoryId.equalsIgnoreCase(fromRepositoryId))
if(nodeService.hasAspect(childNodeRef, TransferModel.ASPECT_ALIEN))
{
// Yes the manifest repository Id and the from repository Id match.
if(nodeService.hasAspect(childNodeRef, TransferModel.ASPECT_ALIEN))
/**
* This node can't be deleted since it contains alien content
* it needs to be "pruned" of the transferring repo's content instead.
*/
log.debug("node to be deleted contains alien content so needs to be pruned." + childNodeRef);
alienProcessor.pruneNode(childNodeRef, fromRepositoryId);
}
else
{
// Node
log.debug("node not alien");
if(manifestRepositoryId.equalsIgnoreCase(fromRepositoryId))
{
/**
* This node can't be deleted since it contains alien content
* it needs to be "pruned" of the transferring repo's content instead.
*/
log.debug("node to be deleted contains alien content so needs to be pruned." + childNodeRef);
alienProcessor.pruneNode(childNodeRef, fromRepositoryId);
//pruneNode(childNodeRef, fromRepositoryId);
}
else
{
// Destination node needs to be deleted.
// Yes the manifest repository Id and the from repository Id match.
// Destination node if from the transferring repo and needs to be deleted.
nodeService.deleteNode(childNodeRef);
log.debug("deleted node:" + childNodeRef);
}
}
}
}
else
{
log.debug("node does not have a transferred aspect");
}
}
}
}
}
}
else
{
log.debug("not sync mode - do nothing");
}
}
}
@ -202,161 +216,6 @@ public class RepoTertiaryManifestProcessorImpl extends AbstractManifestProcessor
this.nodeService = nodeService;
}
// /**
// * Prune out the non aliens from the specified repository
// *
// * Need to walk the tree downwards pruning any aliens for this repository
// *
// * Also any folders remaining need to have their invaded by field rippled upwards since they may no
// * longer be invaded by the specified repository if all the alien children have been pruned.
// *
// * @param nodeRef the node to prune
// * @param fromRepositoryId the repository id of the nodes to prune.
// */
// private void pruneNode(NodeRef parentNodeRef, String fromRepositoryId)
// {
// Stack<NodeRef> nodesToPrune = new Stack<NodeRef>();
// Stack<NodeRef> foldersToRecalculate = new Stack<NodeRef>();
// nodesToPrune.add(parentNodeRef);
//
// while(!nodesToPrune.isEmpty())
// {
// /**
// * for all alien children
// *
// * if from the repo with no (other) aliens - delete
// *
// * if from the repo with multiple alien invasions - leave alone but process children
// */
// NodeRef currentNodeRef = nodesToPrune.pop();
//
// log.debug("pruneNode:" + currentNodeRef);
//
// if(nodeService.hasAspect(currentNodeRef, TransferModel.ASPECT_ALIEN))
// {
// // Yes this is an alien node
// List<String>invadedBy = (List<String>)nodeService.getProperty(currentNodeRef, TransferModel.PROP_INVADED_BY);
// if(invadedBy.contains(fromRepositoryId))
// {
// if(invadedBy.size() == 1)
// {
// // we are invaded by a single repository which must be fromRepositoryId
// log.debug("pruned - deleted node:" + currentNodeRef);
// nodeService.deleteNode(currentNodeRef);
// }
// else
// {
// log.debug("folder has multiple invaders");
// // multiple invasion - so it must be a folder
// //TODO replace with a more efficient query
// List<ChildAssociationRef> refs = nodeService.getChildAssocs(parentNodeRef);
// for(ChildAssociationRef ref : refs)
// {
// if(log.isDebugEnabled())
// {
// log.debug("will need to check child:" + ref);
// }
// nodesToPrune.push(ref.getChildRef());
//
// /**
// * This folder can't be deleted so its invaded flag needs to be re-calculated
// */
// if(!foldersToRecalculate.contains(ref.getParentRef()))
// {
// foldersToRecalculate.push(ref.getParentRef());
// }
// }
// }
// }
// else
// {
// /**
// * Current node has been invaded by another repository
// *
// * Need to check fromRepositoryId since its children may need to be pruned
// */
// nodeService.hasAspect(currentNodeRef, TransferModel.ASPECT_TRANSFERRED);
// {
// String fromRepoId = (String)nodeService.getProperty(currentNodeRef, TransferModel.PROP_FROM_REPOSITORY_ID);
// if(fromRepositoryId.equalsIgnoreCase(fromRepoId))
// {
// log.debug("folder is from the transferring repository");
// // invaded from somewhere else - so it must be a folder
// List<ChildAssociationRef> refs = nodeService.getChildAssocs(currentNodeRef);
// for(ChildAssociationRef ref : refs)
// {
// if(log.isDebugEnabled())
// {
// log.debug("will need to check child:" + ref);
// }
// nodesToPrune.push(ref.getChildRef());
//
// /**
// * This folder can't be deleted so its invaded flag needs to be re-calculated
// */
// if(!foldersToRecalculate.contains(ref.getParentRef()))
// {
// foldersToRecalculate.push(ref.getParentRef());
// }
// }
// }
// }
// }
// }
// else
// {
// // Current node does not contain alien nodes so it can be deleted.
// nodeService.hasAspect(currentNodeRef, TransferModel.ASPECT_TRANSFERRED);
// {
// String fromRepoId = (String)nodeService.getProperty(currentNodeRef, TransferModel.PROP_FROM_REPOSITORY_ID);
// if(fromRepositoryId.equalsIgnoreCase(fromRepoId))
// {
// // we are invaded by a single repository
// log.debug("pruned - deleted non alien node:" + currentNodeRef);
// nodeService.deleteNode(currentNodeRef);
// }
// }
// }
// }
//
// /**
// * Now ripple the "invadedBy" flag upwards.
// */
//
// while(!foldersToRecalculate.isEmpty())
// {
// NodeRef folderNodeRef = foldersToRecalculate.pop();
//
// log.debug("recalculate invadedBy :" + folderNodeRef);
//
// List<String>folderInvadedBy = (List<String>)nodeService.getProperty(folderNodeRef, TransferModel.PROP_INVADED_BY);
//
// boolean stillInvaded = false;
// //TODO need a more efficient query here
// List<ChildAssociationRef> refs = nodeService.getChildAssocs(folderNodeRef);
// for(ChildAssociationRef ref : refs)
// {
// NodeRef childNode = ref.getChildRef();
// List<String>childInvadedBy = (List<String>)nodeService.getProperty(childNode, TransferModel.PROP_INVADED_BY);
//
// if(childInvadedBy.contains(fromRepositoryId))
// {
// log.debug("folder is still invaded");
// stillInvaded = true;
// break;
// }
// }
//
// if(!stillInvaded)
// {
// List<String> newInvadedBy = new ArrayList<String>(folderInvadedBy);
// folderInvadedBy.remove(fromRepositoryId);
// nodeService.setProperty(folderNodeRef, TransferModel.PROP_INVADED_BY, (Serializable)newInvadedBy);
// }
// }
// log.debug("pruneNode: end");
// }
public void setAlienProcessor(AlienProcessor alienProcessor)
{
this.alienProcessor = alienProcessor;
@ -366,4 +225,13 @@ public class RepoTertiaryManifestProcessorImpl extends AbstractManifestProcessor
{
return alienProcessor;
}
/**
* @param nodeResolver
* the nodeResolver to set
*/
public void setNodeResolver(CorrespondingNodeResolver nodeResolver)
{
this.nodeResolver = nodeResolver;
}
}

View File

@ -968,75 +968,7 @@ public class RepoTransferReceiverImpl implements TransferReceiver,
log.debug("on create child association to transferred node");
final String localRepositoryId = descriptorService.getCurrentRepositoryDescriptor().getId();
alienProcessor.onCreateChild(childAssocRef, localRepositoryId);
//
// ChildAssociationRef currentAssoc = childAssocRef;
//
// final String localRepositoryId = descriptorService.getCurrentRepositoryDescriptor().getId();
//
// // TODO Needs to check assoc is a cm:contains or subtype
// if(childAssocRef.isPrimary())
// {
// NodeRef parentNodeRef = currentAssoc.getParentRef();
// NodeRef childNodeRef = currentAssoc.getChildRef();
//
// /**
// * Make the new child node ref an alien node
// */
// setAlien(childNodeRef, localRepositoryId);
//
// /**
// * Now deal with the parents of this alien node
// */
// while(currentAssoc != null)
// {
// parentNodeRef = currentAssoc.getParentRef();
// childNodeRef = currentAssoc.getChildRef();
//
// if(nodeService.hasAspect(parentNodeRef, TransferModel.ASPECT_TRANSFERRED) || nodeService.hasAspect(parentNodeRef, TransferModel.ASPECT_ALIEN))
// {
// if (!isInvaded(parentNodeRef, localRepositoryId))
// {
// if(log.isDebugEnabled())
// {
// log.debug("alien invades parent node:" + parentNodeRef + ", repositoryId:" + localRepositoryId);
// }
//
// final NodeRef newAlien = parentNodeRef;
//
// /**
// * Parent may be locked or not be editable by the current user
// * turn off auditing and lock service for this transaction and
// * run as admin.
// */
// RunAsWork<Void> actionRunAs = new RunAsWork<Void>()
// {
// public Void doWork() throws Exception
// {
// behaviourFilter.disableBehaviour(newAlien, ContentModel.ASPECT_AUDITABLE);
// behaviourFilter.disableBehaviour(newAlien, ContentModel.ASPECT_LOCKABLE);
// setAlien(newAlien, localRepositoryId);
// return null;
// }
// };
// AuthenticationUtil.runAs(actionRunAs, AuthenticationUtil.getSystemUserName());
//
// // Yes the parent has been invaded so step up to the parent's parent
// currentAssoc = nodeService.getPrimaryParent(parentNodeRef);
// }
// else
// {
// log.debug("parent node is already invaded");
// currentAssoc = null;
// }
// }
// else
// {
// log.debug("parent is not a transferred node");
// currentAssoc = null;
// }
// }
// }
alienProcessor.onCreateChild(childAssocRef, localRepositoryId);
}
/**
@ -1048,175 +980,8 @@ public class RepoTransferReceiverImpl implements TransferReceiver,
{
log.debug("on delete node - need to check for transferred node");
alienProcessor.beforeDeleteAlien(deletedNodeRef);
//
// List<String>stuff = (List<String>)nodeService.getProperty(deletedNodeRef, TransferModel.PROP_INVADED_BY);
//
// Vector<String> exInvaders = new Vector<String>(stuff);
//
// ChildAssociationRef currentAssoc = nodeService.getPrimaryParent(deletedNodeRef);
//
// while(currentAssoc != null && exInvaders != null && exInvaders.size() > 0)
// {
// NodeRef parentNodeRef = currentAssoc.getParentRef();
// NodeRef currentNodeRef = currentAssoc.getChildRef();
//
// /**
// * Does the parent have alien invaders ?
// */
// if(nodeService.hasAspect(parentNodeRef, TransferModel.ASPECT_ALIEN))
// {
// log.debug("parent node is alien - check siblings");
//
// /**
// * For each invader of the deletedNode
// */
// Iterator<String> i = exInvaders.listIterator();
// while(i.hasNext())
// {
// String exInvader = i.next();
// log.debug("Checking exInvader:" + exInvader);
//
// /**
// * Check the siblings of this node to see whether there are any other alien nodes for this invader.
// */
// //TODO replace with a more efficient query
// List<ChildAssociationRef> refs = nodeService.getChildAssocs(parentNodeRef);
//
// for(ChildAssociationRef ref : refs)
// {
// NodeRef childRef = ref.getChildRef();
// List<String>invadedBy = (List<String>)nodeService.getProperty(childRef, TransferModel.PROP_INVADED_BY);
//
// if(childRef.equals(currentNodeRef))
// {
// // do nothing - this is the node we are working with.
// }
// else
// {
// if(invadedBy != null && invadedBy.contains(exInvader))
// {
// // There is a sibling so remove this from the list of ex invaders.
// log.debug("yes there is a sibling so it remains an invader");
// i.remove();
// break;
// }
// }
// } // for each child assoc
//
// } // for each invader
//
// log.debug("end of checking siblings");
//
// if(exInvaders.size() > 0)
// {
// log.debug("removing invaders from parent node:" + parentNodeRef);
// List<String> parentInvaders = (List<String>)nodeService.getProperty(parentNodeRef, TransferModel.PROP_INVADED_BY);
//
// final List<String> newInvaders = new ArrayList<String>(10);
// for(String invader : parentInvaders)
// {
// if(exInvaders.contains(invader))
// {
// log.debug("removing invader:" + invader);
// }
// else
// {
// newInvaders.add(invader);
// }
// }
//
// final NodeRef oldAlien = parentNodeRef;
//
// /**
// * Parent may be locked or not be editable by the current user
// * turn off auditing and lock service for this transaction and
// * run as admin.
// */
// RunAsWork<Void> actionRunAs = new RunAsWork<Void>()
// {
// public Void doWork() throws Exception
// {
// behaviourFilter.disableBehaviour(oldAlien, ContentModel.ASPECT_AUDITABLE);
// behaviourFilter.disableBehaviour(oldAlien, ContentModel.ASPECT_LOCKABLE);
// if(newInvaders.size() > 0)
// {
// nodeService.setProperty(oldAlien, TransferModel.PROP_INVADED_BY, (Serializable)newInvaders);
// }
// else
// {
// log.debug("parent node no is no longer alien");
// nodeService.removeAspect(oldAlien, TransferModel.ASPECT_ALIEN);
// }
// return null;
// }
// };
// AuthenticationUtil.runAs(actionRunAs, AuthenticationUtil.getSystemUserName());
// }
//
// /**
// * Now step up to the parent's parent
// */
// currentAssoc = nodeService.getPrimaryParent(parentNodeRef);
// }
// else
// {
// log.debug("parent is not an alien node");
// currentAssoc = null;
// }
// } // end of while
}
// /**
// * Is this node invaded ?
// * @param nodeRef
// * @param invader
// * @return true, this node has been invaded by the invader
// */
// private boolean isInvaded(NodeRef nodeRef, String invader)
// {
// List<String>invadedBy = (List<String>)nodeService.getProperty(nodeRef, TransferModel.PROP_INVADED_BY);
//
// if(invadedBy == null)
// {
// return false;
// }
//
// return invadedBy.contains(invader);
// }
//
// /**
// * Mark the specified node as an alien node, invadedby the invader.
// * @param newAlien
// * @param invader
// */
// private void setAlien(NodeRef newAlien, String invader)
// {
// // Introduce a Multi-valued property
// List<String> invadedBy = (List<String>)nodeService.getProperty(newAlien,
// TransferModel.PROP_INVADED_BY);
//
// if(invadedBy == null)
// {
// nodeService.setProperty(newAlien, TransferModel.PROP_ALIEN, Boolean.TRUE);
// invadedBy = new ArrayList<String>(1);
// }
// invadedBy.add(invader);
//
// /**
// * Set the invaded by property
// */
// nodeService.setProperty(newAlien, TransferModel.PROP_INVADED_BY, (Serializable) invadedBy);
//
// /**
// * Experiment with a residual property
// */
// nodeService.setProperty(newAlien, QName.createQName(TransferModel.TRANSFER_MODEL_1_0_URI,
// "invader" + invader), Boolean.TRUE);
//
// }
public void setDescriptorService(DescriptorService descriptorService)
{
this.descriptorService = descriptorService;

View File

@ -45,7 +45,7 @@ public interface TransferModel
*/
static final QName ASPECT_ALIEN = QName.createQName(TRANSFER_MODEL_1_0_URI, "alien");
static final QName PROP_INVADED_BY = QName.createQName(TRANSFER_MODEL_1_0_URI, "invadedBy");
static final QName PROP_ALIEN = QName.createQName(TRANSFER_MODEL_1_0_URI, "alien");
// static final QName PROP_ALIEN = QName.createQName(TRANSFER_MODEL_1_0_URI, "alien");
/*
* Type : Transfer Group