transfer service : first cut of transfer "sync" and unit test.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@20941 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Mark Rogers
2010-07-05 14:18:03 +00:00
parent b59b9604e9
commit 7969f7fca9
9 changed files with 765 additions and 29 deletions

View File

@@ -61,6 +61,11 @@ public class DefaultManifestProcessorFactoryImpl implements ManifestProcessorFac
secondaryProcessor.setNodeService(nodeService); secondaryProcessor.setNodeService(nodeService);
processors.add(secondaryProcessor); processors.add(secondaryProcessor);
RepoTertiaryManifestProcessorImpl tertiaryProcessor = new RepoTertiaryManifestProcessorImpl(receiver, transferId);
tertiaryProcessor.setNodeResolver(nodeResolver);
tertiaryProcessor.setNodeService(nodeService);
processors.add(tertiaryProcessor);
return processors; return processors;
} }

View File

@@ -0,0 +1,179 @@
/*
* Copyright (C) 2009-2010 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 <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.transfer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.repo.transfer.manifest.TransferManifestDeletedNode;
import org.alfresco.repo.transfer.manifest.TransferManifestHeader;
import org.alfresco.repo.transfer.manifest.TransferManifestNodeHelper;
import org.alfresco.repo.transfer.manifest.TransferManifestNormalNode;
import org.alfresco.service.cmr.repository.AssociationRef;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.transfer.TransferReceiver;
import org.alfresco.service.namespace.RegexQNamePattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* @author mrogers
*
* The tertiary manifest processor performs a third parse of the snapshot file.
*
* For a complete transfer it is responsible for deleting any replicated nodes
* which exist in the target repository that do not exist in the source repository.
*
* If the transfer is not "complete" then this processor does nothing.
*
*/
public class RepoTertiaryManifestProcessorImpl extends AbstractManifestProcessorBase
{
private NodeService nodeService;
private CorrespondingNodeResolver nodeResolver;
private static final Log log = LogFactory.getLog(RepoTertiaryManifestProcessorImpl.class);
/**
* Is this a "complete" transfer. If not then does nothing.
*/
boolean isComplete = false;
/**
* @param receiver
* @param transferId
*/
public RepoTertiaryManifestProcessorImpl(TransferReceiver receiver, String transferId)
{
super(receiver, transferId);
}
protected void endManifest()
{
//NOOP
}
protected void processNode(TransferManifestDeletedNode node)
{
//NOOP
}
protected void processNode(TransferManifestNormalNode node)
{
NodeRef nodeRef = node.getNodeRef();
log.debug("processNode " + nodeRef);
if(isComplete)
{
List<ChildAssociationRef> expectedChildren = node.getChildAssocs();
List<NodeRef> expectedChildNodeRefs = new ArrayList<NodeRef>();
for(ChildAssociationRef ref : expectedChildren)
{
log.debug("expecting child" + ref);
expectedChildNodeRefs.add(ref.getChildRef());
}
// TODO Do we need to worry about path based nodes ? Assuming no at the moment.
if(nodeService.exists(nodeRef))
{
log.debug("destination node exists");
/**
* yes this node exists in the destination.
*/
List<ChildAssociationRef> actualChildren = nodeService.getChildAssocs(nodeRef);
/**
* For each destination child association
*/
for(ChildAssociationRef child : actualChildren)
{
log.debug("checking child: " + child);
if(child.isPrimary())
{
/**
* yes its a primary assoc
* should it be there ?
*/
NodeRef childNodeRef = child.getChildRef();
if(!expectedChildNodeRefs.contains(childNodeRef))
{
/**
* An unexpected child - if this node has been transferred then
* it needs to be deleted. If it is a local node then we don't
* touch it.
*/
log.debug("unexpected child:" + child);
if(nodeService.hasAspect(childNodeRef, TransferModel.ASPECT_TRANSFERRED));
{
// Destination
// log.debug("destination node has been transferred");
nodeService.deleteNode(childNodeRef);
log.debug("deleted node:" + childNodeRef);
}
}
}
}
}
}
}
protected void processHeader(TransferManifestHeader header)
{
isComplete = header.isComplete();
log.debug("isComplete :" + isComplete);
}
/*
* (non-Javadoc)
*
* @see org.alfresco.repo.transfer.manifest.TransferManifestProcessor#startTransferManifest()
*/
protected void startManifest()
{
//NOOP
}
/**
* @param nodeService
* the nodeService to set
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
/**
* @param nodeResolver
* the nodeResolver to set
*/
public void setNodeResolver(CorrespondingNodeResolver nodeResolver)
{
this.nodeResolver = nodeResolver;
}
}

View File

@@ -565,6 +565,7 @@ public class TransferServiceImpl implements TransferService
header.setRepositoryId(descriptor.getId()); header.setRepositoryId(descriptor.getId());
header.setCreatedDate(new Date()); header.setCreatedDate(new Date());
header.setNodeCount(nodes.size()); header.setNodeCount(nodes.size());
header.setComplete(definition.isComplete());
formatter.startTransferManifest(snapshotWriter); formatter.startTransferManifest(snapshotWriter);
formatter.writeTransferManifestHeader(header); formatter.writeTransferManifestHeader(header);
for(NodeRef nodeRef : nodes) for(NodeRef nodeRef : nodes)

View File

@@ -1855,6 +1855,497 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
// } // }
// } // }
/**
* Test the transfer method behaviour with respect to sync folders - sending a complete set of nodes and implying delete from
* absence of a node.
*
* This is a unit test so it does some shenanigans to send to the same instance of alfresco.
*
* Tree of nodes
*
* A1
* | |
* A2 A3 (Content)
* |
* A4 A5 (content)
*
* Test steps -
* 1 add A1
* 2 add A2, A3, A4, A5
* 3 remove A2 (A4 and A5 should cascade delete on source)
* 4 remove A3
* 5 add back A3
* 6 add A2, A4, A5
*
*/
public void testTransferSyncNodes() throws Exception
{
setDefaultRollback(false);
String CONTENT_TITLE = "ContentTitle";
String CONTENT_TITLE_UPDATED = "ContentTitleUpdated";
Locale CONTENT_LOCALE = Locale.GERMAN;
String CONTENT_STRING = "Hello";
/**
* 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.
*/
TransferTransmitter transmitter = new UnitTestInProcessTransmitterImpl(receiver, contentService, transactionService);
transferServiceImpl.setTransmitter(transmitter);
UnitTestTransferManifestNodeFactory testNodeFactory = new UnitTestTransferManifestNodeFactory(this.transferManifestNodeFactory);
transferServiceImpl.setTransferManifestNodeFactory(testNodeFactory);
List<Pair<Path, Path>> pathMap = testNodeFactory.getPathMap();
// Map company_home/guest_home to company_home so tranferred nodes and moved "up" one level.
pathMap.add(new Pair<Path, Path>(PathHelper.stringToPath(GUEST_HOME_XPATH_QUERY), PathHelper.stringToPath(COMPANY_HOME_XPATH_QUERY)));
/**
* Now go ahead and create our first transfer target
*/
String targetName = "testTransferSyncNodes";
TransferTarget transferMe;
NodeRef A1NodeRef;
NodeRef A2NodeRef;
NodeRef A3NodeRef;
NodeRef A4NodeRef;
NodeRef A5NodeRef;
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 A5 that we will read and write
*/
{
// Node A1
String name = GUID.generate();
ChildAssociationRef child = nodeService.createNode(guestHome, ContentModel.ASSOC_CONTAINS, QName.createQName(name), ContentModel.TYPE_FOLDER);
A1NodeRef = child.getChildRef();
nodeService.setProperty(A1NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A1NodeRef, ContentModel.PROP_NAME, name);
}
{
// Node A2
ChildAssociationRef child = nodeService.createNode(A1NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A2"), ContentModel.TYPE_FOLDER);
A2NodeRef = child.getChildRef();
nodeService.setProperty(A2NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A2NodeRef, ContentModel.PROP_NAME, "A2");
}
{
// Node A3
ChildAssociationRef child = nodeService.createNode(A1NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A3"), ContentModel.TYPE_CONTENT);
A3NodeRef = child.getChildRef();
nodeService.setProperty(A3NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A3NodeRef, ContentModel.PROP_NAME, "A3");
ContentWriter writer = contentService.getWriter(A3NodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
}
{
// Node A4
ChildAssociationRef child = nodeService.createNode(A2NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A4"), ContentModel.TYPE_CONTENT);
A4NodeRef = child.getChildRef();
nodeService.setProperty(A4NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A4NodeRef, ContentModel.PROP_NAME, "A4");
ContentWriter writer = contentService.getWriter(A4NodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
}
{
// Node A5
ChildAssociationRef child = nodeService.createNode(A2NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A5"), ContentModel.TYPE_CONTENT);
A5NodeRef = child.getChildRef();
nodeService.setProperty(A5NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A5NodeRef, ContentModel.PROP_NAME, "A5");
ContentWriter writer = contentService.getWriter(A5NodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
}
// Create the transfer target if it does not already exist
if(!transferService.targetExists(targetName))
{
transferMe = createTransferTarget(targetName);
}
else
{
transferMe = transferService.getTransferTarget(targetName);
}
}
finally
{
endTransaction();
}
/**
* Step 1. Add Node A1.
*/
startNewTransaction();
try
{
/**
* Transfer Node A with no children
*/
{
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(A1NodeRef);
definition.setNodes(nodes);
definition.setComplete(true);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists and has similar properties to the source
destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
assertFalse("unit test stuffed up - comparing with self", destNodeRef.equals(transferMe.getNodeRef()));
assertTrue("dest node ref does not exist", nodeService.exists(destNodeRef));
assertEquals("title is wrong", (String)nodeService.getProperty(destNodeRef, ContentModel.PROP_TITLE), CONTENT_TITLE);
assertEquals("type is wrong", nodeService.getType(A1NodeRef), nodeService.getType(destNodeRef));
// Check injected transferred aspect.
assertNotNull("transferredAspect", (String)nodeService.getProperty(destNodeRef, TransferModel.PROP_REPOSITORY_ID));
}
finally
{
endTransaction();
}
/**
* Step 2. Add Node A2, A3, A4, A5.
*/
startNewTransaction();
try
{
/**
* Transfer Node A 1-5
*/
{
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(A1NodeRef);
nodes.add(A2NodeRef);
nodes.add(A3NodeRef);
nodes.add(A4NodeRef);
nodes.add(A5NodeRef);
definition.setNodes(nodes);
definition.setComplete(true);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists and has similar properties to the source
destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
assertFalse("unit test stuffed up - comparing with self", destNodeRef.equals(transferMe.getNodeRef()));
assertTrue("dest node ref A1 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A1NodeRef)));
assertTrue("dest node ref A2 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A2NodeRef)));
assertTrue("dest node ref A3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A3NodeRef)));
assertTrue("dest node ref A4 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A4NodeRef)));
assertTrue("dest node ref A5 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A5NodeRef)));
// Check injected transferred aspect.
assertNotNull("transferredAspect", (String)nodeService.getProperty(destNodeRef, TransferModel.PROP_REPOSITORY_ID));
}
finally
{
endTransaction();
}
/**
* Step 3 - remove folder node A2
*/
startNewTransaction();
try
{
nodeService.deleteNode(A2NodeRef);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
/**
* Transfer Node A 1-5
*/
{
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(A1NodeRef);
//nodes.add(A2NodeRef);
nodes.add(A3NodeRef);
//nodes.add(A4NodeRef);
//nodes.add(A5NodeRef);
definition.setNodes(nodes);
definition.setComplete(true);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists and has similar properties to the source
destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
assertFalse("unit test stuffed up - comparing with self", destNodeRef.equals(transferMe.getNodeRef()));
assertTrue("dest node ref A1 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A1NodeRef)));
assertFalse("dest node ref A2 has not been deleted", nodeService.exists(testNodeFactory.getMappedNodeRef(A2NodeRef)));
assertTrue("dest node ref A3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A3NodeRef)));
assertFalse("dest node ref A4 has not been deleted", nodeService.exists(testNodeFactory.getMappedNodeRef(A4NodeRef)));
assertFalse("dest node ref A5 has not been deleted", nodeService.exists(testNodeFactory.getMappedNodeRef(A5NodeRef)));
// Check injected transferred aspect.
assertNotNull("transferredAspect", (String)nodeService.getProperty(destNodeRef, TransferModel.PROP_REPOSITORY_ID));
}
finally
{
endTransaction();
}
/**
* Step 4 - remove content node A3
*/
startNewTransaction();
try
{
nodeService.deleteNode(A3NodeRef);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
/**
* Transfer Node A 1-5
*/
{
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(A1NodeRef);
//nodes.add(A2NodeRef);
//nodes.add(A3NodeRef);
//nodes.add(A4NodeRef);
//nodes.add(A5NodeRef);
definition.setNodes(nodes);
definition.setComplete(true);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists and has similar properties to the source
destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
assertFalse("unit test stuffed up - comparing with self", destNodeRef.equals(transferMe.getNodeRef()));
assertTrue("dest node ref A1 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A1NodeRef)));
assertFalse("dest node ref A2 has not been deleted", nodeService.exists(testNodeFactory.getMappedNodeRef(A2NodeRef)));
assertFalse("dest node ref A3 has not been deleted", nodeService.exists(testNodeFactory.getMappedNodeRef(A3NodeRef)));
assertFalse("dest node ref A4 has not been deleted", nodeService.exists(testNodeFactory.getMappedNodeRef(A4NodeRef)));
assertFalse("dest node ref A5 has not been deleted", nodeService.exists(testNodeFactory.getMappedNodeRef(A5NodeRef)));
// Check injected transferred aspect.
assertNotNull("transferredAspect", (String)nodeService.getProperty(destNodeRef, TransferModel.PROP_REPOSITORY_ID));
}
finally
{
endTransaction();
}
/**
* Step 5. Add back A3.
*/
startNewTransaction();
try
{
ChildAssociationRef child = nodeService.createNode(A1NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A3"), ContentModel.TYPE_CONTENT);
A3NodeRef = child.getChildRef();
nodeService.setProperty(A3NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A3NodeRef, ContentModel.PROP_NAME, "A3");
ContentWriter writer = contentService.getWriter(A3NodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
/**
* Transfer Node A 1-5
*/
{
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(A1NodeRef);
//nodes.add(A2NodeRef);
nodes.add(A3NodeRef);
//nodes.add(A4NodeRef);
//nodes.add(A5NodeRef);
definition.setNodes(nodes);
definition.setComplete(true);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists and has similar properties to the source
destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
assertFalse("unit test stuffed up - comparing with self", destNodeRef.equals(transferMe.getNodeRef()));
assertTrue("dest node ref A1 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A1NodeRef)));
assertFalse("dest node ref A2 has not been deleted", nodeService.exists(testNodeFactory.getMappedNodeRef(A2NodeRef)));
assertTrue("dest node A3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A3NodeRef)));
assertFalse("dest node ref A4 has not been deleted", nodeService.exists(testNodeFactory.getMappedNodeRef(A4NodeRef)));
assertFalse("dest node ref A5 has not been deleted", nodeService.exists(testNodeFactory.getMappedNodeRef(A5NodeRef)));
// Check injected transferred aspect.
assertNotNull("transferredAspect", (String)nodeService.getProperty(destNodeRef, TransferModel.PROP_REPOSITORY_ID));
}
finally
{
endTransaction();
}
/**
* Step 6. add A2, A4, A5
*/
startNewTransaction();
try
{
{
// Node A2
ChildAssociationRef child = nodeService.createNode(A1NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A2"), ContentModel.TYPE_FOLDER);
A2NodeRef = child.getChildRef();
nodeService.setProperty(A2NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A2NodeRef, ContentModel.PROP_NAME, "A2");
}
{
// Node A4
ChildAssociationRef child = nodeService.createNode(A2NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A4"), ContentModel.TYPE_CONTENT);
A4NodeRef = child.getChildRef();
nodeService.setProperty(A4NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A4NodeRef, ContentModel.PROP_NAME, "A4");
ContentWriter writer = contentService.getWriter(A4NodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
}
{
// Node A5
ChildAssociationRef child = nodeService.createNode(A2NodeRef, ContentModel.ASSOC_CONTAINS, QName.createQName("A5"), ContentModel.TYPE_CONTENT);
A5NodeRef = child.getChildRef();
nodeService.setProperty(A5NodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(A5NodeRef, ContentModel.PROP_NAME, "A5");
ContentWriter writer = contentService.getWriter(A5NodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
/**
* Transfer Node A 1-5
*/
{
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(A1NodeRef);
nodes.add(A2NodeRef);
nodes.add(A3NodeRef);
nodes.add(A4NodeRef);
nodes.add(A5NodeRef);
definition.setNodes(nodes);
definition.setComplete(true);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
// Now validate that the target node exists and has similar properties to the source
destNodeRef = testNodeFactory.getMappedNodeRef(A1NodeRef);
assertFalse("unit test stuffed up - comparing with self", destNodeRef.equals(transferMe.getNodeRef()));
assertTrue("dest node A1 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A1NodeRef)));
assertTrue("dest node A2 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A2NodeRef)));
assertTrue("dest node A3 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A3NodeRef)));
assertTrue("dest node A4 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A4NodeRef)));
assertTrue("dest node A5 does not exist", nodeService.exists(testNodeFactory.getMappedNodeRef(A5NodeRef)));
// Check injected transferred aspect.
assertNotNull("transferredAspect", (String)nodeService.getProperty(destNodeRef, TransferModel.PROP_REPOSITORY_ID));
}
finally
{
endTransaction();
}
}
private TransferTarget createTransferTarget(String name) private TransferTarget createTransferTarget(String name)
{ {

View File

@@ -108,6 +108,26 @@ public class UnitTestTransferManifestNodeFactory implements TransferManifestNode
} }
normalNode.setParentAssocs(mappedParentAssocs); normalNode.setParentAssocs(mappedParentAssocs);
} }
/**
* Fiddle with the child assocs
*/
if (newNode instanceof TransferManifestNormalNode)
{
TransferManifestNormalNode normalNode = (TransferManifestNormalNode) newNode;
List<ChildAssociationRef> assocs = normalNode.getChildAssocs();
List<ChildAssociationRef> mappedChildAssocs = new ArrayList<ChildAssociationRef>();
for (ChildAssociationRef assoc : assocs)
{
NodeRef before = assoc.getChildRef();
NodeRef mappedChildNodeRef = mapNodeRef(before);
ChildAssociationRef replace = new ChildAssociationRef(assoc.getTypeQName(), mappedParentNodeRef,
assoc.getQName(), mappedChildNodeRef, assoc.isPrimary(), assoc.getNthSibling());
mappedChildAssocs.add(replace);
}
normalNode.setChildAssocs(mappedChildAssocs);
}
/** /**
* Fiddle with the UUID property * Fiddle with the UUID property

View File

@@ -29,6 +29,7 @@ public interface ManifestModel extends TransferModel
static final String LOCALNAME_TRANSFER_HEADER = "transferManifestHeader"; static final String LOCALNAME_TRANSFER_HEADER = "transferManifestHeader";
static final String LOCALNAME_HEADER_CREATED_DATE = "createdDate"; static final String LOCALNAME_HEADER_CREATED_DATE = "createdDate";
static final String LOCALNAME_HEADER_NODE_COUNT = "nodeCount"; static final String LOCALNAME_HEADER_NODE_COUNT = "nodeCount";
static final String LOCALNAME_HEADER_COMPLETE = "complete";
static final String LOCALNAME_HEADER_REPOSITORY_ID = "repositoryId"; static final String LOCALNAME_HEADER_REPOSITORY_ID = "repositoryId";
static final String LOCALNAME_ELEMENT_NODES = "nodes"; static final String LOCALNAME_ELEMENT_NODES = "nodes";
static final String LOCALNAME_ELEMENT_NODE = "node"; static final String LOCALNAME_ELEMENT_NODE = "node";

View File

@@ -31,6 +31,7 @@ public class TransferManifestHeader
private Date createdDate; private Date createdDate;
private int nodeCount; private int nodeCount;
private String repositoryId; private String repositoryId;
private boolean isComplete;
public void setCreatedDate(Date createDate) public void setCreatedDate(Date createDate)
{ {
@@ -58,15 +59,33 @@ public class TransferManifestHeader
this.nodeCount = nodeCount; this.nodeCount = nodeCount;
} }
/**
* The repository ID of this, the sending system
* @param repositoryId
*/
public void setRepositoryId(String repositoryId) public void setRepositoryId(String repositoryId)
{ {
this.repositoryId = repositoryId; this.repositoryId = repositoryId;
} }
/**
* Get the repository ID of this, the sending system
* @return the repository Id
*/
public String getRepositoryId() public String getRepositoryId()
{ {
return repositoryId; return repositoryId;
} }
public void setComplete(boolean isComplete)
{
this.isComplete = isComplete;
}
public boolean isComplete()
{
return isComplete;
}
} }

View File

@@ -387,6 +387,11 @@ public class XMLTransferManifestReader extends DefaultHandler implements Content
header.setNodeCount(Integer.parseInt(buffer.toString())); header.setNodeCount(Integer.parseInt(buffer.toString()));
buffer = null; buffer = null;
} }
else if(elementName.equals(ManifestModel.LOCALNAME_HEADER_COMPLETE))
{
TransferManifestHeader header = (TransferManifestHeader)props.get("header");
header.setComplete(true);
}
else if(elementName.equals(ManifestModel.LOCALNAME_HEADER_REPOSITORY_ID)) else if(elementName.equals(ManifestModel.LOCALNAME_HEADER_REPOSITORY_ID))
{ {
TransferManifestHeader header = (TransferManifestHeader)props.get("header"); TransferManifestHeader header = (TransferManifestHeader)props.get("header");

View File

@@ -117,49 +117,64 @@ public class XMLTransferManifestWriter implements TransferManifestWriter
{ {
// Start Header // Start Header
writer.startElement(TransferModel.TRANSFER_MODEL_1_0_URI, writer.startElement(TransferModel.TRANSFER_MODEL_1_0_URI,
ManifestModel.LOCALNAME_TRANSFER_HEADER, PREFIX + ":" ManifestModel.LOCALNAME_TRANSFER_HEADER, PREFIX + ":"
+ ManifestModel.LOCALNAME_TRANSFER_HEADER, EMPTY_ATTRIBUTES); + ManifestModel.LOCALNAME_TRANSFER_HEADER, EMPTY_ATTRIBUTES);
// Created Date // Created Date
writer writer
.startElement(TransferModel.TRANSFER_MODEL_1_0_URI, .startElement(TransferModel.TRANSFER_MODEL_1_0_URI,
ManifestModel.LOCALNAME_HEADER_CREATED_DATE, PREFIX + ":" ManifestModel.LOCALNAME_HEADER_CREATED_DATE, PREFIX + ":"
+ ManifestModel.LOCALNAME_HEADER_CREATED_DATE, + ManifestModel.LOCALNAME_HEADER_CREATED_DATE,
EMPTY_ATTRIBUTES); EMPTY_ATTRIBUTES);
writeDate(header.getCreatedDate()); writeDate(header.getCreatedDate());
writer.endElement(TransferModel.TRANSFER_MODEL_1_0_URI, writer.endElement(TransferModel.TRANSFER_MODEL_1_0_URI,
ManifestModel.LOCALNAME_HEADER_CREATED_DATE, PREFIX + ":" ManifestModel.LOCALNAME_HEADER_CREATED_DATE, PREFIX + ":"
+ ManifestModel.LOCALNAME_HEADER_CREATED_DATE); + ManifestModel.LOCALNAME_HEADER_CREATED_DATE);
}
if(header.getNodeCount() > 0)
{
// Node count // Node count
writer.startElement(TransferModel.TRANSFER_MODEL_1_0_URI, writer.startElement(TransferModel.TRANSFER_MODEL_1_0_URI,
ManifestModel.LOCALNAME_HEADER_NODE_COUNT, PREFIX + ":" ManifestModel.LOCALNAME_HEADER_NODE_COUNT, PREFIX + ":"
+ ManifestModel.LOCALNAME_HEADER_NODE_COUNT, EMPTY_ATTRIBUTES); + ManifestModel.LOCALNAME_HEADER_NODE_COUNT, EMPTY_ATTRIBUTES);
char[] nodeCountChars = Integer.toString(header.getNodeCount()).toCharArray(); char[] nodeCountChars = Integer.toString(header.getNodeCount()).toCharArray();
writer.characters(nodeCountChars, 0, nodeCountChars.length); writer.characters(nodeCountChars, 0, nodeCountChars.length);
writer.endElement(TransferModel.TRANSFER_MODEL_1_0_URI, writer.endElement(TransferModel.TRANSFER_MODEL_1_0_URI,
ManifestModel.LOCALNAME_HEADER_NODE_COUNT, PREFIX + ":" ManifestModel.LOCALNAME_HEADER_NODE_COUNT, PREFIX + ":"
+ ManifestModel.LOCALNAME_HEADER_NODE_COUNT); + ManifestModel.LOCALNAME_HEADER_NODE_COUNT);
}
if(header.getRepositoryId() != null)
{ if(header.getRepositoryId() != null)
// Repository Id {
writer.startElement(TransferModel.TRANSFER_MODEL_1_0_URI, // Repository Id
writer.startElement(TransferModel.TRANSFER_MODEL_1_0_URI,
ManifestModel.LOCALNAME_HEADER_REPOSITORY_ID, PREFIX + ":" ManifestModel.LOCALNAME_HEADER_REPOSITORY_ID, PREFIX + ":"
+ ManifestModel.LOCALNAME_HEADER_REPOSITORY_ID, EMPTY_ATTRIBUTES); + ManifestModel.LOCALNAME_HEADER_REPOSITORY_ID, EMPTY_ATTRIBUTES);
char[] repositoryId = header.getRepositoryId().toCharArray(); char[] repositoryId = header.getRepositoryId().toCharArray();
writer.characters(repositoryId, 0, repositoryId.length); writer.characters(repositoryId, 0, repositoryId.length);
writer.endElement(TransferModel.TRANSFER_MODEL_1_0_URI, writer.endElement(TransferModel.TRANSFER_MODEL_1_0_URI,
ManifestModel.LOCALNAME_HEADER_REPOSITORY_ID, PREFIX + ":" ManifestModel.LOCALNAME_HEADER_REPOSITORY_ID, PREFIX + ":"
+ ManifestModel.LOCALNAME_HEADER_REPOSITORY_ID); + ManifestModel.LOCALNAME_HEADER_REPOSITORY_ID);
}
// End Header
writer.endElement(TransferModel.TRANSFER_MODEL_1_0_URI,
ManifestModel.LOCALNAME_TRANSFER_HEADER, PREFIX + ":"
+ ManifestModel.LOCALNAME_TRANSFER_HEADER);
} }
if(header.isComplete())
{
// Is this a complete transfer
writer.startElement(TransferModel.TRANSFER_MODEL_1_0_URI,
ManifestModel.LOCALNAME_HEADER_COMPLETE, PREFIX + ":"
+ ManifestModel.LOCALNAME_HEADER_COMPLETE, EMPTY_ATTRIBUTES);
writer.endElement(TransferModel.TRANSFER_MODEL_1_0_URI,
ManifestModel.LOCALNAME_HEADER_COMPLETE, PREFIX + ":"
+ ManifestModel.LOCALNAME_HEADER_COMPLETE);
}
// End Header
writer.endElement(TransferModel.TRANSFER_MODEL_1_0_URI,
ManifestModel.LOCALNAME_TRANSFER_HEADER, PREFIX + ":"
+ ManifestModel.LOCALNAME_TRANSFER_HEADER);
} }
/** /**