diff --git a/config/alfresco/model/transferModel.xml b/config/alfresco/model/transferModel.xml index 5b5c1199bb..fb24579531 100644 --- a/config/alfresco/model/transferModel.xml +++ b/config/alfresco/model/transferModel.xml @@ -186,6 +186,19 @@ + + + Nodes with this aspect are have been transferred from one repository to another + + + + Source RepositoryId + d:text + true + + + + diff --git a/source/java/org/alfresco/repo/transfer/RepoPrimaryManifestProcessorImpl.java b/source/java/org/alfresco/repo/transfer/RepoPrimaryManifestProcessorImpl.java index 195108cf49..483144c13b 100644 --- a/source/java/org/alfresco/repo/transfer/RepoPrimaryManifestProcessorImpl.java +++ b/source/java/org/alfresco/repo/transfer/RepoPrimaryManifestProcessorImpl.java @@ -51,6 +51,11 @@ import org.apache.commons.logging.LogFactory; /** * @author brian * + * The primary manifest processor is responsible for the first parsing the snapshot + * file and writing nodes into the receiving repository. + * + * New nodes may be written into a "temporary" space if their primary parent node + * has not yet been transferred. */ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorBase { @@ -76,7 +81,17 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB private ContentService contentService; private DictionaryService dictionaryService; private CorrespondingNodeResolver nodeResolver; + + // State within this class + /** + * The header of the manifest + */ + TransferManifestHeader header; + /** + * The list of orphans, during processing orphans are added and removed from this list. + * If at the end of processing there are still orphans then an exception will be thrown. + */ private Map> orphans = new HashMap>(89); /** @@ -276,6 +291,13 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB // Split out the content properties and sanitise the others Map contentProps = processProperties(null, props, true); + + // inject transferred property here + if(!contentProps.containsKey(TransferModel.PROP_REPOSITORY_ID)) + { + log.debug("injecting repositoryId property"); + props.put(TransferModel.PROP_REPOSITORY_ID, header.getRepositoryId()); + } // Create the corresponding node... ChildAssociationRef newNode = nodeService.createNode(parentNodeRef, parentAssocType, parentAssocName, node @@ -368,6 +390,13 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB // We need to process content properties separately. // First, create a shallow copy of the supplied property map... Map props = new HashMap(node.getProperties()); + + // inject transferred property here + if(!props.containsKey(TransferModel.PROP_REPOSITORY_ID)) + { + log.debug("injecting repositoryId property"); + props.put(TransferModel.PROP_REPOSITORY_ID, header.getRepositoryId()); + } // Split out the content properties and sanitise the others Map contentProps = processProperties(nodeToUpdate, props, false); @@ -391,6 +420,7 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB } aspectsToRemove.removeAll(suppliedAspects); + aspectsToRemove.remove(TransferModel.ASPECT_TRANSFERRED); suppliedAspects.removeAll(existingAspects); // Now aspectsToRemove contains the set of aspects to remove @@ -570,6 +600,8 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB protected void processHeader(TransferManifestHeader header) { + // squirrel away the header for later use + this.header = header; } /* diff --git a/source/java/org/alfresco/repo/transfer/RepoSecondaryManifestProcessorImpl.java b/source/java/org/alfresco/repo/transfer/RepoSecondaryManifestProcessorImpl.java index 69c899e622..2022c10f3c 100644 --- a/source/java/org/alfresco/repo/transfer/RepoSecondaryManifestProcessorImpl.java +++ b/source/java/org/alfresco/repo/transfer/RepoSecondaryManifestProcessorImpl.java @@ -38,6 +38,13 @@ import org.alfresco.service.namespace.RegexQNamePattern; /** * @author brian * + * The secondary manifest processor performs a second parse of the snapshot file. + * + * It is responsible for linking nodes together, moving them out of the temporary space + * into their final position in the repository. At the point that this processor runs both + * ends (source and target) of the nodes' associations should be available in the receiving + * repository. + * */ public class RepoSecondaryManifestProcessorImpl extends AbstractManifestProcessorBase { diff --git a/source/java/org/alfresco/repo/transfer/TransferModel.java b/source/java/org/alfresco/repo/transfer/TransferModel.java index 4484a58cfc..5901c24851 100644 --- a/source/java/org/alfresco/repo/transfer/TransferModel.java +++ b/source/java/org/alfresco/repo/transfer/TransferModel.java @@ -33,6 +33,12 @@ public interface TransferModel static final QName ASPECT_ENABLEABLE = QName.createQName(TRANSFER_MODEL_1_0_URI, "enableable"); // static final QName ASSOC_IMAP_ATTACHMENTS_FOLDER = QName.createQName(IMAP_MODEL_1_0_URI, "attachmentsFolder"); + /** + * Aspect : transferred + */ + static final QName ASPECT_TRANSFERRED = QName.createQName(TRANSFER_MODEL_1_0_URI, "transferred"); + static final QName PROP_REPOSITORY_ID = QName.createQName(TRANSFER_MODEL_1_0_URI, "repositoryId"); + /* * Type : Transfer Group */ diff --git a/source/java/org/alfresco/repo/transfer/TransferServiceImplTest.java b/source/java/org/alfresco/repo/transfer/TransferServiceImplTest.java index de04a2e078..4f913337b4 100644 --- a/source/java/org/alfresco/repo/transfer/TransferServiceImplTest.java +++ b/source/java/org/alfresco/repo/transfer/TransferServiceImplTest.java @@ -676,6 +676,10 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest assertEquals("title is wrong", (String)nodeService.getProperty(destNodeRef, ContentModel.PROP_TITLE), CONTENT_TITLE); assertEquals("type is wrong", nodeService.getType(contentNodeRef), nodeService.getType(destNodeRef)); + // Check injected transferred aspect. + assertNotNull("transferredAspect", (String)nodeService.getProperty(destNodeRef, TransferModel.PROP_REPOSITORY_ID)); + + // Now set up the next test which is to nodeService.setProperty(contentNodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE_UPDATED); } finally @@ -690,11 +694,11 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest * Transfer our node again - so this is an update */ { - TransferDefinition definition = new TransferDefinition(); - Setnodes = new HashSet(); - nodes.add(contentNodeRef); - definition.setNodes(nodes); - transferService.transfer(targetName, definition); + TransferDefinition definition = new TransferDefinition(); + Setnodes = new HashSet(); + nodes.add(contentNodeRef); + definition.setNodes(nodes); + transferService.transfer(targetName, definition); } } finally @@ -710,6 +714,10 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest assertTrue("dest node ref does not exist", nodeService.exists(destNodeRef)); assertEquals("title is wrong", (String)nodeService.getProperty(destNodeRef, ContentModel.PROP_TITLE), CONTENT_TITLE_UPDATED); assertEquals("type is wrong", nodeService.getType(contentNodeRef), nodeService.getType(destNodeRef)); + + // Check injected transferred aspect. + assertNotNull("transferredAspect", (String)nodeService.getProperty(destNodeRef, TransferModel.PROP_REPOSITORY_ID)); + } finally {