From 9e4ec6276f9a8abcdba25c92550e602919d7c57d Mon Sep 17 00:00:00 2001 From: David Caruana Date: Tue, 14 Sep 2010 14:59:12 +0000 Subject: [PATCH] Resolve ALF-4739 Transfer of an item with a rule defined against it (without its associated rule) causes data corruption on destination repository - transfer definition now allows aspects to be excluded from the transfer (setExcludedAspects) - manifest builder is sensitive to excluded aspects - replication definition excludes rule:rules for now git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@22513 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/transfer-service-context.xml | 1 + .../ReplicationActionExecutor.java | 14 +-- .../repo/transfer/TransferServiceImpl2.java | 2 +- .../UnitTestTransferManifestNodeFactory.java | 5 +- .../manifest/TransferManifestNodeFactory.java | 3 +- .../TransferManifestNodeFactoryImpl.java | 86 ++++++++++++++++--- .../cmr/transfer/TransferDefinition.java | 36 +++++++- 7 files changed, 123 insertions(+), 24 deletions(-) diff --git a/config/alfresco/transfer-service-context.xml b/config/alfresco/transfer-service-context.xml index 56c070fcea..496e687a4a 100644 --- a/config/alfresco/transfer-service-context.xml +++ b/config/alfresco/transfer-service-context.xml @@ -58,6 +58,7 @@ + toTransfer - ) { + ReplicationDefinition replicationDef, Set toTransfer) + { TransferDefinition transferDefinition = new TransferDefinition(); transferDefinition.setNodes(toTransfer); transferDefinition.setSync(true); transferDefinition.setReadOnly(true); + // Exclude aspects from transfer + // NOTE: this list of aspects should be synced up with the NodeCrawler in expandPayload to + // ensure a coherent set of nodes are transferred + transferDefinition.setExcludedAspects(RuleModel.ASPECT_RULES); + return transferDefinition; } @@ -209,10 +215,6 @@ public class ReplicationActionExecutor extends ActionExecuterAbstractBase { throw new ReplicationServiceException("Unable to execute a disabled replication definition"); } - // Clear the previous transfer report references -// replicationDef.setLocalTransferReport(null); -// replicationDef.setRemoteTransferReport(null); - // Lock the service - only one instance of the replication // should occur at a time ReplicationDefinitionLockExtender lock = diff --git a/source/java/org/alfresco/repo/transfer/TransferServiceImpl2.java b/source/java/org/alfresco/repo/transfer/TransferServiceImpl2.java index fd3917e7f0..049a2bc97a 100644 --- a/source/java/org/alfresco/repo/transfer/TransferServiceImpl2.java +++ b/source/java/org/alfresco/repo/transfer/TransferServiceImpl2.java @@ -909,7 +909,7 @@ public class TransferServiceImpl2 implements TransferService2 formatter.writeTransferManifestHeader(header); for(NodeRef nodeRef : nodes) { - TransferManifestNode node = transferManifestNodeFactory.createTransferManifestNode(nodeRef); + TransferManifestNode node = transferManifestNodeFactory.createTransferManifestNode(nodeRef, definition); formatter.writeTransferManifestNode(node); } formatter.endTransferManifest(); diff --git a/source/java/org/alfresco/repo/transfer/UnitTestTransferManifestNodeFactory.java b/source/java/org/alfresco/repo/transfer/UnitTestTransferManifestNodeFactory.java index e89a75e04c..adf60ba017 100644 --- a/source/java/org/alfresco/repo/transfer/UnitTestTransferManifestNodeFactory.java +++ b/source/java/org/alfresco/repo/transfer/UnitTestTransferManifestNodeFactory.java @@ -31,6 +31,7 @@ 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.Path; +import org.alfresco.service.cmr.transfer.TransferDefinition; import org.alfresco.service.namespace.QName; import org.alfresco.util.Pair; @@ -69,9 +70,9 @@ public class UnitTestTransferManifestNodeFactory implements TransferManifestNode this.realFactory = realFactory; } - public TransferManifestNode createTransferManifestNode(NodeRef nodeRef) + public TransferManifestNode createTransferManifestNode(NodeRef nodeRef, TransferDefinition definition) { - TransferManifestNode newNode = realFactory.createTransferManifestNode(nodeRef); + TransferManifestNode newNode = realFactory.createTransferManifestNode(nodeRef, definition); NodeRef origNodeRef = newNode.getNodeRef(); diff --git a/source/java/org/alfresco/repo/transfer/manifest/TransferManifestNodeFactory.java b/source/java/org/alfresco/repo/transfer/manifest/TransferManifestNodeFactory.java index e4ea7a46bf..f6fb950e21 100644 --- a/source/java/org/alfresco/repo/transfer/manifest/TransferManifestNodeFactory.java +++ b/source/java/org/alfresco/repo/transfer/manifest/TransferManifestNodeFactory.java @@ -19,8 +19,9 @@ package org.alfresco.repo.transfer.manifest; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.transfer.TransferDefinition; public interface TransferManifestNodeFactory { - TransferManifestNode createTransferManifestNode(NodeRef nodeRef); + TransferManifestNode createTransferManifestNode(NodeRef nodeRef, TransferDefinition definition); } diff --git a/source/java/org/alfresco/repo/transfer/manifest/TransferManifestNodeFactoryImpl.java b/source/java/org/alfresco/repo/transfer/manifest/TransferManifestNodeFactoryImpl.java index 59df1f7f7a..501b6df17b 100644 --- a/source/java/org/alfresco/repo/transfer/manifest/TransferManifestNodeFactoryImpl.java +++ b/source/java/org/alfresco/repo/transfer/manifest/TransferManifestNodeFactoryImpl.java @@ -18,11 +18,17 @@ */ package org.alfresco.repo.transfer.manifest; +import java.io.Serializable; import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import org.alfresco.model.ContentModel; +import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.alfresco.service.cmr.dictionary.PropertyDefinition; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; @@ -30,7 +36,9 @@ import org.alfresco.service.cmr.repository.Path; import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.security.AccessPermission; import org.alfresco.service.cmr.security.PermissionService; +import org.alfresco.service.cmr.transfer.TransferDefinition; import org.alfresco.service.cmr.transfer.TransferException; +import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.RegexQNamePattern; /** @@ -43,15 +51,16 @@ public class TransferManifestNodeFactoryImpl implements TransferManifestNodeFact { private NodeService nodeService; private PermissionService permissionService; + private DictionaryService dictionaryService; public void init() { } - public TransferManifestNode createTransferManifestNode(NodeRef nodeRef) + public TransferManifestNode createTransferManifestNode(NodeRef nodeRef, TransferDefinition definition) { - NodeRef.Status status = nodeService.getNodeStatus(nodeRef); + NodeRef.Status status = nodeService.getNodeStatus(nodeRef); if(status == null) { @@ -104,9 +113,9 @@ public class TransferManifestNodeFactoryImpl implements TransferManifestNodeFact TransferManifestNormalNode node = new TransferManifestNormalNode(); node.setNodeRef(nodeRef); - node.setProperties(nodeService.getProperties(nodeRef)); - node.setAspects(nodeService.getAspects(nodeRef)); - node.setType(nodeService.getType(nodeRef)); + node.setProperties(getNodeProperties(nodeRef, definition == null ? null : definition.getExcludedAspects())); + node.setAspects(getNodeAspects(nodeRef, definition == null ? null : definition.getExcludedAspects())); + node.setType(nodeService.getType(nodeRef)); ChildAssociationRef parentAssocRef = nodeService.getPrimaryParent(nodeRef); if(parentAssocRef != null && parentAssocRef.getParentRef() != null) { @@ -145,25 +154,76 @@ public class TransferManifestNodeFactoryImpl implements TransferManifestNodeFact return node; } } + + /** + * Gets the aspects of the specified node, minus those that have been explicitly excluded + * + * @param nodeRef node to get aspects for + * @param excludedAspects aspects to exluce + * @return set of aspects minus those excluded + */ + private Set getNodeAspects(NodeRef nodeRef, Set excludedAspects) + { + Set aspects = nodeService.getAspects(nodeRef); + if (excludedAspects == null || excludedAspects.size() == 0) + { + return aspects; + } + else + { + Set filteredAspects = new HashSet(aspects.size()); + for (QName aspect : aspects) + { + if (!excludedAspects.contains(aspect)) + { + filteredAspects.add(aspect); + } + } + return filteredAspects; + } + } + /** + * Gets the properties of the specified node, minus those that have been explicitly excluded + * + * @param nodeRef node to get aspects for + * @param excludedAspects aspects to exluce + * @return map of properties minus those excluded + */ + private Map getNodeProperties(NodeRef nodeRef, Set excludedAspects) + { + Map properties = nodeService.getProperties(nodeRef); + if (excludedAspects == null || excludedAspects.size() == 0) + { + return properties; + } + else + { + Map filteredProperties = new HashMap(properties.size()); + for (Map.Entry property : properties.entrySet()) + { + PropertyDefinition propDef = dictionaryService.getProperty(property.getKey()); + if (propDef == null || !excludedAspects.contains(propDef.getContainerClass().getName())) + { + filteredProperties.put(property.getKey(), property.getValue()); + } + } + return filteredProperties; + } + } public void setNodeService(NodeService nodeService) { this.nodeService = nodeService; } - public NodeService getNodeService() - { - return nodeService; - } - public void setPermissionService(PermissionService permissionService) { this.permissionService = permissionService; } - - public PermissionService getPermissionService() + + public void setDictionaryService(DictionaryService dictionaryService) { - return permissionService; + this.dictionaryService = dictionaryService; } } diff --git a/source/java/org/alfresco/service/cmr/transfer/TransferDefinition.java b/source/java/org/alfresco/service/cmr/transfer/TransferDefinition.java index 58302ed57d..ebbcb3d803 100644 --- a/source/java/org/alfresco/service/cmr/transfer/TransferDefinition.java +++ b/source/java/org/alfresco/service/cmr/transfer/TransferDefinition.java @@ -25,6 +25,7 @@ import java.util.HashSet; import java.util.Set; import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.QName; /** * Definition of what to transfer. @@ -47,6 +48,9 @@ public class TransferDefinition implements Serializable // Which nodes to deploy private Set nodes; + + // Which aspects to exclude + private Set excludedAspects; /** * isSync specifies whether the list of nodes is to be sync'ed. If sync then the transfer @@ -73,7 +77,7 @@ public class TransferDefinition implements Serializable public void setNodes(NodeRef...nodes) { - this.setNodes(new HashSet(Arrays.asList(nodes))); + this.setNodes(Arrays.asList(nodes)); } /** @@ -84,6 +88,36 @@ public class TransferDefinition implements Serializable { return nodes; } + + /** + * Sets which aspects to exclude from transfer + * + * @param exludedAspects collection of aspects to exclude + */ + public void setExcludedAspects(Collection exludedAspects) + { + this.excludedAspects = new HashSet(exludedAspects); + } + + /** + * Sets which aspects to exclude from transfer + * + * @param excludedAspects aspects to exclude from transfer + */ + public void setExcludedAspects(QName... excludedAspects) + { + this.setExcludedAspects(Arrays.asList(excludedAspects)); + } + + /** + * Gets the aspects to exclude from transfer + * + * @return set of excluded aspects (or null, if none specified) + */ + public Set getExcludedAspects() + { + return excludedAspects; + } /** * isSync specifies whether the list of nodes is to be sync'ed. If sync then the transfer