diff --git a/source/java/org/alfresco/repo/transfer/AbstractManifestProcessorBase.java b/source/java/org/alfresco/repo/transfer/AbstractManifestProcessorBase.java
index 6b01a8e6a6..40e0de4cc9 100644
--- a/source/java/org/alfresco/repo/transfer/AbstractManifestProcessorBase.java
+++ b/source/java/org/alfresco/repo/transfer/AbstractManifestProcessorBase.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2010 Alfresco Software Limited.
+ * Copyright (C) 2005-2015 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -19,9 +19,13 @@
package org.alfresco.repo.transfer;
import java.io.File;
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
import javax.transaction.UserTransaction;
+import org.alfresco.model.ContentModel;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transfer.manifest.TransferManifestDeletedNode;
import org.alfresco.repo.transfer.manifest.TransferManifestHeader;
@@ -30,6 +34,7 @@ import org.alfresco.repo.transfer.manifest.TransferManifestNormalNode;
import org.alfresco.repo.transfer.manifest.TransferManifestProcessor;
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.TransferException;
import org.alfresco.service.cmr.transfer.TransferProgress;
import org.alfresco.service.cmr.transfer.TransferReceiver;
@@ -270,4 +275,40 @@ public abstract class AbstractManifestProcessorBase implements TransferManifestP
{
receiver.getProgressMonitor().logMoved(transferId, sourceNode, destNode, oldPath, newParent, newPath);
}
+
+ /**
+ * Puts information about current childRef
and its parentRef
into log in TRACE level. Information includes 'name', 'fromRepositoryId', 'aliened' and
+ * 'invadedBy' properties. Additionally, collects the same information for children of childRef
+ *
+ * @param parentRef - {@link NodeRef} instance of child node
+ * @param childRef - {@link NodeRef} instance of parent of the childRef
+ * @param nodeService - {@link NodeService} instance to get properties and checking other states
+ * @param log - {@link Log} instance to put log for appropriate class
+ */
+ protected void logInvasionHierarchy(NodeRef parentRef, NodeRef childRef, NodeService nodeService, Log log)
+ {
+ Map properties = nodeService.getProperties(childRef);
+ Map parentProperties = nodeService.getProperties(parentRef);
+ StringBuilder message = new StringBuilder("Information about '").append(properties.get(ContentModel.PROP_NAME)).append("' node:\n fromRepositoryId: ").append(
+ properties.get(TransferModel.PROP_FROM_REPOSITORY_ID)).append("\n").append(" invadedBy: ").append(properties.get(TransferModel.PROP_INVADED_BY)).append("\n")
+ .append(" alien: ").append(nodeService.hasAspect(childRef, TransferModel.ASPECT_ALIEN)).append("\n").append(" repositoryId: ").append(
+ properties.get(TransferModel.PROP_REPOSITORY_ID)).append("\n").append(" parent: ").append(parentProperties.get(ContentModel.PROP_NAME)).append("(")
+ .append(parentProperties.get(TransferModel.PROP_FROM_REPOSITORY_ID)).append(")").append(parentProperties.get(TransferModel.PROP_INVADED_BY)).append(": ").append(
+ nodeService.hasAspect(parentRef, TransferModel.ASPECT_ALIEN)).append("\n").append(" children:\n");
+
+ List childAssocs = nodeService.getChildAssocs(childRef);
+
+ if ((null != childAssocs) && !childAssocs.isEmpty())
+ {
+ for (ChildAssociationRef child : childAssocs)
+ {
+ properties = nodeService.getProperties(child.getChildRef());
+ message.append(" ").append(properties.get(ContentModel.PROP_NAME)).append("(").append(properties.get(TransferModel.PROP_FROM_REPOSITORY_ID)).append(")")
+ .append(properties.get(TransferModel.PROP_INVADED_BY)).append(": ").append(nodeService.hasAspect(child.getChildRef(), TransferModel.ASPECT_ALIEN)).append(
+ "\n");
+ }
+ }
+
+ log.trace(message.toString());
+ }
}
diff --git a/source/java/org/alfresco/repo/transfer/AlienProcessorImpl.java b/source/java/org/alfresco/repo/transfer/AlienProcessorImpl.java
index 4f859ff19b..d422835977 100644
--- a/source/java/org/alfresco/repo/transfer/AlienProcessorImpl.java
+++ b/source/java/org/alfresco/repo/transfer/AlienProcessorImpl.java
@@ -1,3 +1,21 @@
+/*
+ * Copyright (C) 2005-2015 Alfresco Software Limited.
+ *
+ * This file is part of Alfresco
+ *
+ * Alfresco is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Alfresco is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Alfresco. If not, see .
+ */
package org.alfresco.repo.transfer;
import java.io.Serializable;
@@ -5,14 +23,12 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Stack;
import java.util.Vector;
import org.alfresco.model.ContentModel;
-import org.alfresco.repo.node.NodeServicePolicies;
import org.alfresco.repo.policy.BehaviourFilter;
-import org.alfresco.repo.policy.JavaBehaviour;
-import org.alfresco.repo.policy.Behaviour.NotificationFrequency;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.service.cmr.dictionary.DictionaryService;
@@ -148,7 +164,46 @@ public class AlienProcessorImpl implements AlienProcessor
currentAssoc = null;
}
}
- }
+
+ if (log.isTraceEnabled())
+ {
+ logInvasionHierarchy(childAssocRef.getParentRef(), childAssocRef.getChildRef());
+ }
+ }
+
+ /**
+ * Puts information about current childRef
and its parentRef
into log in TRACE level. Information includes 'name', 'fromRepositoryId', 'aliened' and
+ * 'invadedBy' properties. Additionally, collects the same information for children of childRef
+ *
+ * @param parentRef - {@link NodeRef} instance of child node
+ * @param childRef - {@link NodeRef} instance of parent of the childRef
+ */
+ protected void logInvasionHierarchy(NodeRef parentRef, NodeRef childRef)
+ {
+ Map properties = nodeService.getProperties(childRef);
+ Map parentProperties = nodeService.getProperties(parentRef);
+ StringBuilder message = new StringBuilder("Information about '").append(properties.get(ContentModel.PROP_NAME)).append("' node:\n fromRepositoryId: ").append(
+ properties.get(TransferModel.PROP_FROM_REPOSITORY_ID)).append("\n").append(" invadedBy: ").append(properties.get(TransferModel.PROP_INVADED_BY)).append("\n")
+ .append(" alien: ").append(nodeService.hasAspect(childRef, TransferModel.ASPECT_ALIEN)).append("\n").append(" repositoryId: ").append(
+ properties.get(TransferModel.PROP_REPOSITORY_ID)).append("\n").append(" parent: ").append(parentProperties.get(ContentModel.PROP_NAME)).append("(")
+ .append(parentProperties.get(TransferModel.PROP_FROM_REPOSITORY_ID)).append(")").append(parentProperties.get(TransferModel.PROP_INVADED_BY)).append(": ").append(
+ nodeService.hasAspect(parentRef, TransferModel.ASPECT_ALIEN)).append("\n").append(" children:\n");
+
+ List childAssocs = nodeService.getChildAssocs(childRef);
+
+ if ((null != childAssocs) && !childAssocs.isEmpty())
+ {
+ for (ChildAssociationRef child : childAssocs)
+ {
+ properties = nodeService.getProperties(child.getChildRef());
+ message.append(" ").append(properties.get(ContentModel.PROP_NAME)).append("(").append(properties.get(TransferModel.PROP_FROM_REPOSITORY_ID)).append(")")
+ .append(properties.get(TransferModel.PROP_INVADED_BY)).append(": ").append(nodeService.hasAspect(child.getChildRef(), TransferModel.ASPECT_ALIEN)).append(
+ "\n");
+ }
+ }
+
+ log.trace(message.toString());
+ }
public void beforeDeleteAlien(NodeRef deletedNodeRef, ChildAssociationRef oldAssoc)
{
@@ -540,7 +595,7 @@ public class AlienProcessorImpl implements AlienProcessor
ChildAssociationRef startingParent = nodeService.getPrimaryParent(nodeToPrune);
Stack foldersToRecalculate = new Stack();
-
+
/**
* Now go and do the pruning.
*/
@@ -554,25 +609,72 @@ public class AlienProcessorImpl implements AlienProcessor
* if from the repo with multiple alien invasions - leave alone but process children
*/
NodeRef currentNodeRef = nodesToPrune.pop();
-
+
+ Map properties = null;
+ if (log.isDebugEnabled())
+ {
+ properties = nodeService.getProperties(currentNodeRef);
+ }
+
+ if (log.isDebugEnabled())
+ {
+ log.debug("Current nodeRef (name: \"" + properties.get(ContentModel.PROP_NAME) + "\", fromRepositoryId: \"" + properties.get(TransferModel.PROP_FROM_REPOSITORY_ID)
+ + "\", manifestId: \"" + fromRepositoryId + "\")" + currentNodeRef);
+ }
+
log.debug("pruneNode:" + currentNodeRef);
-
+
if(getNodeService().hasAspect(currentNodeRef, TransferModel.ASPECT_ALIEN))
{
- // Yes this is an alien node
- ListinvadedBy = (List)getNodeService().getProperty(currentNodeRef, TransferModel.PROP_INVADED_BY);
- if(invadedBy.contains(fromRepositoryId))
+ if (log.isDebugEnabled())
{
- // Yes we are invaded by fromRepositoryId
- if(invadedBy.size() == 1)
+ log.debug("Current nodeRef has ASPECT_ALIEN (name: \"" + properties.get(ContentModel.PROP_NAME) + "\", fromRepositoryId: \""
+ + properties.get(TransferModel.PROP_FROM_REPOSITORY_ID) + "\", manifestId: \"" + fromRepositoryId + "\")");
+ }
+
+ // Yes this is an alien node
+ List invadedBy = (List)getNodeService().getProperty(currentNodeRef, TransferModel.PROP_INVADED_BY);
+ String initialRepoId = (String) getNodeService().getProperty(currentNodeRef, TransferModel.PROP_FROM_REPOSITORY_ID);
+
+ if (log.isDebugEnabled())
+ {
+ log.debug("Current nodeRef has PROP_INVADED_BY (name: \"" + properties.get(ContentModel.PROP_NAME) + "\", fromRepositoryId: \""
+ + properties.get(TransferModel.PROP_FROM_REPOSITORY_ID) + "\", manifestId: \"" + fromRepositoryId + "\"): " + invadedBy);
+ }
+
+ if ((null != invadedBy) && invadedBy.contains(fromRepositoryId))
+ {
+ if (log.isDebugEnabled())
{
+ log.debug("Current nodeRef's PROP_INVADED_BY contains current manifestId (name: \"" + properties.get(ContentModel.PROP_NAME) + "\", fromRepositoryId: \""
+ + properties.get(TransferModel.PROP_FROM_REPOSITORY_ID) + "\", manifestId: \"" + fromRepositoryId + "\")");
+ }
+
+ // Yes we are invaded by fromRepositoryId
+ if ((1 == invadedBy.size()) && fromRepositoryId.equalsIgnoreCase(initialRepoId))
+ {
+ if (log.isDebugEnabled())
+ {
+ log
+ .debug("Current nodeRef has only 1 element in PROP_INVADED_BY. Also MANIFEST_ID and INITIAL_REPOSITORY_ID are the same. Deleting the node... (name: \""
+ + properties.get(ContentModel.PROP_NAME)
+ + "\", fromRepositoryId: \""
+ + properties.get(TransferModel.PROP_FROM_REPOSITORY_ID)
+ + "\", manifestId: \"" + fromRepositoryId + "\")");
+ }
+
// we are invaded by a single repository which must be fromRepositoryId
- log.debug("pruned - deleted node:" + currentNodeRef);
getNodeService().deleteNode(currentNodeRef);
}
else
{
- log.debug("folder has multiple invaders");
+ if (log.isDebugEnabled())
+ {
+ log.debug("Current 'nodeRef' has more than 1 element in PROP_INVADED_BY. Adding its children to 'nodesToPrune' list... (name: \""
+ + properties.get(ContentModel.PROP_NAME) + "\", fromRepositoryId: \"" + properties.get(TransferModel.PROP_FROM_REPOSITORY_ID)
+ + "\", manifestId: \"" + fromRepositoryId + "\")");
+ }
+
// multiple invasion - so it must be a folder
List refs = nodeService.getChildAssocsByPropertyValue(currentNodeRef, TransferModel.PROP_INVADED_BY, fromRepositoryId);
for(ChildAssociationRef ref : refs)
@@ -589,12 +691,24 @@ public class AlienProcessorImpl implements AlienProcessor
*/
if(!foldersToRecalculate.contains(currentNodeRef))
{
+ if (log.isDebugEnabled())
+ {
+ log.debug("Current 'nodeRef' is not in 'foldersToRecalculate' list. Adding it to the list... (name: \"" + properties.get(ContentModel.PROP_NAME)
+ + "\", fromRepositoryId: \"" + properties.get(TransferModel.PROP_FROM_REPOSITORY_ID) + "\", manifestId: \"" + fromRepositoryId + "\")");
+ }
+
foldersToRecalculate.push(currentNodeRef);
}
}
}
else
{
+ if (log.isDebugEnabled())
+ {
+ log.debug("Current \"nodeRef\"'s PROP_INVADED_BY does not contain current 'manifestId' (name: \"" + properties.get(ContentModel.PROP_NAME)
+ + "\", fromRepositoryId: \"" + properties.get(TransferModel.PROP_FROM_REPOSITORY_ID) + "\", manifestId: \"" + fromRepositoryId + "\")");
+ }
+
/**
* Current node has been invaded by another repository
*
@@ -602,10 +716,15 @@ public class AlienProcessorImpl implements AlienProcessor
*/
getNodeService().hasAspect(currentNodeRef, TransferModel.ASPECT_TRANSFERRED);
{
- String fromRepoId = (String)getNodeService().getProperty(currentNodeRef, TransferModel.PROP_FROM_REPOSITORY_ID);
- if(fromRepositoryId.equalsIgnoreCase(fromRepoId))
+ if(fromRepositoryId.equalsIgnoreCase(initialRepoId))
{
- log.debug("folder is from the transferring repository");
+ if (log.isDebugEnabled())
+ {
+ log.debug("folder is from the transferring repository");
+ log.debug("Current nodeRef has more than 1 element in PROP_INVADED_BY. Adding its children to 'nodesToPrune' list... (name: \""
+ + properties.get(ContentModel.PROP_NAME) + "\", fromRepositoryId: \"" + properties.get(TransferModel.PROP_FROM_REPOSITORY_ID)
+ + "\", manifestId: \"" + fromRepositoryId + "\")");
+ }
// invaded from somewhere else - so it must be a folder
List refs = getNodeService().getChildAssocs(currentNodeRef);
for(ChildAssociationRef ref : refs)
@@ -621,6 +740,13 @@ public class AlienProcessorImpl implements AlienProcessor
*/
if(!foldersToRecalculate.contains(currentNodeRef))
{
+ if (log.isDebugEnabled())
+ {
+ log.debug("Current 'nodeRef' is not in 'foldersToRecalculate' list. Adding it to the list... (name: \""
+ + properties.get(ContentModel.PROP_NAME) + "\", fromRepositoryId: \"" + properties.get(TransferModel.PROP_FROM_REPOSITORY_ID)
+ + "\", manifestId: \"" + fromRepositoryId + "\")");
+ }
+
foldersToRecalculate.push(currentNodeRef);
}
}
@@ -633,11 +759,24 @@ public class AlienProcessorImpl implements AlienProcessor
// Current node does not contain alien nodes so it can be deleted.
getNodeService().hasAspect(currentNodeRef, TransferModel.ASPECT_TRANSFERRED);
{
- String fromRepoId = (String)getNodeService().getProperty(currentNodeRef, TransferModel.PROP_FROM_REPOSITORY_ID);
- if(fromRepositoryId.equalsIgnoreCase(fromRepoId))
+ if (log.isDebugEnabled())
{
- // we are invaded by a single repository
- log.debug("pruned - deleted non alien node:" + currentNodeRef);
+ log.debug("Current 'nodeRef' does not have ASPECT_ALIEN (name: \"" + properties.get(ContentModel.PROP_NAME) + "\", fromRepositoryId: \""
+ + properties.get(TransferModel.PROP_FROM_REPOSITORY_ID) + "\", manifestId: \"" + fromRepositoryId + "\")");
+ }
+
+ String initialRepoId = (String) getNodeService().getProperty(currentNodeRef, TransferModel.PROP_REPOSITORY_ID);
+ if(fromRepositoryId.equalsIgnoreCase(initialRepoId))
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("Current \"nodeRef\"'s has PROP_FROM_REPOSITORY_ID equal to current 'manifestId'. Deleting the node... (name: \""
+ + properties.get(ContentModel.PROP_NAME) + "\", fromRepositoryId: \"" + properties.get(TransferModel.PROP_FROM_REPOSITORY_ID)
+ + "\", manifestId: \"" + fromRepositoryId + "\")");
+ // we are invaded by a single repository
+ log.debug("pruned - deleted non alien node:" + currentNodeRef);
+ }
+
getNodeService().deleteNode(currentNodeRef);
}
}
@@ -745,44 +884,97 @@ public class AlienProcessorImpl implements AlienProcessor
*/
private boolean recalcInvasion(NodeRef folderNodeRef, String fromRepositoryId)
{
- ListfolderInvadedBy = (List)nodeService.getProperty(folderNodeRef, TransferModel.PROP_INVADED_BY);
-
+ if (log.isTraceEnabled())
+ {
+ log.trace("#################");
+ log.trace("#RECALC INVASION#");
+ log.trace("#################");
+ }
+
+ List folderInvadedBy = (List)nodeService.getProperty(folderNodeRef, TransferModel.PROP_INVADED_BY);
+
+ if (log.isDebugEnabled())
+ {
+ log.debug("Node(" + nodeService.getProperty(folderNodeRef, ContentModel.PROP_NAME) + ")" + folderInvadedBy + ": checking '" + fromRepositoryId + "' id...");
+ }
+
boolean stillInvaded = false;
-
+ boolean hasAlienChild = false;
+
//TODO need a more efficient query here
List refs = nodeService.getChildAssocs(folderNodeRef);
- for(ChildAssociationRef ref : refs)
+
+ if (log.isDebugEnabled())
+ {
+ log.debug("Children count: " + refs.size());
+ log.debug("Is alien: " + nodeService.hasAspect(folderNodeRef, TransferModel.ASPECT_ALIEN));
+ }
+
+ String parentRepositoryId = (String) nodeService.getProperty(folderNodeRef, TransferModel.PROP_FROM_REPOSITORY_ID);
+ for (ChildAssociationRef ref : refs)
{
NodeRef childNode = ref.getChildRef();
- ListchildInvadedBy = (List)getNodeService().getProperty(childNode, TransferModel.PROP_INVADED_BY);
-
- if(childInvadedBy != null && childInvadedBy.contains(fromRepositoryId))
+
+ if (log.isTraceEnabled())
{
- log.debug("folder is still invaded");
+ logInvasionHierarchy(folderNodeRef, childNode);
+ }
+
+ Map properties = nodeService.getProperties(childNode);
+ List childInvadedBy = (List) properties.get(TransferModel.PROP_INVADED_BY);
+ String childRepositoryId = (String) properties.get(TransferModel.PROP_FROM_REPOSITORY_ID);
+
+ hasAlienChild = hasAlienChild || parentRepositoryId.equalsIgnoreCase(childRepositoryId);
+
+ if (!stillInvaded && (null != childInvadedBy) && (childInvadedBy.contains(fromRepositoryId) || fromRepositoryId.equalsIgnoreCase(childRepositoryId)))
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("This child contains current 'fromRepositoryId'. Current folder is still invaded by this repository");
+ }
+
stillInvaded = true;
- break;
}
}
-
- if(!stillInvaded)
+
+ if (!stillInvaded)
{
- log.debug("folder is no longer invaded by this repo:" + folderNodeRef);
- folderInvadedBy.remove(fromRepositoryId);
- if(folderInvadedBy.size() > 0)
+ if (log.isDebugEnabled())
{
- if(log.isDebugEnabled())
+ log.debug("Current folder is not invaded by this repository. Updating 'invadedBy' property...");
+ log.debug("folder is no longer invaded by this repo:" + folderNodeRef);
+ }
+
+ folderInvadedBy.remove(fromRepositoryId);
+ if (folderInvadedBy.size() > 0)
+ {
+ if (log.isDebugEnabled())
{
+ log.debug("Current folder HAS ANOTHER invasions. Updating the 'invadedBy' property...");
log.debug("still invaded by:" + folderInvadedBy);
}
- getNodeService().setProperty(folderNodeRef, TransferModel.PROP_INVADED_BY, (Serializable)folderInvadedBy);
+
+ getNodeService().setProperty(folderNodeRef, TransferModel.PROP_INVADED_BY, (Serializable) folderInvadedBy);
}
- else
+ else if (!hasAlienChild)
{
- log.debug("no longer alien:" + folderNodeRef);
+ if (log.isDebugEnabled())
+ {
+ log.debug("no longer alien:" + folderNodeRef);
+ log.debug("This invasion was the last one for the current folder. Removing aspect 'ALIEN' completely...");
+ }
+
getNodeService().removeAspect(folderNodeRef, TransferModel.ASPECT_ALIEN);
}
}
-
+
+ if (log.isTraceEnabled())
+ {
+ log.trace("#################");
+ log.trace("# COMPLETED #");
+ log.trace("#################");
+ }
+
return stillInvaded;
}
diff --git a/source/java/org/alfresco/repo/transfer/RepoPrimaryManifestProcessorImpl.java b/source/java/org/alfresco/repo/transfer/RepoPrimaryManifestProcessorImpl.java
index 281bbcd52b..186f7f6561 100644
--- a/source/java/org/alfresco/repo/transfer/RepoPrimaryManifestProcessorImpl.java
+++ b/source/java/org/alfresco/repo/transfer/RepoPrimaryManifestProcessorImpl.java
@@ -215,6 +215,12 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
// Does a corresponding node exist in this repo?
if (resolvedNodes.resolvedChild != null)
{
+ if (log.isTraceEnabled())
+ {
+ log.trace("REPO_PRIMARY_MANIFEST_PROCESSOR - node DOES exist!");
+ logInvasionHierarchy(resolvedNodes.resolvedParent, resolvedNodes.resolvedChild, nodeService, log);
+ }
+
// Yes, the corresponding node does exist. Update it.
if (log.isDebugEnabled())
{
@@ -222,6 +228,11 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
+ resolvedNodes.resolvedChild);
}
update(node, resolvedNodes, primaryParentAssoc);
+
+ if (log.isTraceEnabled())
+ {
+ log.trace("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
+ }
}
else
{
@@ -245,7 +256,19 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
{
log.debug("Incoming noderef has no corresponding local noderef: " + node.getNodeRef());
}
+
+ if (log.isTraceEnabled())
+ {
+ log.trace("REPO_PRIMARY_MANIFEST_PROCESSOR - node DOES NOT esist yet! Name: '" + node.getProperties().get(ContentModel.PROP_NAME) + "', parentPath: '"
+ + node.getParentPath() + "'");
+ }
+
create(node, resolvedNodes, primaryParentAssoc);
+
+ if (log.isTraceEnabled())
+ {
+ log.trace("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
+ }
}
}
diff --git a/source/java/org/alfresco/repo/transfer/RepoTertiaryManifestProcessorImpl.java b/source/java/org/alfresco/repo/transfer/RepoTertiaryManifestProcessorImpl.java
index eb953263f6..0bc435503b 100644
--- a/source/java/org/alfresco/repo/transfer/RepoTertiaryManifestProcessorImpl.java
+++ b/source/java/org/alfresco/repo/transfer/RepoTertiaryManifestProcessorImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2010 Alfresco Software Limited.
+ * Copyright (C) 2009-2015 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -16,18 +16,21 @@
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see .
*/
-
package org.alfresco.repo.transfer;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
+import org.alfresco.repo.transfer.CorrespondingNodeResolver.ResolvedParentChildPair;
import org.alfresco.repo.transfer.manifest.TransferManifestDeletedNode;
import org.alfresco.repo.transfer.manifest.TransferManifestHeader;
import org.alfresco.repo.transfer.manifest.TransferManifestNormalNode;
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.repository.Path;
import org.alfresco.service.cmr.transfer.TransferReceiver;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -102,16 +105,90 @@ public class RepoTertiaryManifestProcessorImpl extends AbstractManifestProcessor
//TODO Use more efficient query here.
List expectedChildren = node.getChildAssocs();
-
+
+ if (log.isDebugEnabled())
+ {
+ log.debug("Checking node in TERTIARY_MANIFEST_PROCESSOR");
+ }
+
+ if ((null != resolvedNodes.resolvedParent) && nodeService.exists(resolvedNodes.resolvedParent))
+ {
+ if (log.isTraceEnabled())
+ {
+ logInvasionHierarchy(resolvedNodes.resolvedParent, nodeRef, nodeService, log);
+ }
+ }
+ else
+ {
+ List parentAssocs = nodeService.getParentAssocs(nodeRef);
+
+ if (log.isTraceEnabled())
+ {
+ logInvasionHierarchy(parentAssocs.iterator().next().getParentRef(), nodeRef, nodeService, log);
+ }
+ }
+
List expectedChildNodeRefs = new ArrayList();
-
+ Set expectedChildNodePaths = new HashSet();
+
+ if (log.isDebugEnabled())
+ {
+ log.debug("Expected children:");
+ }
+
for(ChildAssociationRef ref : expectedChildren)
{
if(log.isDebugEnabled())
{
- log.debug("expecting child node" + ref);
+ log.debug("Expecting child node " + ref);
+ }
+
+ NodeRef childRef = null;
+ if (nodeService.exists(ref.getChildRef()))
+ {
+ childRef = ref.getChildRef();
+
+ if (log.isTraceEnabled())
+ {
+ logInvasionHierarchy(nodeRef, ref.getChildRef(), nodeService, log);
+ }
+ }
+ else
+ {
+ Path parentPath = node.getParentPath();
+ parentPath = parentPath.subPath(0, (parentPath.size() - 1));
+ parentPath.append(new Path.ChildAssocElement(ref));
+ ResolvedParentChildPair resolvedChild = nodeResolver.resolveCorrespondingNode(ref.getChildRef(), ref, parentPath);
+
+ if (null != resolvedChild.resolvedChild)
+ {
+ childRef = resolvedChild.resolvedChild;
+
+ if (log.isDebugEnabled())
+ {
+ log.debug("The node has been RESOLVED!");
+ }
+
+ if (log.isTraceEnabled())
+ {
+ logInvasionHierarchy(resolvedChild.resolvedParent, resolvedChild.resolvedChild, nodeService, log);
+ }
+ }
+ else
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("The node DOES NOT exist in current repository! Processing will be made by its PATH!");
+ }
+
+ expectedChildNodePaths.add(parentPath);
+ }
+ }
+
+ if (null != childRef)
+ {
+ expectedChildNodeRefs.add(childRef);
}
- expectedChildNodeRefs.add(ref.getChildRef());
}
List actualChildren = nodeService.getChildAssocs(nodeRef);
@@ -119,19 +196,35 @@ public class RepoTertiaryManifestProcessorImpl extends AbstractManifestProcessor
/**
* For each actual child association
*/
+ if (log.isDebugEnabled())
+ {
+ log.debug("Traversing ACTUAL children:");
+ }
+
for(ChildAssociationRef child : actualChildren)
{
log.debug("checking child: " + child);
if(child.isPrimary())
{
+ if (log.isTraceEnabled())
+ {
+ logInvasionHierarchy(child.getParentRef(), child.getChildRef(), nodeService, log);
+ }
+
/**
* yes it is a primary assoc
* should it be there ?
*/
NodeRef childNodeRef = child.getChildRef();
-
- if(!expectedChildNodeRefs.contains(childNodeRef))
+ Path actualChildPath = nodeService.getPath(childNodeRef);
+
+ if(!expectedChildNodeRefs.contains(childNodeRef) && !expectedChildNodePaths.contains(actualChildPath))
{
+ if (log.isDebugEnabled())
+ {
+ log.debug("This child IS NOT EXPECTED!");
+ }
+
/**
* An unexpected child - if this node has been transferred then
* it may need to be deleted.
@@ -143,10 +236,16 @@ public class RepoTertiaryManifestProcessorImpl extends AbstractManifestProcessor
{
log.debug("an unexpected transferred child node:" + child);
logComment("Transfer sync mode - checking unexpected child node:" + child);
- String fromRepositoryId = (String)nodeService.getProperty(childNodeRef, TransferModel.PROP_FROM_REPOSITORY_ID);
+ 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 (log.isDebugEnabled())
+ {
+ log.debug("'manifestRepositoryId': " + manifestRepositoryId);
+ }
+
if(fromRepositoryId != null && manifestRepositoryId != null)
{
if(nodeService.hasAspect(childNodeRef, TransferModel.ASPECT_ALIEN))
@@ -157,19 +256,36 @@ public class RepoTertiaryManifestProcessorImpl extends AbstractManifestProcessor
*/
log.debug("node to be deleted contains alien content so needs to be pruned." + childNodeRef);
logComment("Transfer sync mode - node contains alien content so can't be deleted. " + childNodeRef);
- alienProcessor.pruneNode(childNodeRef, fromRepositoryId);
+ alienProcessor.pruneNode(childNodeRef, manifestRepositoryId);
}
else
{
- // Node
- log.debug("node not alien");
- if(manifestRepositoryId.equalsIgnoreCase(fromRepositoryId))
+ // Node
+ if (log.isDebugEnabled())
{
+ log.debug("Node not alien. Trying to delete the node...");
+ }
+
+ String initialRepositoryId = (String) nodeService.getProperty(childNodeRef, TransferModel.PROP_FROM_REPOSITORY_ID);
+
+ if(manifestRepositoryId.equalsIgnoreCase(initialRepositoryId))
+ {
+ if (log.isDebugEnabled())
+ {
+ log.debug("Replication is initiated from the same repository from which this node was transferred! Deleting");
+ }
// Yes the manifest repository Id and the from repository Id match.
// Destination node if from the transferring repo and needs to be deleted.
logDeleted(node.getNodeRef(), childNodeRef, nodeService.getPath(childNodeRef).toString());
nodeService.deleteNode(childNodeRef);
- log.debug("deleted node:" + childNodeRef);
+ }
+ else
+ {
+ if (log.isDebugEnabled())
+ {
+ log
+ .debug("It is not an alien, but 'fromRepositoryId' is not equal to the 'manifestRepositoryId'! Cannot delete the foreign node...");
+ }
}
}
}