+ * So any children that are only invaded by the specified repository are deleted.
+ *
+ * Folders which are invaded by more than one repository will remain.
+ *
* @param parentNodeRef the root to prune
* @param fromRepositoryId the repositoryId to prune.
*/
@@ -29,25 +34,38 @@ public interface AlienProcessor
*/
public boolean isAlien(NodeRef nodeRef);
- /**
- * Called before deleting an alien node.
- *
- * @param nodeBeingDeleted node about to be deleted
- */
- public void beforeDeleteAlien(NodeRef deletedNodeRef);
-
/**
* Called before creating a child of a transferred node.
- *
+ *
* When a new node is created as a child of a Transferred or Alien node then
* the new node needs to be marked as an alien.
*
* Then the tree needs to be walked upwards to mark all parent
- * transferred nodes as alien.
+ * transferred nodes as alien.
*
* @param childAssocRef the association ref to the new node
* @param repositoryId - the repositoryId of the system who owns the new node.
+ * @param isNewNode - is this a new nide
*/
- public void onCreateChild(ChildAssociationRef childAssocRef, String repositoryId);
-
+ public void onCreateChild(ChildAssociationRef childAssocRef, String repositoryId, boolean isNewNode);
+
+ /**
+ * Called when an alien node has been moved from one parent to another.
+ *
+ * If the new parent is transferred or alien may make the new parent an alien.
+ *
+ * The alien node may also stop being an alien node.
+ */
+ public void afterMoveAlien(ChildAssociationRef newAssocRef);
+
+ /**
+ * Called before deleting an alien node.
+ *
+ * The tree needs to be walked upwards to take account of the removed alien node.
+ *
+ * @param nodeBeingDeleted node about to be deleted
+ * @param oldRef null if the deleted node is still "in place" and readable else the old ref prior to
+ * the node being moved.
+ */
+ public void beforeDeleteAlien(NodeRef deletedNodeRef, ChildAssociationRef oldRef);
}
diff --git a/source/java/org/alfresco/repo/transfer/AlienProcessorImpl.java b/source/java/org/alfresco/repo/transfer/AlienProcessorImpl.java
index 758d1a1cd0..77d6885437 100644
--- a/source/java/org/alfresco/repo/transfer/AlienProcessorImpl.java
+++ b/source/java/org/alfresco/repo/transfer/AlienProcessorImpl.java
@@ -19,6 +19,7 @@ import org.alfresco.service.cmr.dictionary.DictionaryService;
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.descriptor.DescriptorService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.PropertyCheck;
import org.apache.commons.logging.Log;
@@ -32,6 +33,7 @@ public class AlienProcessorImpl implements AlienProcessor
private NodeService nodeService;
private BehaviourFilter behaviourFilter;
private DictionaryService dictionaryService;
+ private DescriptorService descriptorService;
private static final Log log = LogFactory.getLog(AlienProcessorImpl.class);
@@ -40,21 +42,26 @@ public class AlienProcessorImpl implements AlienProcessor
PropertyCheck.mandatory(this, "nodeService", nodeService);
PropertyCheck.mandatory(this, "behaviourFilter", behaviourFilter);
PropertyCheck.mandatory(this, "dictionaryService", getDictionaryService());
+ PropertyCheck.mandatory(this, "descriptorService", descriptorService);
}
- public void onCreateChild(ChildAssociationRef childAssocRef, final String repositoryId)
+ public void onCreateChild(ChildAssociationRef childAssocRef, final String repositoryId, boolean isNewNode)
{
log.debug("on create child association to transferred node");
ChildAssociationRef currentAssoc = childAssocRef;
-
+ NodeRef parentNodeRef = currentAssoc.getParentRef();
+ NodeRef childNodeRef = currentAssoc.getChildRef();
+
if(!childAssocRef.isPrimary())
{
log.debug("not a primary assoc - do nothing");
return;
}
-
- // TODO Needs to check assoc is a cm:contains or subtype of cm:contains
+
+ /**
+ * check assoc is a cm:contains or subtype of cm:contains
+ */
if(!childAssocRef.getTypeQName().equals(ContentModel.ASSOC_CONTAINS))
{
Collection subAspects = dictionaryService.getSubAspects(ContentModel.ASSOC_CONTAINS, true);
@@ -64,14 +71,11 @@ public class AlienProcessorImpl implements AlienProcessor
return;
}
}
-
- NodeRef parentNodeRef = currentAssoc.getParentRef();
- NodeRef childNodeRef = currentAssoc.getChildRef();
- if(!nodeService.hasAspect(parentNodeRef, TransferModel.ASPECT_TRANSFERRED))
+ if(!(nodeService.hasAspect(parentNodeRef, TransferModel.ASPECT_TRANSFERRED) || nodeService.hasAspect(parentNodeRef, TransferModel.ASPECT_ALIEN)))
{
- log.debug("parent was not transferred - do nothing");
- return;
+ log.debug("parent was not transferred or alien - do nothing");
+ return;
}
if(!nodeService.hasAspect(parentNodeRef, TransferModel.ASPECT_ALIEN))
@@ -83,8 +87,8 @@ public class AlienProcessorImpl implements AlienProcessor
{
log.debug("parent was not alien and this node is from the same repo - do nothing");
return;
- }
- }
+ }
+ }
}
/**
@@ -143,30 +147,64 @@ public class AlienProcessorImpl implements AlienProcessor
log.debug("parent is not a transferred node");
currentAssoc = null;
}
- }
- }
-
- public void beforeDeleteAlien(NodeRef deletedNodeRef)
+ }
+ }
+
+ public void beforeDeleteAlien(NodeRef deletedNodeRef, ChildAssociationRef oldAssoc)
{
log.debug("before delete node - need to check for alien invaders");
- Liststuff = (List)nodeService.getProperty(deletedNodeRef, TransferModel.PROP_INVADED_BY);
-
+ Liststuff = (List)nodeService.getProperty(deletedNodeRef, TransferModel.PROP_INVADED_BY);
Vector exInvaders = new Vector(stuff);
- ChildAssociationRef currentAssoc = nodeService.getPrimaryParent(deletedNodeRef);
+ /**
+ * some fudge to get this to run after the node has been moved.
+ */
+ ChildAssociationRef currentAssoc;
+ if(oldAssoc != null)
+ {
+ currentAssoc = oldAssoc;
+ }
+ else
+ {
+ currentAssoc = nodeService.getPrimaryParent(deletedNodeRef);
+ }
while(currentAssoc != null && exInvaders != null && exInvaders.size() > 0)
{
NodeRef parentNodeRef = currentAssoc.getParentRef();
- NodeRef currentNodeRef = currentAssoc.getChildRef();
+ NodeRef currentNodeRef;
+
+ if(currentAssoc == oldAssoc)
+ {
+ currentNodeRef = deletedNodeRef;
+ }
+ else
+ {
+ currentNodeRef = currentAssoc.getChildRef();
+ }
/**
* Does the parent have alien invaders ?
*/
if(nodeService.hasAspect(parentNodeRef, TransferModel.ASPECT_ALIEN))
{
- log.debug("parent node is alien - check siblings");
+ log.debug("parent node is invaded by aliens");
+
+ /**
+ * Remove the parent's origin from the list of exInvaders since the parent also invades.
+ */
+ String parentRepoId;
+ if(nodeService.hasAspect(parentNodeRef, TransferModel.ASPECT_TRANSFERRED))
+ {
+ parentRepoId = (String)nodeService.getProperty(parentNodeRef, TransferModel.PROP_FROM_REPOSITORY_ID);
+ }
+ else
+ {
+ parentRepoId = descriptorService.getCurrentRepositoryDescriptor().getId();
+ }
+
+ exInvaders.remove(parentRepoId);
/**
* For each invader of the deletedNode
@@ -178,8 +216,8 @@ public class AlienProcessorImpl implements AlienProcessor
log.debug("Checking exInvader:" + exInvader);
/**
- * Check the siblings of this node to see whether there are any other alien nodes for this invader.
- */
+ * 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 refs = nodeService.getChildAssocs(parentNodeRef);
@@ -190,7 +228,7 @@ public class AlienProcessorImpl implements AlienProcessor
if(childRef.equals(currentNodeRef))
{
- // do nothing - this is the node we are working with.
+ // do nothing - this is the node we are working with.
}
else
{
@@ -266,7 +304,223 @@ public class AlienProcessorImpl implements AlienProcessor
}
} // end of while
}
-
+
+
+ public void afterMoveAlien(ChildAssociationRef newAssocRef)
+ {
+ log.debug("after move alien: newAssocRef");
+
+ NodeRef parentNodeRef = newAssocRef.getParentRef();
+ NodeRef childNodeRef = newAssocRef.getChildRef();
+
+ List childInvadedBy = (List)nodeService.getProperty(childNodeRef, TransferModel.PROP_INVADED_BY);
+
+ if(nodeService.hasAspect(parentNodeRef, TransferModel.ASPECT_TRANSFERRED) || nodeService.hasAspect(parentNodeRef, TransferModel.ASPECT_ALIEN))
+ {
+ ListaliensToAdd = new ArrayList();
+
+ log.debug("new parent is transferred or alien");
+
+ /**
+ * check assoc is a cm:contains or subtype of cm:contains
+ */
+ if(!newAssocRef.getTypeQName().equals(ContentModel.ASSOC_CONTAINS))
+ {
+ Collection subAspects = dictionaryService.getSubAspects(ContentModel.ASSOC_CONTAINS, true);
+ if(!subAspects.contains(newAssocRef.getTypeQName()))
+ {
+ log.debug("not a subtype of cm:contains - may need to uninvade");
+
+ String parentRepoId = descriptorService.getCurrentRepositoryDescriptor().getId();
+ retreatDownwards(childNodeRef, parentRepoId);
+
+ return;
+ }
+ }
+
+ if(nodeService.hasAspect(parentNodeRef, TransferModel.ASPECT_ALIEN))
+ {
+ // parent is already alien
+ ListparentInvadedBy = (List)nodeService.getProperty(parentNodeRef, TransferModel.PROP_INVADED_BY);
+ for(String invader : childInvadedBy)
+ {
+ if(!parentInvadedBy.contains(invader))
+ {
+ aliensToAdd.add(invader);
+ }
+ }
+ }
+ else
+ {
+ // parent is transfered but does not yet contain aliens
+ String parentFromRepo = (String)nodeService.getProperty(parentNodeRef, TransferModel.PROP_FROM_REPOSITORY_ID);
+ {
+ for(String invader : childInvadedBy)
+ {
+ if(invader.equalsIgnoreCase(parentFromRepo))
+ {
+ // The invader is the same repo
+ log.debug("child node is from the same repo as a non invaded node");
+ retreatDownwards(childNodeRef, parentFromRepo);
+ }
+ else
+ {
+ aliensToAdd.add(invader);
+ }
+ }
+ }
+ }
+
+ /**
+ * Now deal with the parents of this alien node
+ */
+ ChildAssociationRef currentAssoc = newAssocRef;
+ while(currentAssoc != null && aliensToAdd.size() > 0)
+ {
+ parentNodeRef = currentAssoc.getParentRef();
+ childNodeRef = currentAssoc.getChildRef();
+
+ if(nodeService.hasAspect(parentNodeRef, TransferModel.ASPECT_TRANSFERRED) || nodeService.hasAspect(parentNodeRef, TransferModel.ASPECT_ALIEN))
+ {
+ for(String alienRepoId : aliensToAdd)
+ {
+ if (!isInvaded(parentNodeRef, alienRepoId))
+ {
+ if(log.isDebugEnabled())
+ {
+ log.debug("alien invades parent node:" + parentNodeRef + ", repositoryId:" + alienRepoId);
+ }
+
+ final NodeRef newAlien = parentNodeRef;
+ final String fAlien = alienRepoId;
+ /**
+ * 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 actionRunAs = new RunAsWork()
+ {
+ public Void doWork() throws Exception
+ {
+ getBehaviourFilter().disableBehaviour(newAlien, ContentModel.ASPECT_AUDITABLE);
+ getBehaviourFilter().disableBehaviour(newAlien, ContentModel.ASPECT_LOCKABLE);
+ setAlien(newAlien, fAlien);
+ return null;
+ }
+ };
+ AuthenticationUtil.runAs(actionRunAs, AuthenticationUtil.getSystemUserName());
+ }
+ else
+ {
+ log.debug("parent node is already invaded by:" + alienRepoId);
+ aliensToAdd.remove(alienRepoId);
+ }
+
+ // Yes the parent has been invaded so step up to the parent's parent
+ currentAssoc = nodeService.getPrimaryParent(parentNodeRef);
+ }
+ }
+ else
+ {
+ log.debug("parent is not a transferred node");
+ currentAssoc = null;
+ }
+ }
+ }
+ else
+ {
+ log.debug("parent was not transferred or alien");
+
+ // TODO Need to remove the alien flags
+ String parentRepoId = descriptorService.getCurrentRepositoryDescriptor().getId();
+ retreatDownwards(childNodeRef, parentRepoId);
+
+ return;
+ }
+ } // after move alien
+
+ /**
+ * Top down un-invasion
+ *
+ * Steps down the tree retreating from all the invaded nodes.
+ *
+ * The retreat will stop is there is a "sub-invasion".
+ *
+ * @param nodeRef the top of the tree
+ * @param repoId the repository that is retreating.
+ */
+ private void retreatDownwards(NodeRef nodeRef, String fromRepositoryId)
+ {
+ Stack nodesToRetreat = new Stack();
+ nodesToRetreat.add(nodeRef);
+
+ /**
+ * Now go and do the retreat.
+ */
+ while(!nodesToRetreat.isEmpty())
+ {
+ if(log.isDebugEnabled())
+ {
+ log.debug("retreat :" + nodeRef + ", repoId:" + fromRepositoryId);
+ }
+
+ /**
+ * for the current node and all alien children
+ *
+ * if they are "from" the retreating repository then
+ */
+ NodeRef currentNodeRef = nodesToRetreat.pop();
+
+ log.debug("retreatNode:" + currentNodeRef);
+
+ if(getNodeService().hasAspect(currentNodeRef, TransferModel.ASPECT_ALIEN))
+ {
+ // Yes this is an alien node
+ ListinvadedBy = (List)getNodeService().getProperty(currentNodeRef, TransferModel.PROP_INVADED_BY);
+
+ String parentRepoId;
+ if(nodeService.hasAspect(currentNodeRef, TransferModel.ASPECT_TRANSFERRED))
+ {
+ log.debug("node is transferred");
+ parentRepoId = (String)nodeService.getProperty(currentNodeRef, TransferModel.PROP_FROM_REPOSITORY_ID);
+ }
+ else
+ {
+ log.debug("node is local");
+ parentRepoId = descriptorService.getCurrentRepositoryDescriptor().getId();
+ }
+
+ if(fromRepositoryId.equalsIgnoreCase(parentRepoId))
+ {
+ // This node is "owned" by the retreating repo
+ // Yes we are invaded by fromRepositoryId
+ if(invadedBy.size() == 1)
+ {
+ // we are invaded by a single repository which must be fromRepositoryId
+ log.debug("no longe alien:" + currentNodeRef);
+ getNodeService().removeAspect(currentNodeRef, TransferModel.ASPECT_ALIEN);
+ }
+ else
+ {
+ invadedBy.remove(parentRepoId);
+ getNodeService().setProperty(currentNodeRef, TransferModel.PROP_INVADED_BY, (Serializable)invadedBy);
+ }
+
+ //TODO replace with a more efficient query
+ List refs = getNodeService().getChildAssocs(currentNodeRef);
+ for(ChildAssociationRef ref : refs)
+ {
+ if(log.isDebugEnabled())
+ {
+ log.debug("will need to check child:" + ref);
+ }
+ nodesToRetreat.push(ref.getChildRef());
+ }
+ }
+ }
+ }
+ } // retreatDownwards
+
public boolean isAlien(NodeRef nodeRef)
{
return nodeService.hasAspect(nodeRef, TransferModel.ASPECT_ALIEN);
@@ -479,7 +733,7 @@ public class AlienProcessorImpl implements AlienProcessor
}
/**
- * Recalculate the whether this node is invaded by the specified repository
+ * Determine whether the specified node is invaded by the specified repository
* @param folderNodeRef the node to re-calculate
* @param fromRepositoryId the repository who is transferring.
*
@@ -527,7 +781,7 @@ public class AlienProcessorImpl implements AlienProcessor
return stillInvaded;
}
-
+
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
@@ -557,4 +811,14 @@ public class AlienProcessorImpl implements AlienProcessor
{
return dictionaryService;
}
+
+ public void setDescriptorService(DescriptorService descriptorService)
+ {
+ this.descriptorService = descriptorService;
+ }
+
+ public DescriptorService getDescriptorService()
+ {
+ return descriptorService;
+ }
}
diff --git a/source/java/org/alfresco/repo/transfer/RepoPrimaryManifestProcessorImpl.java b/source/java/org/alfresco/repo/transfer/RepoPrimaryManifestProcessorImpl.java
index a6c97f7391..ad508e017f 100644
--- a/source/java/org/alfresco/repo/transfer/RepoPrimaryManifestProcessorImpl.java
+++ b/source/java/org/alfresco/repo/transfer/RepoPrimaryManifestProcessorImpl.java
@@ -338,7 +338,7 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
*/
if(nodeService.hasAspect(parentNodeRef, TransferModel.ASPECT_TRANSFERRED))
{
- alienProcessor.onCreateChild(newNode, header.getRepositoryId());
+ alienProcessor.onCreateChild(newNode, header.getRepositoryId(), true);
}
// Is the node that we've just added the parent of any orphans that
@@ -408,7 +408,7 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
*/
if(nodeService.hasAspect(newRef.getParentRef(), TransferModel.ASPECT_TRANSFERRED))
{
- alienProcessor.onCreateChild(newRef, header.getRepositoryId());
+ alienProcessor.onCreateChild(newRef, header.getRepositoryId(), true);
}
}
// We can now remove the record of these orphans, as their parent
@@ -477,19 +477,16 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
*/
if(nodeService.hasAspect(currentParent.getParentRef(), TransferModel.ASPECT_ALIEN))
{
- // old parent node ref may be alien
- alienProcessor.beforeDeleteAlien(node.getNodeRef());
+ // old parent node ref may be alien so treat as a delete
+ alienProcessor.beforeDeleteAlien(currentParent.getChildRef(), null);
}
// Yes, we need to move the node
ChildAssociationRef newNode = nodeService.moveNode(nodeToUpdate, parentNodeRef, parentAssocType, parentAssocName);
logProgress("Moved node " + nodeToUpdate + " to be under parent node " + parentNodeRef);
- // We may have created a new alien.
- if(nodeService.hasAspect(parentNodeRef, TransferModel.ASPECT_TRANSFERRED))
- {
- alienProcessor.onCreateChild(newNode, header.getRepositoryId());
- }
+ alienProcessor.afterMoveAlien(newNode);
+
}
log.info("Resolved parent node to " + parentNodeRef);
diff --git a/source/java/org/alfresco/repo/transfer/RepoTransferReceiverImpl.java b/source/java/org/alfresco/repo/transfer/RepoTransferReceiverImpl.java
index c8e973fe53..308a94fb5c 100644
--- a/source/java/org/alfresco/repo/transfer/RepoTransferReceiverImpl.java
+++ b/source/java/org/alfresco/repo/transfer/RepoTransferReceiverImpl.java
@@ -41,7 +41,9 @@ import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.alfresco.model.ContentModel;
+import org.alfresco.repo.copy.CopyServicePolicies.BeforeCopyPolicy;
import org.alfresco.repo.node.NodeServicePolicies;
+import org.alfresco.repo.node.NodeServicePolicies.OnMoveNodePolicy;
import org.alfresco.repo.policy.BehaviourFilter;
import org.alfresco.repo.policy.JavaBehaviour;
import org.alfresco.repo.policy.PolicyComponent;
@@ -86,7 +88,9 @@ import org.springframework.util.FileCopyUtils;
*/
public class RepoTransferReceiverImpl implements TransferReceiver,
NodeServicePolicies.OnCreateChildAssociationPolicy,
- NodeServicePolicies.BeforeDeleteNodePolicy
+ NodeServicePolicies.BeforeDeleteNodePolicy,
+ NodeServicePolicies.OnRestoreNodePolicy,
+ NodeServicePolicies.OnMoveNodePolicy
{
/**
@@ -195,14 +199,38 @@ public class RepoTransferReceiverImpl implements TransferReceiver,
TransferModel.ASPECT_TRANSFERRED,
new JavaBehaviour(this, "onCreateChildAssociation", NotificationFrequency.EVERY_EVENT));
+ /**
+ * For every new child of a node with the trx:alien aspect run this.onCreateChildAssociation
+ */
+ this.getPolicyComponent().bindAssociationBehaviour(
+ NodeServicePolicies.OnCreateChildAssociationPolicy.QNAME,
+ TransferModel.ASPECT_ALIEN,
+ new JavaBehaviour(this, "onCreateChildAssociation", NotificationFrequency.EVERY_EVENT));
+
/**
* For every node with the trx:alien aspect run this.beforeDeleteNode
*/
this.getPolicyComponent().bindClassBehaviour(
NodeServicePolicies.BeforeDeleteNodePolicy.QNAME,
TransferModel.ASPECT_ALIEN,
- new JavaBehaviour(this, "beforeDeleteNode", NotificationFrequency.EVERY_EVENT));
-
+ new JavaBehaviour(this, "beforeDeleteNode", NotificationFrequency.EVERY_EVENT));
+
+ /**
+ * For every restore of a node with the trx:alien aspect
+ */
+ this.getPolicyComponent().bindClassBehaviour(
+ NodeServicePolicies.OnRestoreNodePolicy.QNAME,
+ TransferModel.ASPECT_ALIEN,
+ new JavaBehaviour(this, "onRestoreNode", NotificationFrequency.EVERY_EVENT));
+
+ /**
+ * For every move of a node with the trx:alien aspect.
+ */
+ this.getPolicyComponent().bindClassBehaviour(
+ NodeServicePolicies.OnMoveNodePolicy.QNAME,
+ TransferModel.ASPECT_ALIEN,
+ new JavaBehaviour(this, "onMoveNode", NotificationFrequency.EVERY_EVENT));
+
}
/*
@@ -968,7 +996,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);
+ alienProcessor.onCreateChild(childAssocRef, localRepositoryId, isNewNode);
}
/**
@@ -979,7 +1007,36 @@ public class RepoTransferReceiverImpl implements TransferReceiver,
public void beforeDeleteNode(NodeRef deletedNodeRef)
{
log.debug("on delete node - need to check for transferred node");
- alienProcessor.beforeDeleteAlien(deletedNodeRef);
+ alienProcessor.beforeDeleteAlien(deletedNodeRef, null);
+ }
+
+ /**
+ * When a transferred node is restored it may be a new invader or it may no
+ * longer be an invader.
+ *
+ * Walk the tree checking the invasion status!
+ */
+ public void onRestoreNode(ChildAssociationRef childAssocRef)
+ {
+ log.debug("on restore node");
+ final String localRepositoryId = descriptorService.getCurrentRepositoryDescriptor().getId();
+ log.debug("restoredAssocRef:" + childAssocRef);
+ alienProcessor.afterMoveAlien(childAssocRef);
+ }
+
+ /**
+ * When an alien node is moved it may un-invade its old location and invade a new
+ * location. The node may also cease to be alien.
+ */
+ public void onMoveNode(ChildAssociationRef oldChildAssocRef,
+ ChildAssociationRef newChildAssocRef)
+ {
+
+ log.debug("onMoveNode");
+ log.debug("oldChildAssocRef:" + oldChildAssocRef);
+ log.debug("newChildAssocRef:" + newChildAssocRef);
+ alienProcessor.beforeDeleteAlien(newChildAssocRef.getChildRef(), oldChildAssocRef);
+ alienProcessor.afterMoveAlien(newChildAssocRef);
}
public void setDescriptorService(DescriptorService descriptorService)
diff --git a/source/java/org/alfresco/repo/transfer/TransferServiceImplTest.java b/source/java/org/alfresco/repo/transfer/TransferServiceImplTest.java
index 605e8fc839..c7fa714ddb 100644
--- a/source/java/org/alfresco/repo/transfer/TransferServiceImplTest.java
+++ b/source/java/org/alfresco/repo/transfer/TransferServiceImplTest.java
@@ -2789,11 +2789,13 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
*
* A1
* | | |
- * A2 A3 (Content Node) B9 Alien Content Node
+ * A2 A3 (Content Node) B9 (Alien Content Node)
* |
* A4 A5 B10 (Alien Content Node) A6
* | |
- * A7 B11 (Alien Content Node) A8 B12 B13 Alien Contact Nodes
+ * A7 B11 (Alien Content Node) A8 B12 B13 (Alien Content Node)
+ * |
+ * B14
*
* Test steps -
*
@@ -2801,9 +2803,11 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
* transfer(sync)
* - add Alien node B9. A1 becomes Alien.
* - remove alien node B9. A1 becomes non Alien.
+ - restore alien node B9. A1 becomes non Alien again.
* - add Alien node B10. A1 and A2 become Alien
* - remove Alien node B10. A1 and A2 become non Alien
- * - add B12 A6, A2, A1 becomes Alien
+ * - add B12 and B14 A6, A2, A1 becomes Alien
+ * - remove B14, B12, A6, A2, A1 remain Alien
* - add B13 A6, A2, A1 remains Alien
* - remove B13 A6, A2, A1 remains Alien
* - remove B12 A6, A2, A1 becomes non Alien.
@@ -2813,11 +2817,6 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
* transfer sync
* (A5, A6, A7 and A8 should be deleted A2 and A4 remain since they contain alien content.)
*
- *
- * TODO test move and alien
- *
- * TODO test restore and alien
- *
*/
public void testTransferInvadedByLocalAlienNodes() throws Exception
{
@@ -2867,6 +2866,7 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
NodeRef B11NodeRef;
NodeRef B12NodeRef;
NodeRef B13NodeRef;
+ NodeRef B14NodeRef;
NodeRef destNodeRef;
@@ -3091,11 +3091,7 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
{
NodeRef A1destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
NodeRef A3destNodeRef = testNodeFactory.getMappedNodeRef(A3NodeRef);
-
- // Temp code
List invaders = (List) nodeService.getProperty(A1destNodeRef, TransferModel.PROP_INVADED_BY);
- logger.debug("MER WOZ ERE AFTER B9 deleted" + invaders);
-
assertTrue("dest node ref does not exist", nodeService.exists(A1destNodeRef));
assertFalse("node A1 is still alien", (Boolean)nodeService.hasAspect(A1destNodeRef, TransferModel.ASPECT_ALIEN));
assertFalse("node A3 is alien", (Boolean)nodeService.hasAspect(A3destNodeRef, TransferModel.ASPECT_ALIEN));
@@ -3176,20 +3172,21 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
/**
* Step 6
- * add B12 (child of A6) A6, A2, A1 becomes Alien
+ * add B12 (child of A6) and B14 A6, A2, A1 becomes Alien
*/
startNewTransaction();
try
{
destNodeRef = testNodeFactory.getMappedNodeRef(A6NodeRef);
- ChildAssociationRef child = nodeService.createNode(destNodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("B12"), ContentModel.TYPE_CONTENT);
+ ChildAssociationRef child = nodeService.createNode(destNodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("B12"), ContentModel.TYPE_FOLDER);
B12NodeRef = child.getChildRef();
nodeService.setProperty(B12NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
- nodeService.setProperty(B12NodeRef, ContentModel.PROP_NAME, "B12");
-
- ContentWriter writer = contentService.getWriter(B12NodeRef, ContentModel.PROP_CONTENT, true);
- writer.setLocale(CONTENT_LOCALE);
- writer.putContent(CONTENT_STRING);
+ nodeService.setProperty(B12NodeRef, ContentModel.PROP_NAME, "B12");
+
+ child = nodeService.createNode(B12NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("B14"), ContentModel.TYPE_CONTENT);
+ B14NodeRef = child.getChildRef();
+ nodeService.setProperty(B14NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
+ nodeService.setProperty(B14NodeRef, ContentModel.PROP_NAME, "B14");
}
finally
{
@@ -3207,6 +3204,41 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
assertTrue("node A1 is not alien", (Boolean)nodeService.hasAspect(A1destNodeRef, TransferModel.ASPECT_ALIEN));
assertTrue("node A2 is not alien", (Boolean)nodeService.hasAspect(A2destNodeRef, TransferModel.ASPECT_ALIEN));
assertTrue("node A6 is not alien", (Boolean)nodeService.hasAspect(A6destNodeRef, TransferModel.ASPECT_ALIEN));
+ assertTrue("node B14 is not alien", (Boolean)nodeService.hasAspect(B14NodeRef, TransferModel.ASPECT_ALIEN));
+ assertTrue("node B12 is not alien", (Boolean)nodeService.hasAspect(B12NodeRef, TransferModel.ASPECT_ALIEN));
+ }
+
+ finally
+ {
+ endTransaction();
+ }
+
+ /**
+ * Step 6a.
+ * Delete B14. B12 remains alien
+ */
+ startNewTransaction();
+ try
+ {
+ nodeService.deleteNode(B14NodeRef);
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+ startNewTransaction();
+ try
+ {
+ // Now validate that the target node exists and has similar properties to the source
+ NodeRef A1destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
+ NodeRef A2destNodeRef = testNodeFactory.getMappedNodeRef(A2NodeRef);
+ NodeRef A6destNodeRef = testNodeFactory.getMappedNodeRef(A6NodeRef);
+
+ assertTrue("node A1 is not alien", (Boolean)nodeService.hasAspect(A1destNodeRef, TransferModel.ASPECT_ALIEN));
+ assertTrue("node A2 is not alien", (Boolean)nodeService.hasAspect(A2destNodeRef, TransferModel.ASPECT_ALIEN));
+ assertTrue("node A6 is not alien", (Boolean)nodeService.hasAspect(A6destNodeRef, TransferModel.ASPECT_ALIEN));
+ assertTrue("node B12 is not alien", (Boolean)nodeService.hasAspect(B12NodeRef, TransferModel.ASPECT_ALIEN));
}
finally
@@ -3491,6 +3523,341 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
}
}
+ /**
+ * Test restore of a local node.
+ *
+ * Tree of nodes
+ * A1 B1
+ * |
+ * B2
+ * |
+ * B3
+ *
+ *
+ * - Add B2. A1 is alien.
+ * - Delete B2. A1 not alien
+ * - Restore B2. A1 is alien
+ * - Add B3. A1 is alien
+ * - Delete B2. A1 not alien
+ * - Restore to B1. B2 and B3 not alien.
+ *
+ * @throws Exception
+ */
+ public void testLocalAlienRestore() throws Exception
+ {
+ setDefaultRollback(false);
+
+ String CONTENT_TITLE = "ContentTitle";
+ String CONTENT_TITLE_UPDATED = "ContentTitleUpdated";
+ Locale CONTENT_LOCALE = Locale.JAPAN;
+ String CONTENT_STRING = "Hello";
+
+
+ /**
+ * Now go ahead and create our first transfer target
+ */
+ String targetName = "testRestoreOfAlienNodes";
+ TransferTarget transferMe;
+
+ NodeRef S0NodeRef;
+ NodeRef A0NodeRef;
+ NodeRef A1NodeRef;
+ NodeRef B1NodeRef;
+ NodeRef B2NodeRef;
+ NodeRef B3NodeRef;
+
+ NodeRef destNodeRef;
+
+ startNewTransaction();
+ try
+ {
+ /**
+ * Get guest home
+ */
+ String guestHomeQuery = "/app:company_home/app:guest_home";
+ ResultSet guestHomeResult = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_XPATH, guestHomeQuery);
+ assertEquals("", 1, guestHomeResult.length());
+ NodeRef guestHome = guestHomeResult.getNodeRef(0);
+
+ /**
+ * Create a test nodes A1 through A8 that we will read and write
+ */
+ {
+ // Node S0
+ String name = GUID.generate();
+ ChildAssociationRef child = nodeService.createNode(guestHome, ContentModel.ASSOC_CONTAINS, QName.createQName(name), ContentModel.TYPE_FOLDER);
+ S0NodeRef = child.getChildRef();
+ nodeService.setProperty(S0NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
+ nodeService.setProperty(S0NodeRef, ContentModel.PROP_NAME, name);
+ }
+ {
+ // Node A1
+ ChildAssociationRef child = nodeService.createNode(S0NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A0"), ContentModel.TYPE_FOLDER);
+ A0NodeRef = child.getChildRef();
+ nodeService.setProperty(A0NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
+ nodeService.setProperty(A0NodeRef, ContentModel.PROP_NAME, "A0");
+ }
+ {
+ // Node A1
+ ChildAssociationRef child = nodeService.createNode(A0NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A1"), ContentModel.TYPE_FOLDER);
+ A1NodeRef = child.getChildRef();
+ nodeService.setProperty(A1NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
+ nodeService.setProperty(A1NodeRef, ContentModel.PROP_NAME, "A1");
+ }
+ {
+ // Node B1
+ ChildAssociationRef child = nodeService.createNode(S0NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("B1"), ContentModel.TYPE_FOLDER);
+ B1NodeRef = child.getChildRef();
+ nodeService.setProperty(B1NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
+ nodeService.setProperty(B1NodeRef, ContentModel.PROP_NAME, "B1");
+ }
+
+ // Create the transfer target if it does not already exist
+ if(!transferService.targetExists(targetName))
+ {
+ transferMe = createTransferTarget(targetName);
+ }
+ else
+ {
+ transferMe = transferService.getTransferTarget(targetName);
+ }
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+ /**
+ * For unit test
+ * - replace the HTTP transport with the in-process transport
+ * - replace the node factory with one that will map node refs, paths etc.
+ *
+ * Mock the transfer service to be from Repo A
+ */
+ TransferTransmitter transmitter = new UnitTestInProcessTransmitterImpl(receiver, contentService, transactionService);
+ transferServiceImpl.setTransmitter(transmitter);
+ UnitTestTransferManifestNodeFactory testNodeFactory = new UnitTestTransferManifestNodeFactory(this.transferManifestNodeFactory);
+ transferServiceImpl.setTransferManifestNodeFactory(testNodeFactory);
+ List> pathMap = testNodeFactory.getPathMap();
+ pathMap.add(new Pair(nodeService.getPath(A0NodeRef), nodeService.getPath(B1NodeRef)));
+ DescriptorService mockedDescriptorService = getMockDescriptorService(REPO_ID_A);
+ transferServiceImpl.setDescriptorService(mockedDescriptorService);
+
+ /**
+ * Step 1. add A1
+ * transfer(sync)
+ */
+ startNewTransaction();
+ try
+ {
+ /**
+ * Transfer Nodes A1
+ */
+ {
+ TransferDefinition definition = new TransferDefinition();
+ Setnodes = new HashSet();
+ nodes.add(A1NodeRef);
+ definition.setNodes(nodes);
+ definition.setSync(true);
+ transferService.transfer(targetName, definition);
+ }
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+ startNewTransaction();
+ try
+ {
+ // Now validate that the target node exists and has similar properties to the source
+ NodeRef A1destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
+ assertTrue("dest node ref does not exist", nodeService.exists(A1destNodeRef));
+ assertFalse("A1 is alien", nodeService.hasAspect(A1destNodeRef, TransferModel.ASPECT_ALIEN));
+ // Check injected transferred aspect.
+ assertNotNull("transferredAspect", (String)nodeService.getProperty(A1destNodeRef, TransferModel.PROP_REPOSITORY_ID));
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+ /**
+ * Step 2 add Alien node B1 child of A1(dest).
+ */
+ startNewTransaction();
+ try
+ {
+ destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
+ ChildAssociationRef child = nodeService.createNode(destNodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("B2"), ContentModel.TYPE_FOLDER);
+ B2NodeRef = child.getChildRef();
+ nodeService.setProperty(B2NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
+ nodeService.setProperty(B2NodeRef, ContentModel.PROP_NAME, "B2");
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+ startNewTransaction();
+ try
+ {
+ // Now validate that the target node exists and has similar properties to the source
+ NodeRef A1destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
+
+ assertTrue("dest node ref does not exist", nodeService.exists(A1destNodeRef));
+ // Check injected transferred aspect.
+ assertTrue("node A1 is not alien aspect", (Boolean)nodeService.hasAspect(A1destNodeRef, TransferModel.ASPECT_ALIEN));
+ assertNotNull("repository id is null", (String)nodeService.getProperty(A1destNodeRef, TransferModel.PROP_REPOSITORY_ID));
+ assertNotNull("from repository id is null", (String)nodeService.getProperty(A1destNodeRef, TransferModel.PROP_FROM_REPOSITORY_ID));
+ assertTrue("node B2 is not alien", (Boolean)nodeService.hasAspect(B2NodeRef, TransferModel.ASPECT_ALIEN));
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+ /**
+ * Step 3 remove alien node B2. A1 becomes non Alien.
+ */
+ startNewTransaction();
+ try
+ {
+ logger.debug("delete node B2");
+ nodeService.deleteNode(B2NodeRef);
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+ startNewTransaction();
+ try
+ {
+ NodeRef A1destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
+ List invaders = (List) nodeService.getProperty(A1destNodeRef, TransferModel.PROP_INVADED_BY);
+ assertTrue("dest node ref does not exist", nodeService.exists(A1destNodeRef));
+ assertFalse("node A1 is still alien", (Boolean)nodeService.hasAspect(A1destNodeRef, TransferModel.ASPECT_ALIEN));
+ assertNotNull("repository id is null", (String)nodeService.getProperty(A1destNodeRef, TransferModel.PROP_REPOSITORY_ID));
+ assertNotNull("from repository id is null", (String)nodeService.getProperty(A1destNodeRef, TransferModel.PROP_FROM_REPOSITORY_ID));
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+ /**
+ * Step 4 restore alien node B2. A1 becomes Alien again
+ */
+ startNewTransaction();
+ try
+ {
+ logger.debug("restore node B2");
+ NodeRef B2ArchiveNodeRef = new NodeRef(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE, B2NodeRef.getId());
+ nodeService.restoreNode(B2ArchiveNodeRef, testNodeFactory.getMappedNodeRef(A1NodeRef), ContentModel.ASSOC_CONTAINS, QName.createQName("B2"));
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+ startNewTransaction();
+ try
+ {
+ NodeRef A1destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
+ assertTrue("dest node ref does not exist", nodeService.exists(A1destNodeRef));
+ assertTrue("node A1 is not alien", (Boolean)nodeService.hasAspect(A1destNodeRef, TransferModel.ASPECT_ALIEN));
+ assertNotNull("repository id is null", (String)nodeService.getProperty(A1destNodeRef, TransferModel.PROP_REPOSITORY_ID));
+ assertNotNull("from repository id is null", (String)nodeService.getProperty(A1destNodeRef, TransferModel.PROP_FROM_REPOSITORY_ID));
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+ /**
+ * Step 5 - add B3
+ */
+ startNewTransaction();
+ try
+ {
+ ChildAssociationRef child = nodeService.createNode(B2NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("B3"), ContentModel.TYPE_FOLDER);
+ B3NodeRef = child.getChildRef();
+ nodeService.setProperty(B3NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
+ nodeService.setProperty(B3NodeRef, ContentModel.PROP_NAME, "B3");
+ }
+ finally
+ {
+ endTransaction();
+ }
+ startNewTransaction();
+ try
+ {
+ assertTrue("node B3 is not alien", (Boolean)nodeService.hasAspect(B3NodeRef, TransferModel.ASPECT_ALIEN));
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+ /**
+ * Step 5 remove alien node B2. A1 becomes non Alien (again).
+ */
+ startNewTransaction();
+ try
+ {
+ logger.debug("delete node B2");
+ nodeService.deleteNode(B2NodeRef);
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+ startNewTransaction();
+ try
+ {
+ NodeRef A1destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
+ List invaders = (List) nodeService.getProperty(A1destNodeRef, TransferModel.PROP_INVADED_BY);
+ assertTrue("dest node ref does not exist", nodeService.exists(A1destNodeRef));
+ assertFalse("node A1 is still alien", (Boolean)nodeService.hasAspect(A1destNodeRef, TransferModel.ASPECT_ALIEN));
+ assertNotNull("repository id is null", (String)nodeService.getProperty(A1destNodeRef, TransferModel.PROP_REPOSITORY_ID));
+ assertNotNull("from repository id is null", (String)nodeService.getProperty(A1destNodeRef, TransferModel.PROP_FROM_REPOSITORY_ID));
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+ /**
+ * Step6 restore B2 and B3 to B1.
+ */
+ startNewTransaction();
+ try
+ {
+ logger.debug("restore node B2");
+ NodeRef B2ArchiveNodeRef = new NodeRef(StoreRef.STORE_REF_ARCHIVE_SPACESSTORE, B2NodeRef.getId());
+ nodeService.restoreNode(B2ArchiveNodeRef, B1NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("B2"));
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+ startNewTransaction();
+ try
+ {
+ assertFalse("node A1 is still alien", (Boolean)nodeService.hasAspect(testNodeFactory.getMappedNodeRef(A1NodeRef), TransferModel.ASPECT_ALIEN));
+ assertFalse("node A2 is still alien", (Boolean)nodeService.hasAspect(B2NodeRef, TransferModel.ASPECT_ALIEN));
+ assertFalse("node A3 is still alien", (Boolean)nodeService.hasAspect(B3NodeRef, TransferModel.ASPECT_ALIEN));
+ }
+ finally
+ {
+ endTransaction();
+ }
+ }
+
+
/**
* Test the transfer method with regard to permissions on a node.
@@ -5034,16 +5401,31 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
* Tree
*
* B1
- * | |
- * C2(p1) C3(p2)
+ * | | |
+ * C2(p1) C3(p2) A4
+ * |
+ * A5
* |
- * A4
+ * B6
*
*
- * Setup tree above. Validate that A1 is child of C2.
+ * Step 1: Tansfer in C's nodes to Repo B
*
- * Step 1. Move A4 fron C2 to C3 via transfer.
- * C2Dest should stop being invaded C3Dest should be invaded.
+ * Step 2. Transfer in A's nodes to Repo B
+ *
+ * Setup tree above. Validate that A2 is child of C2 dest.
+ * A4 is a child of B1
+ *
+ * Step 3. Move A5 from C2 to C3 via transfer.
+ * C2Dest should stop being invaded by A5, C3Dest should be invaded by A5.
+ *
+ * Step 4. Invade A5 by B6. Move from C3 to C2 via transfer.
+ * C2Dest should be invaded by A and B.
+ * C3Dest should not be invaded.
+ *
+ * Step 5. Move A5 to A4.
+ * A4 should be invaded by B due to B6 but not by A.
+ * C2Dest should not be invaded.
*/
public void testMultiRepoTransferMove() throws Exception
{
@@ -5063,6 +5445,8 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
NodeRef C2NodeRef;
NodeRef C3NodeRef;
NodeRef A4NodeRef;
+ NodeRef A5NodeRef;
+ NodeRef B6NodeRef;
NodeRef C2DummyNodeRef;
NodeRef C3DummyNodeRef;
QName C2Path = QName.createQName("p2");
@@ -5148,10 +5532,18 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
{
// Node A4
- ChildAssociationRef child = nodeService.createNode(C2DummyNodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("C4"), ContentModel.TYPE_FOLDER);
+ ChildAssociationRef child = nodeService.createNode(A1NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("C4"), ContentModel.TYPE_FOLDER);
A4NodeRef = child.getChildRef();
- nodeService.setProperty(A4NodeRef, ContentModel.PROP_TITLE, "C4");
- nodeService.setProperty(A4NodeRef, ContentModel.PROP_NAME, "C4");
+ nodeService.setProperty(A4NodeRef, ContentModel.PROP_TITLE, "A4");
+ nodeService.setProperty(A4NodeRef, ContentModel.PROP_NAME, "A4");
+ }
+
+ {
+ // Node A5
+ ChildAssociationRef child = nodeService.createNode(C2DummyNodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A5"), ContentModel.TYPE_FOLDER);
+ A5NodeRef = child.getChildRef();
+ nodeService.setProperty(A5NodeRef, ContentModel.PROP_TITLE, "A5");
+ nodeService.setProperty(A5NodeRef, ContentModel.PROP_NAME, "A5");
}
// Create the transfer target if it does not already exist
@@ -5240,6 +5632,7 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
TransferDefinition definition = new TransferDefinition();
Collection nodes = new ArrayList();
nodes.add(A4NodeRef);
+ nodes.add(A5NodeRef);
definition.setNodes(nodes);
definition.setSync(true);
transferService.transfer(targetName, definition);
@@ -5252,14 +5645,17 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
startNewTransaction();
try
{
- assertTrue("dest node A4 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A4NodeRef)));
+ assertTrue("dest node A5 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A5NodeRef)));
assertTrue("dest node C3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(C3NodeRef)));
assertTrue("dest node C2 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(C2NodeRef)));
- // Check that A4 dest is a child of C2Dest which is a child of B1
- ChildAssociationRef A4Ref = nodeService.getPrimaryParent(testNodeFactory.getMappedNodeRef(A4NodeRef));
- assertEquals("A4 dest is connected to the wrong node", A4Ref.getParentRef(), testNodeFactory.getMappedNodeRef(C2NodeRef));
+ ChildAssociationRef A5Ref = nodeService.getPrimaryParent(testNodeFactory.getMappedNodeRef(A5NodeRef));
+ assertEquals("A5 dest is connected to the wrong node", A5Ref.getParentRef(), testNodeFactory.getMappedNodeRef(C2NodeRef));
assertTrue("C2 dest is not invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(C2NodeRef), TransferModel.ASPECT_ALIEN));
assertFalse("C3 dest is not invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(C3NodeRef), TransferModel.ASPECT_ALIEN));
+
+ ChildAssociationRef A4Ref = nodeService.getPrimaryParent(testNodeFactory.getMappedNodeRef(A4NodeRef));
+ assertEquals("A4 dest is connected to the wrong node", A4Ref.getParentRef(), B1NodeRef);
+
}
finally
{
@@ -5269,12 +5665,12 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
/**
* Step 3
* Now move A3
- * C2 (Dest) gets invaded by A4
+ * C2 (Dest) gets invaded by A5
*/
startNewTransaction();
try
{
- nodeService.moveNode(A4NodeRef, C3DummyNodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("C4"));
+ nodeService.moveNode(A5NodeRef, C3DummyNodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("C4"));
}
finally
{
@@ -5286,7 +5682,7 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
{
TransferDefinition definition = new TransferDefinition();
Collection nodes = new ArrayList();
- nodes.add(A4NodeRef);
+ nodes.add(A5NodeRef);
definition.setNodes(nodes);
definition.setSync(true);
transferService.transfer(targetName, definition);
@@ -5299,14 +5695,14 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
startNewTransaction();
try
{
- assertTrue("dest node A4 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A4NodeRef)));
+ assertTrue("dest node A5 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A5NodeRef)));
assertTrue("dest node C3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(C3NodeRef)));
assertTrue("dest node C2 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(C2NodeRef)));
// Check that A4 dest is a child of C3Dest which is a child of B1
- ChildAssociationRef A4Ref = nodeService.getPrimaryParent(testNodeFactory.getMappedNodeRef(A4NodeRef));
- assertEquals("A4 dest is connected to the wrong node", A4Ref.getParentRef(), testNodeFactory.getMappedNodeRef(C3NodeRef));
- assertTrue("A4 dest is not invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(A4NodeRef), TransferModel.ASPECT_ALIEN));
+ ChildAssociationRef A5Ref = nodeService.getPrimaryParent(testNodeFactory.getMappedNodeRef(A5NodeRef));
+ assertEquals("A5 dest is connected to the wrong node", A5Ref.getParentRef(), testNodeFactory.getMappedNodeRef(C3NodeRef));
+ assertTrue("A5 dest is not invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(A5NodeRef), TransferModel.ASPECT_ALIEN));
assertTrue("C3 dest is not invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(C3NodeRef), TransferModel.ASPECT_ALIEN));
assertFalse("C2 dest is still invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(C2NodeRef), TransferModel.ASPECT_ALIEN));
}
@@ -5314,17 +5710,122 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
{
endTransaction();
}
-
+
+ /**
+ * Step 4 - multi invasion move via transfer service.
+ * Invade A5 by B6. Transfer from C3 back to C2.
+ */
+ startNewTransaction();
+ try
+ {
+ nodeService.moveNode(A5NodeRef, C2DummyNodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("B6"));
+
+ // Node B5
+ ChildAssociationRef child = nodeService.createNode(testNodeFactory.getMappedNodeRef(A5NodeRef), ContentModel.ASSOC_CONTAINS, QName.createQName("B6"), ContentModel.TYPE_FOLDER);
+ B6NodeRef = child.getChildRef();
+ nodeService.setProperty(B6NodeRef, ContentModel.PROP_TITLE, "B6");
+ nodeService.setProperty(B6NodeRef, ContentModel.PROP_NAME, "B6");
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+ startNewTransaction();
+ try
+ {
+ TransferDefinition definition = new TransferDefinition();
+ Collection nodes = new ArrayList();
+ nodes.add(A5NodeRef);
+ definition.setNodes(nodes);
+ definition.setSync(true);
+ transferService.transfer(targetName, definition);
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+ startNewTransaction();
+ try
+ {
+ assertTrue("dest node A5 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A5NodeRef)));
+ assertTrue("dest node C3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(C3NodeRef)));
+ assertTrue("dest node C2 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(C2NodeRef)));
+
+ // Check that A4 dest is a child of C2Dest which is a child of B1
+ ChildAssociationRef A5Ref = nodeService.getPrimaryParent(testNodeFactory.getMappedNodeRef(A5NodeRef));
+ ChildAssociationRef B6Ref = nodeService.getPrimaryParent(B6NodeRef);
+ assertEquals("A5 dest is connected to the wrong node", A5Ref.getParentRef(), testNodeFactory.getMappedNodeRef(C2NodeRef));
+ assertEquals("B6 connected to the wrong node", B6Ref.getParentRef(), testNodeFactory.getMappedNodeRef(A5NodeRef));
+ assertTrue("A5 dest is not invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(A5NodeRef), TransferModel.ASPECT_ALIEN));
+ assertTrue("C2 dest is not invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(C2NodeRef), TransferModel.ASPECT_ALIEN));
+ assertFalse("C3 dest is still invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(C3NodeRef), TransferModel.ASPECT_ALIEN));
+ Listinvaders = (List)nodeService.getProperty(testNodeFactory.getMappedNodeRef(C2NodeRef), TransferModel.PROP_INVADED_BY);
+ assertTrue("invaders is too small", invaders.size() > 1);
+ assertTrue("invaders does not contain REPO A", invaders.contains(REPO_ID_A));
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+ /**
+ * Step 5
+ * Move
+ */
+ startNewTransaction();
+ try
+ {
+ nodeService.moveNode(A5NodeRef, A4NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A5"));
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+ startNewTransaction();
+ try
+ {
+ TransferDefinition definition = new TransferDefinition();
+ Collection nodes = new ArrayList();
+ nodes.add(A5NodeRef);
+ definition.setNodes(nodes);
+ definition.setSync(true);
+ transferService.transfer(targetName, definition);
+ }
+ finally
+ {
+ endTransaction();
+ }
+
+ startNewTransaction();
+ try
+ {
+ assertTrue("dest node A5 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A5NodeRef)));
+ assertTrue("dest node C3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(C3NodeRef)));
+ assertTrue("dest node C2 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(C2NodeRef)));
+
+ // Check that A5dest is a child of A4Dest which is a child of B1
+ ChildAssociationRef A5Ref = nodeService.getPrimaryParent(testNodeFactory.getMappedNodeRef(A5NodeRef));
+ assertEquals("A5 dest is connected to the wrong node", A5Ref.getParentRef(), testNodeFactory.getMappedNodeRef(A4NodeRef));
+ assertTrue("A4 dest is not invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(A4NodeRef), TransferModel.ASPECT_ALIEN));
+ assertTrue("A5 dest is not invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(A5NodeRef), TransferModel.ASPECT_ALIEN));
+ assertTrue("B6 dest is not invaded", nodeService.hasAspect(B6NodeRef, TransferModel.ASPECT_ALIEN));
+ assertFalse("C2 dest is still invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(C2NodeRef), TransferModel.ASPECT_ALIEN));
+ assertFalse("C3 dest is still invaded", nodeService.hasAspect(testNodeFactory.getMappedNodeRef(C3NodeRef), TransferModel.ASPECT_ALIEN));
+
+ Listinvaders = (List)nodeService.getProperty(testNodeFactory.getMappedNodeRef(A4NodeRef), TransferModel.PROP_INVADED_BY);
+ assertTrue("invaders is too big", invaders.size() < 2);
+ assertFalse("invaders contains REPO A", invaders.contains(REPO_ID_A));
+
+ }
+ finally
+ {
+ endTransaction();
+ }
}
- /**
- * transfer should only be able to update and delete nodes that are "from" the transferring system
- */
- public void testFromRepo()
- {
- assertTrue("not yet implemented", false);
- }
-
private void createUser(String userName, String password)
{
if (this.authenticationService.authenticationExists(userName) == false)