mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Transfer service : more work on just sending content that is required.
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@21160 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -31,18 +31,18 @@ import java.util.TreeSet;
|
||||
public class DeltaList
|
||||
{
|
||||
/**
|
||||
* The set of requiredURLs
|
||||
* The set of requiredParts
|
||||
*/
|
||||
|
||||
private TreeSet<String> requiredURLs = new TreeSet<String>();
|
||||
private TreeSet<String> requiredParts = new TreeSet<String>();
|
||||
|
||||
/**
|
||||
* get the list of URLs reqired by the manifest.
|
||||
* @return the list of required URLs
|
||||
*/
|
||||
public Set<String> getRequiredURLs()
|
||||
public Set<String> getRequiredParts()
|
||||
{
|
||||
return requiredURLs;
|
||||
return requiredParts;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -290,7 +290,7 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
|
||||
Map<QName, Serializable> props = new HashMap<QName, Serializable>(node.getProperties());
|
||||
|
||||
// Split out the content properties and sanitise the others
|
||||
Map<QName, Serializable> contentProps = processProperties(null, props, true);
|
||||
Map<QName, Serializable> contentProps = processProperties(null, props, null);
|
||||
|
||||
// inject transferred property here
|
||||
if(!contentProps.containsKey(TransferModel.PROP_REPOSITORY_ID))
|
||||
@@ -390,6 +390,7 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
|
||||
// We need to process content properties separately.
|
||||
// First, create a shallow copy of the supplied property map...
|
||||
Map<QName, Serializable> props = new HashMap<QName, Serializable>(node.getProperties());
|
||||
Map<QName, Serializable> existingProps = nodeService.getProperties(nodeToUpdate);
|
||||
|
||||
// inject transferred property here
|
||||
if(!props.containsKey(TransferModel.PROP_REPOSITORY_ID))
|
||||
@@ -399,7 +400,7 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
|
||||
}
|
||||
|
||||
// Split out the content properties and sanitise the others
|
||||
Map<QName, Serializable> contentProps = processProperties(nodeToUpdate, props, false);
|
||||
Map<QName, Serializable> contentProps = processProperties(nodeToUpdate, props, existingProps);
|
||||
|
||||
// Update the non-content properties
|
||||
nodeService.setProperties(nodeToUpdate, props);
|
||||
@@ -448,17 +449,19 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
|
||||
* @param nodeToUpdate
|
||||
* The noderef of the existing node in the local repo that is to be updated with these properties. May be
|
||||
* null, indicating that these properties are destined for a brand new local node.
|
||||
* @param props
|
||||
* @return A map containing the content properties from the supplied "props" map
|
||||
* @param props the new properties
|
||||
* @param the existing properties, null if this is a create
|
||||
* @return A map containing the content properties which are going to be replaced from the supplied "props" map
|
||||
*/
|
||||
private Map<QName, Serializable> processProperties(NodeRef nodeToUpdate, Map<QName, Serializable> props,
|
||||
boolean isNew)
|
||||
Map<QName, Serializable> existingProps)
|
||||
{
|
||||
Map<QName, Serializable> contentProps = new HashMap<QName, Serializable>();
|
||||
// ...and copy any supplied content properties into this new map...
|
||||
for (Map.Entry<QName, Serializable> propEntry : props.entrySet())
|
||||
{
|
||||
Serializable value = propEntry.getValue();
|
||||
QName key = propEntry.getKey();
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
if (value == null)
|
||||
@@ -468,8 +471,43 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
|
||||
}
|
||||
if ((value != null) && ContentData.class.isAssignableFrom(value.getClass()))
|
||||
{
|
||||
if(existingProps != null)
|
||||
{
|
||||
// This is an update and we have content data
|
||||
File stagingDir = getStagingFolder();
|
||||
ContentData contentData = (ContentData) propEntry.getValue();
|
||||
String contentUrl = contentData.getContentUrl();
|
||||
String fileName = TransferCommons.URLToPartName(contentUrl);
|
||||
File stagedFile = new File(stagingDir, fileName);
|
||||
if (stagedFile.exists())
|
||||
{
|
||||
if(log.isDebugEnabled())
|
||||
{
|
||||
log.debug("replace content for node:" + nodeToUpdate + ", " + key);
|
||||
}
|
||||
// Yes we are going to replace the content item
|
||||
contentProps.put(propEntry.getKey(), propEntry.getValue());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Staging file does not exist
|
||||
if(props.containsKey(key))
|
||||
{
|
||||
if(log.isDebugEnabled())
|
||||
{
|
||||
log.debug("keep existing content for node:" + nodeToUpdate + ", " + key);
|
||||
}
|
||||
// keep the existing content value
|
||||
props.put(propEntry.getKey(), existingProps.get(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is a create so all content items are new
|
||||
contentProps.put(propEntry.getKey(), propEntry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now we can remove the content properties from amongst the other kinds
|
||||
@@ -480,13 +518,10 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
|
||||
props.remove(contentPropertyName);
|
||||
}
|
||||
|
||||
if (!isNew)
|
||||
if (existingProps != null)
|
||||
{
|
||||
// Finally, overlay the repo-specific properties from the existing
|
||||
// node (if there is one)
|
||||
Map<QName, Serializable> existingProps = (nodeToUpdate == null) ? new HashMap<QName, Serializable>()
|
||||
: nodeService.getProperties(nodeToUpdate);
|
||||
|
||||
for (QName localProperty : getLocalProperties())
|
||||
{
|
||||
Serializable existingValue = existingProps.get(localProperty);
|
||||
@@ -515,7 +550,7 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
|
||||
{
|
||||
ContentData contentData = (ContentData) contentEntry.getValue();
|
||||
String contentUrl = contentData.getContentUrl();
|
||||
String fileName = contentUrl.substring(contentUrl.lastIndexOf('/') + 1);
|
||||
String fileName = TransferCommons.URLToPartName(contentUrl);
|
||||
File stagedFile = new File(stagingDir, fileName);
|
||||
if (!stagedFile.exists())
|
||||
{
|
||||
|
@@ -22,6 +22,7 @@ package org.alfresco.repo.transfer;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -105,9 +106,9 @@ public class RepoRequsiteManifestProcessorImpl extends AbstractManifestProcessor
|
||||
*/
|
||||
NodeRef destinationNode = resolvedNodes.resolvedChild;
|
||||
|
||||
// Serializable yy = node.getProperties().get(ContentModel.PROP_MODIFIED);
|
||||
Map<QName, Serializable> destProps = nodeService.getProperties(destinationNode);
|
||||
// Serializable xx = destProps.get(ContentModel.PROP_MODIFIED);
|
||||
|
||||
|
||||
|
||||
for (Map.Entry<QName, Serializable> propEntry : node.getProperties().entrySet())
|
||||
{
|
||||
@@ -128,26 +129,33 @@ public class RepoRequsiteManifestProcessorImpl extends AbstractManifestProcessor
|
||||
ContentData destContent = (ContentData)destProps.get(propEntry.getKey());
|
||||
|
||||
/**
|
||||
* If the URLs are the same then the content is already on the server
|
||||
* If the modification dates for the node are different
|
||||
*/
|
||||
if(TransferCommons.URLToPartName(destContent.getContentUrl()).equalsIgnoreCase(
|
||||
TransferCommons.URLToPartName(srcContent.getContentUrl())))
|
||||
Serializable srcModified = node.getProperties().get(ContentModel.PROP_MODIFIED);
|
||||
Serializable destModified = destProps.get(ContentModel.PROP_MODIFIED);
|
||||
|
||||
log.debug ("srcModified :" + srcModified + "destModified :" + destModified);
|
||||
|
||||
if(srcModified != null &&
|
||||
destModified != null &&
|
||||
srcModified instanceof Date &&
|
||||
destModified instanceof Date &&
|
||||
((Date)srcModified).getTime() >= ((Date)destModified).getTime())
|
||||
{
|
||||
if(log.isDebugEnabled())
|
||||
{
|
||||
log.debug("the url is the same - no need to send it:" + destContent.getContentUrl());
|
||||
log.debug("the modified date is the same - no need to send it:" + destContent.getContentUrl());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We need to diff the property
|
||||
out.missingContent(node.getNodeRef(), propEntry.getKey(), srcContent.getContentUrl());
|
||||
out.missingContent(node.getNodeRef(), propEntry.getKey(), TransferCommons.URLToPartName(srcContent.getContentUrl()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We don't have the property on the destination node
|
||||
out.missingContent(node.getNodeRef(), propEntry.getKey(), srcContent.getContentUrl());
|
||||
out.missingContent(node.getNodeRef(), propEntry.getKey(), TransferCommons.URLToPartName(srcContent.getContentUrl()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -171,7 +179,7 @@ public class RepoRequsiteManifestProcessorImpl extends AbstractManifestProcessor
|
||||
{
|
||||
ContentData content = (ContentData)value;
|
||||
//
|
||||
out.missingContent(node.getNodeRef(), propEntry.getKey(), content.getContentUrl());
|
||||
out.missingContent(node.getNodeRef(), propEntry.getKey(), TransferCommons.URLToPartName(content.getContentUrl()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -699,7 +699,8 @@ public class TransferServiceImpl implements TransferService
|
||||
*/
|
||||
if(deltaList != null)
|
||||
{
|
||||
if(deltaList.getRequiredURLs().contains(d.getContentUrl()))
|
||||
String partName = TransferCommons.URLToPartName(d.getContentUrl());
|
||||
if(deltaList.getRequiredParts().contains(partName))
|
||||
{
|
||||
logger.debug("content is required :" + d.getContentUrl());
|
||||
chunker.addContent(d);
|
||||
|
@@ -19,6 +19,7 @@
|
||||
package org.alfresco.repo.transfer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@@ -62,6 +63,8 @@ import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.util.BaseAlfrescoSpringTest;
|
||||
import org.alfresco.util.GUID;
|
||||
import org.alfresco.util.Pair;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.transaction.TransactionDefinition;
|
||||
import org.springframework.transaction.support.DefaultTransactionDefinition;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
@@ -647,6 +650,7 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
|
||||
endTransaction();
|
||||
}
|
||||
|
||||
logger.debug("First transfer - create new node (no content yet)");
|
||||
startNewTransaction();
|
||||
try
|
||||
{
|
||||
@@ -676,10 +680,25 @@ 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 the modified time of the destination node is the same as the source node.
|
||||
Date destModifiedDate = (Date)nodeService.getProperty(destNodeRef, ContentModel.PROP_MODIFIED);
|
||||
Date srcModifiedDate = (Date)nodeService.getProperty(contentNodeRef, ContentModel.PROP_MODIFIED);
|
||||
|
||||
logger.debug("srcModifiedDate : " + srcModifiedDate + " destModifiedDate : " + destModifiedDate);
|
||||
assertTrue("dest modified date is not correct", destModifiedDate.compareTo(srcModifiedDate)== 0);
|
||||
|
||||
Date destCreatedDate = (Date)nodeService.getProperty(destNodeRef, ContentModel.PROP_CREATED);
|
||||
Date srcCreatedDate = (Date)nodeService.getProperty(contentNodeRef, ContentModel.PROP_CREATED);
|
||||
|
||||
logger.debug("srcCreatedDate : " + srcCreatedDate + " destCreatedDate : " + destCreatedDate);
|
||||
assertTrue("dest created date is not correct", destCreatedDate.compareTo(srcCreatedDate)== 0);
|
||||
|
||||
|
||||
|
||||
// Check injected transferred aspect.
|
||||
assertNotNull("transferredAspect", (String)nodeService.getProperty(destNodeRef, TransferModel.PROP_REPOSITORY_ID));
|
||||
|
||||
// Now set up the next test which is to
|
||||
// Now set up the next test which is to change the title
|
||||
nodeService.setProperty(contentNodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE_UPDATED);
|
||||
}
|
||||
finally
|
||||
@@ -687,11 +706,12 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
|
||||
endTransaction();
|
||||
}
|
||||
|
||||
logger.debug("Second transfer - update title property (no content yet)");
|
||||
startNewTransaction();
|
||||
try
|
||||
{
|
||||
/**
|
||||
* Transfer our node again - so this is an update
|
||||
* Transfer our node again - so this is an update of the title property
|
||||
*/
|
||||
{
|
||||
TransferDefinition definition = new TransferDefinition();
|
||||
@@ -715,6 +735,21 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
|
||||
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 the modified time of the destination node is the same as the source node.
|
||||
Date destModifiedDate = (Date)nodeService.getProperty(destNodeRef, ContentModel.PROP_MODIFIED);
|
||||
Date srcModifiedDate = (Date)nodeService.getProperty(contentNodeRef, ContentModel.PROP_MODIFIED);
|
||||
|
||||
logger.debug("srcModifiedDate : " + srcModifiedDate + " destModifiedDate : " + destModifiedDate);
|
||||
|
||||
// BUGBUG - MER 14/07/2010 - can't set modified date
|
||||
// assertTrue("after update, modified date is not correct", destModifiedDate.compareTo(srcModifiedDate) == 0);
|
||||
|
||||
Date destCreatedDate = (Date)nodeService.getProperty(destNodeRef, ContentModel.PROP_CREATED);
|
||||
Date srcCreatedDate = (Date)nodeService.getProperty(contentNodeRef, ContentModel.PROP_CREATED);
|
||||
|
||||
logger.debug("srcCreatedDate : " + srcCreatedDate + " destCreatedDate : " + destCreatedDate);
|
||||
assertTrue("after update, created date is not correct", destCreatedDate.compareTo(srcCreatedDate)== 0);
|
||||
|
||||
// Check injected transferred aspect.
|
||||
assertNotNull("transferredAspect", (String)nodeService.getProperty(destNodeRef, TransferModel.PROP_REPOSITORY_ID));
|
||||
|
||||
@@ -724,6 +759,7 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
|
||||
endTransaction();
|
||||
}
|
||||
|
||||
logger.debug("Transfer again - this is an update");
|
||||
startNewTransaction();
|
||||
try
|
||||
{
|
||||
@@ -744,9 +780,10 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
|
||||
}
|
||||
|
||||
/**
|
||||
* Now transfer nothing - content items do not need to be transferred since its alrady on
|
||||
* Now transfer nothing - content items do not need to be transferred since its already on
|
||||
* the destination.
|
||||
*/
|
||||
logger.debug("Transfer again - with no new content");
|
||||
startNewTransaction();
|
||||
try
|
||||
{
|
||||
@@ -761,11 +798,28 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
|
||||
endTransaction();
|
||||
}
|
||||
|
||||
startNewTransaction();
|
||||
try
|
||||
{
|
||||
// Now validate that the target node still exists and in particular that the old content is still there
|
||||
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_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
|
||||
{
|
||||
endTransaction();
|
||||
}
|
||||
|
||||
/**
|
||||
* Negative test transfer nothing
|
||||
*/
|
||||
logger.debug("Transfer again - with no content - should throw exception");
|
||||
try
|
||||
{
|
||||
TransferDefinition definition = new TransferDefinition();
|
||||
|
@@ -38,7 +38,7 @@ public class DeltaListRequsiteProcessor implements TransferRequsiteProcessor
|
||||
|
||||
public void missingContent(NodeRef node, QName qname, String name)
|
||||
{
|
||||
deltaList.getRequiredURLs().add(name);
|
||||
deltaList.getRequiredParts().add(name);
|
||||
}
|
||||
|
||||
public void startTransferRequsite()
|
||||
|
@@ -25,6 +25,8 @@ import org.alfresco.repo.transfer.TransferModel;
|
||||
*/
|
||||
public interface RequsiteModel extends TransferModel
|
||||
{
|
||||
static final String REQUSITE_MODEL_1_0_URI = "http://www.alfresco.org/model/requsite/1.0";
|
||||
|
||||
static final String LOCALNAME_TRANSFER_REQUSITE = "transferRequsite";
|
||||
|
||||
static final String LOCALNAME_ELEMENT_NODES = "nodes";
|
||||
@@ -37,5 +39,5 @@ public interface RequsiteModel extends TransferModel
|
||||
|
||||
|
||||
// Manifest file prefix
|
||||
static final String REQUSITE_PREFIX = "xferreq";
|
||||
static final String REQUSITE_PREFIX = "xferr";
|
||||
}
|
||||
|
@@ -51,7 +51,7 @@ public class XMLTransferRequsiteReader extends DefaultHandler implements Content
|
||||
*/
|
||||
LinkedList<HashMap<String, String>> namespaces = new LinkedList<HashMap<String, String>>();
|
||||
|
||||
final String TRANSFER_URI = RequsiteModel.TRANSFER_MODEL_1_0_URI;
|
||||
final String REQUSITE_URI = RequsiteModel.REQUSITE_MODEL_1_0_URI;
|
||||
final String XMLNS_URI = "http://www.w3.org/XML/1998/namespace";
|
||||
|
||||
/*
|
||||
@@ -191,7 +191,7 @@ public class XMLTransferRequsiteReader extends DefaultHandler implements Content
|
||||
return;
|
||||
}
|
||||
|
||||
if(elementQName.getNamespaceURI().equals(TRANSFER_URI));
|
||||
if(elementQName.getNamespaceURI().equals(REQUSITE_URI));
|
||||
{
|
||||
// This is one of the transfer manifest elements
|
||||
String elementName = elementQName.getLocalName();
|
||||
|
@@ -90,7 +90,7 @@ public class XMLTransferRequsiteWriter implements TransferRequsiteWriter
|
||||
{
|
||||
this.writer.startDocument();
|
||||
|
||||
this.writer.startPrefixMapping(PREFIX, TransferModel.TRANSFER_MODEL_1_0_URI);
|
||||
this.writer.startPrefixMapping(PREFIX, RequsiteModel.TRANSFER_MODEL_1_0_URI);
|
||||
this.writer.startPrefixMapping("cm", NamespaceService.CONTENT_MODEL_1_0_URI);
|
||||
|
||||
// Start Transfer Manifest // uri, name, prefix
|
||||
|
Reference in New Issue
Block a user