ALF-4865 - transfer service: transfer empty content property

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@22682 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Mark Rogers
2010-09-24 09:51:50 +00:00
parent 0d42709dd2
commit f95cb3c51b
4 changed files with 599 additions and 242 deletions

View File

@@ -307,22 +307,22 @@ public class HttpClientTransmitterImpl implements TransferTransmitter
int responseStatus = httpClient.executeMethod(hostConfig, postSnapshotRequest, httpState); int responseStatus = httpClient.executeMethod(hostConfig, postSnapshotRequest, httpState);
checkResponseStatus("sendManifest", responseStatus, postSnapshotRequest); checkResponseStatus("sendManifest", responseStatus, postSnapshotRequest);
InputStream is = postSnapshotRequest.getResponseBodyAsStream(); InputStream is = postSnapshotRequest.getResponseBodyAsStream();
InputStreamReader reader = new InputStreamReader(is);
BufferedReader br = new BufferedReader(reader); final ReadableByteChannel inputChannel = Channels.newChannel(is);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(result)); final WritableByteChannel outputChannel = Channels.newChannel(result);
try
String s = br.readLine();
while(s != null)
{ {
bw.write(s); // copy the channels
s = br.readLine(); channelCopy(inputChannel, outputChannel);
} }
bw.close(); finally
{
inputChannel.close();
outputChannel.close();
}
return; return;
} }
catch (RuntimeException e) catch (RuntimeException e)

View File

@@ -780,17 +780,26 @@ public class RepoPrimaryManifestProcessorImpl extends AbstractManifestProcessorB
{ {
ContentData contentData = (ContentData) contentEntry.getValue(); ContentData contentData = (ContentData) contentEntry.getValue();
String contentUrl = contentData.getContentUrl(); String contentUrl = contentData.getContentUrl();
String fileName = TransferCommons.URLToPartName(contentUrl); if(contentUrl == null || contentUrl.isEmpty())
File stagedFile = new File(stagingDir, fileName);
if (!stagedFile.exists())
{ {
error(MSG_REFERENCED_CONTENT_FILE_MISSING); log.debug("content data is null or empty:" + nodeToUpdate);
ContentData cd = new ContentData(null, null, 0, null);
nodeService.setProperty(nodeToUpdate, contentEntry.getKey(), cd);
}
else
{
String fileName = TransferCommons.URLToPartName(contentUrl);
File stagedFile = new File(stagingDir, fileName);
if (!stagedFile.exists())
{
error(MSG_REFERENCED_CONTENT_FILE_MISSING);
}
ContentWriter writer = contentService.getWriter(nodeToUpdate, contentEntry.getKey(), true);
writer.setEncoding(contentData.getEncoding());
writer.setMimetype(contentData.getMimetype());
writer.setLocale(contentData.getLocale());
writer.putContent(stagedFile);
} }
ContentWriter writer = contentService.getWriter(nodeToUpdate, contentEntry.getKey(), true);
writer.setEncoding(contentData.getEncoding());
writer.setMimetype(contentData.getMimetype());
writer.setLocale(contentData.getLocale());
writer.putContent(stagedFile);
} }
} }

View File

@@ -1,4 +1,4 @@
/* /*
* Copyright (C) 2009-2010 Alfresco Software Limited. * Copyright (C) 2009-2010 Alfresco Software Limited.
* *
* This file is part of Alfresco * This file is part of Alfresco
@@ -14,208 +14,207 @@
* GNU Lesser General Public License for more details. * GNU Lesser General Public License for more details.
* *
* You should have received a copy of the GNU Lesser General Public License * You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.alfresco.repo.transfer; package org.alfresco.repo.transfer;
import java.io.OutputStream; import java.io.Serializable;
import java.io.Serializable; import java.util.Date;
import java.util.ArrayList; import java.util.Map;
import java.util.Date;
import java.util.HashMap; import org.alfresco.model.ContentModel;
import java.util.List; import org.alfresco.repo.transfer.manifest.TransferManifestDeletedNode;
import java.util.Map; import org.alfresco.repo.transfer.manifest.TransferManifestHeader;
import org.alfresco.repo.transfer.manifest.TransferManifestNormalNode;
import org.alfresco.model.ContentModel; import org.alfresco.repo.transfer.requisite.TransferRequsiteWriter;
import org.alfresco.repo.transfer.manifest.TransferManifestDeletedNode; import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.repo.transfer.manifest.TransferManifestHeader; import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.repo.transfer.manifest.TransferManifestNodeHelper; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.repo.transfer.manifest.TransferManifestNormalNode; import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.repo.transfer.requisite.TransferRequsiteWriter; import org.alfresco.service.cmr.transfer.TransferReceiver;
import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.namespace.QName;
import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.apache.commons.logging.Log;
import org.alfresco.service.cmr.repository.ContentData; import org.apache.commons.logging.LogFactory;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; /**
import org.alfresco.service.cmr.repository.StoreRef; * @author mrogers
import org.alfresco.service.cmr.transfer.TransferReceiver; *
import org.alfresco.service.namespace.QName; * The requisite manifest processor performs a parse of the manifest file to determine which
import org.alfresco.service.namespace.RegexQNamePattern; * resources are required. In particular it returns a list of nodes which require content to be transferred.
import org.apache.commons.logging.Log; *
import org.apache.commons.logging.LogFactory; */
import org.xml.sax.SAXParseException; public class RepoRequisiteManifestProcessorImpl extends AbstractManifestProcessorBase
{
/** private NodeService nodeService;
* @author mrogers private CorrespondingNodeResolver nodeResolver;
* private TransferRequsiteWriter out;
* The requsite manifest processor performs a parse of the manifest file to determine which
* resources are required.
* private static final Log log = LogFactory.getLog(CopyRepoRequisiteManifestProcessorImpl.class);
*/
public class RepoRequisiteManifestProcessorImpl extends AbstractManifestProcessorBase /**
{ * @param receiver
private NodeService nodeService; * @param transferId
private CorrespondingNodeResolver nodeResolver; */
private TransferRequsiteWriter out; public RepoRequisiteManifestProcessorImpl(TransferReceiver receiver, String transferId, TransferRequsiteWriter out)
{
super(receiver, transferId);
private static final Log log = LogFactory.getLog(RepoRequisiteManifestProcessorImpl.class); this.out = out;
}
/**
* @param receiver protected void endManifest()
* @param transferId {
*/ log.debug("End Requsite");
public RepoRequisiteManifestProcessorImpl(TransferReceiver receiver, String transferId, TransferRequsiteWriter out) out.endTransferRequsite();
{ }
super(receiver, transferId);
this.out = out; protected void processNode(TransferManifestDeletedNode node)
} {
//NOOP
protected void endManifest() }
{
log.debug("End Requsite"); protected void processNode(TransferManifestNormalNode node)
out.endTransferRequsite(); {
}
if (log.isDebugEnabled())
protected void processNode(TransferManifestDeletedNode node) {
{ log.debug("Processing node with incoming noderef of " + node.getNodeRef());
//NOOP }
} logComment("Primary Processing incoming node: " + node.getNodeRef() + " -- Source path = " + node.getParentPath() + "/" + node.getPrimaryParentAssoc().getQName());
protected void processNode(TransferManifestNormalNode node) ChildAssociationRef primaryParentAssoc = node.getPrimaryParentAssoc();
{
CorrespondingNodeResolver.ResolvedParentChildPair resolvedNodes = nodeResolver.resolveCorrespondingNode(node
if (log.isDebugEnabled()) .getNodeRef(), primaryParentAssoc, node.getParentPath());
{
log.debug("Processing node with incoming noderef of " + node.getNodeRef()); // Does a corresponding node exist in this repo?
} if (resolvedNodes.resolvedChild != null)
logComment("Primary Processing incoming node: " + node.getNodeRef() + " -- Source path = " + node.getParentPath() + "/" + node.getPrimaryParentAssoc().getQName()); {
/**
ChildAssociationRef primaryParentAssoc = node.getPrimaryParentAssoc(); * there is a corresponding node so we need to check whether we already
* have the content item
CorrespondingNodeResolver.ResolvedParentChildPair resolvedNodes = nodeResolver.resolveCorrespondingNode(node */
.getNodeRef(), primaryParentAssoc, node.getParentPath()); NodeRef destinationNode = resolvedNodes.resolvedChild;
// Does a corresponding node exist in this repo? Map<QName, Serializable> destProps = nodeService.getProperties(destinationNode);
if (resolvedNodes.resolvedChild != null)
{
/**
* there is a corresponding node so we need to check whether we already for (Map.Entry<QName, Serializable> propEntry : node.getProperties().entrySet())
* have the content item {
*/ Serializable value = propEntry.getValue();
NodeRef destinationNode = resolvedNodes.resolvedChild; if (log.isDebugEnabled())
{
Map<QName, Serializable> destProps = nodeService.getProperties(destinationNode); if (value == null)
{
log.debug("Received a null value for property " + propEntry.getKey());
}
for (Map.Entry<QName, Serializable> propEntry : node.getProperties().entrySet()) }
{ if ((value != null) && ContentData.class.isAssignableFrom(value.getClass()))
Serializable value = propEntry.getValue(); {
if (log.isDebugEnabled()) ContentData srcContent = (ContentData)value;
{
if (value == null) if(srcContent.getContentUrl() != null && !srcContent.getContentUrl().isEmpty() )
{ {
log.debug("Received a null value for property " + propEntry.getKey()); Serializable destSer = destProps.get(propEntry.getKey());
} if(destSer != null && ContentData.class.isAssignableFrom(destSer.getClass()))
} {
if ((value != null) && ContentData.class.isAssignableFrom(value.getClass())) ContentData destContent = (ContentData)destProps.get(propEntry.getKey());
{ /**
ContentData srcContent = (ContentData)value; * If the modification dates for the node are different
Serializable destSer = destProps.get(propEntry.getKey()); */
if(destSer != null && ContentData.class.isAssignableFrom(destSer.getClass())) Serializable srcModified = node.getProperties().get(ContentModel.PROP_MODIFIED);
{ Serializable destModified = destProps.get(ContentModel.PROP_MODIFIED);
ContentData destContent = (ContentData)destProps.get(propEntry.getKey());
log.debug ("srcModified :" + srcModified + "destModified :" + destModified);
/**
* If the modification dates for the node are different if(srcModified != null &&
*/ destModified != null &&
Serializable srcModified = node.getProperties().get(ContentModel.PROP_MODIFIED); srcModified instanceof Date &&
Serializable destModified = destProps.get(ContentModel.PROP_MODIFIED); destModified instanceof Date &&
((Date)srcModified).getTime() <= ((Date)destModified).getTime())
log.debug ("srcModified :" + srcModified + "destModified :" + destModified); {
if(log.isDebugEnabled())
if(srcModified != null && {
destModified != null && log.debug("the modified date is the same or before - no need to send it:" + destContent.getContentUrl());
srcModified instanceof Date && }
destModified instanceof Date && }
((Date)srcModified).getTime() <= ((Date)destModified).getTime()) else
{ {
if(log.isDebugEnabled()) log.debug("require content for node : " + node.getNodeRef());
{ out.missingContent(node.getNodeRef(), propEntry.getKey(), TransferCommons.URLToPartName(srcContent.getContentUrl()));
log.debug("the modified date is the same - no need to send it:" + destContent.getContentUrl()); }
} }
} else
else {
{ // We don't have the property on the destination node
out.missingContent(node.getNodeRef(), propEntry.getKey(), TransferCommons.URLToPartName(srcContent.getContentUrl())); out.missingContent(node.getNodeRef(), propEntry.getKey(), TransferCommons.URLToPartName(srcContent.getContentUrl()));
} }
} } // content url not null
else } // value is content data
{ }
// We don't have the property on the destination node }
out.missingContent(node.getNodeRef(), propEntry.getKey(), TransferCommons.URLToPartName(srcContent.getContentUrl())); else
} {
} log.debug("Node does not exist on destination");
} /**
} * there is no corresponding node so all content properties are "missing."
else */
{ for (Map.Entry<QName, Serializable> propEntry : node.getProperties().entrySet())
/** {
* there is no corresponding node so all content properties are "missing." Serializable value = propEntry.getValue();
*/ if (log.isDebugEnabled())
for (Map.Entry<QName, Serializable> propEntry : node.getProperties().entrySet()) {
{ if (value == null)
Serializable value = propEntry.getValue(); {
if (log.isDebugEnabled()) log.debug("Received a null value for property " + propEntry.getKey());
{ }
if (value == null) }
{ if ((value != null) && ContentData.class.isAssignableFrom(value.getClass()))
log.debug("Received a null value for property " + propEntry.getKey()); {
} ContentData srcContent = (ContentData)value;
} if(srcContent.getContentUrl() != null && !srcContent.getContentUrl().isEmpty())
if ((value != null) && ContentData.class.isAssignableFrom(value.getClass())) {
{ //
ContentData content = (ContentData)value; out.missingContent(node.getNodeRef(), propEntry.getKey(), TransferCommons.URLToPartName(srcContent.getContentUrl()));
// }
out.missingContent(node.getNodeRef(), propEntry.getKey(), TransferCommons.URLToPartName(content.getContentUrl())); }
} }
} }
} }
}
protected void processHeader(TransferManifestHeader header)
protected void processHeader(TransferManifestHeader header) {
{ // T.B.D
// T.B.D }
}
/*
/* * (non-Javadoc)
* (non-Javadoc) *
* * @see org.alfresco.repo.transfer.manifest.TransferManifestProcessor#startTransferManifest()
* @see org.alfresco.repo.transfer.manifest.TransferManifestProcessor#startTransferManifest() */
*/ protected void startManifest()
protected void startManifest() {
{ log.debug("Start Requsite");
log.debug("Start Requsite"); out.startTransferRequsite();
out.startTransferRequsite(); }
}
/**
/** * @param nodeService
* @param nodeService * the nodeService to set
* the nodeService to set */
*/ public void setNodeService(NodeService nodeService)
public void setNodeService(NodeService nodeService) {
{ this.nodeService = nodeService;
this.nodeService = nodeService; }
}
/**
/** * @param nodeResolver
* @param nodeResolver * the nodeResolver to set
* the nodeResolver to set */
*/ public void setNodeResolver(CorrespondingNodeResolver nodeResolver)
public void setNodeResolver(CorrespondingNodeResolver nodeResolver) {
{ this.nodeResolver = nodeResolver;
this.nodeResolver = nodeResolver; }
} }
}

View File

@@ -21,15 +21,23 @@ package org.alfresco.repo.transfer;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map;
import java.util.Queue; import java.util.Queue;
import java.util.Set; import java.util.Set;
import javax.transaction.Status;
import javax.transaction.UserTransaction; import javax.transaction.UserTransaction;
import javax.xml.XMLConstants; import javax.xml.XMLConstants;
import javax.xml.transform.Source; import javax.xml.transform.Source;
@@ -47,6 +55,7 @@ import org.alfresco.service.cmr.action.ActionService;
import org.alfresco.service.cmr.lock.LockService; import org.alfresco.service.cmr.lock.LockService;
import org.alfresco.service.cmr.lock.LockType; import org.alfresco.service.cmr.lock.LockType;
import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.service.cmr.repository.ContentWriter;
@@ -614,18 +623,20 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
* Step 2: Update Node title property * Step 2: Update Node title property
* transfer * transfer
* *
* Step 3: Update Content property * Step 3: Update Content property (add content)
* transfer * transfer
* *
* Step 4: Transfer again * Step 4: Transfer again
* transfer (Should transfer but not request the content item) * transfer (Should transfer but not request the content item)
*
* Step 5: Delete the node
* *
* Step 6: Negative test : transfer no nodes * Step 5: Update Content property (update content)
*
* Step 6: Delete the node
*
* Step 7: Negative test : transfer no nodes
* transfer (should throw exception) * transfer (should throw exception)
* *
* Step 7: Negative test : transfer to a disabled transfer target * Step 8: Negative test : transfer to a disabled transfer target
* transfer (should throw exception) * transfer (should throw exception)
* *
* This is a unit test so it does some shenanigans to send to the same instance of alfresco. * This is a unit test so it does some shenanigans to send to the same instance of alfresco.
@@ -637,7 +648,8 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
String CONTENT_TITLE = "ContentTitle"; String CONTENT_TITLE = "ContentTitle";
String CONTENT_TITLE_UPDATED = "ContentTitleUpdated"; String CONTENT_TITLE_UPDATED = "ContentTitleUpdated";
Locale CONTENT_LOCALE = Locale.GERMAN; Locale CONTENT_LOCALE = Locale.GERMAN;
String CONTENT_STRING = "Hello"; String CONTENT_STRING = "Hello World";
String CONTENT_UPDATE_STRING = "Foo Bar";
/** /**
* For unit test * For unit test
@@ -801,17 +813,28 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
// Check injected transferred aspect. // Check injected transferred aspect.
assertNotNull("transferredAspect", (String)nodeService.getProperty(destNodeRef, TransferModel.PROP_REPOSITORY_ID)); assertNotNull("transferredAspect", (String)nodeService.getProperty(destNodeRef, TransferModel.PROP_REPOSITORY_ID));
ContentWriter writer = contentService.getWriter(contentNodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
} }
finally finally
{ {
endTransaction(); endTransaction();
} }
logger.debug("Transfer again - this is an update with new content"); /**
* Step 3 - update to add content
*/
startNewTransaction();
try
{
ContentWriter writer = contentService.getWriter(contentNodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
}
finally
{
endTransaction();
}
logger.debug("Transfer again - this is an update to add new content");
startNewTransaction(); startNewTransaction();
try try
{ {
@@ -831,7 +854,20 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
{ {
endTransaction(); endTransaction();
} }
startNewTransaction();
try
{
ContentReader reader = contentService.getReader(destNodeRef, ContentModel.PROP_CONTENT);
assertNotNull("reader is null", reader);
String contentStr = reader.getContentString();
assertEquals("Content is wrong", contentStr, CONTENT_STRING);
}
finally
{
endTransaction();
}
/** /**
* Step 4: * Step 4:
* Now transfer nothing - content items do not need to be transferred since its already on * Now transfer nothing - content items do not need to be transferred since its already on
@@ -861,6 +897,11 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
assertEquals("title is wrong", (String)nodeService.getProperty(destNodeRef, ContentModel.PROP_TITLE), CONTENT_TITLE_UPDATED); assertEquals("title is wrong", (String)nodeService.getProperty(destNodeRef, ContentModel.PROP_TITLE), CONTENT_TITLE_UPDATED);
assertEquals("type is wrong", nodeService.getType(contentNodeRef), nodeService.getType(destNodeRef)); assertEquals("type is wrong", nodeService.getType(contentNodeRef), nodeService.getType(destNodeRef));
ContentReader reader = contentService.getReader(destNodeRef, ContentModel.PROP_CONTENT);
assertNotNull("reader is null", reader);
String contentStr = reader.getContentString();
assertEquals("Content is wrong", contentStr, CONTENT_STRING);
// Check injected transferred aspect. // Check injected transferred aspect.
assertNotNull("transferredAspect", (String)nodeService.getProperty(destNodeRef, TransferModel.PROP_REPOSITORY_ID)); assertNotNull("transferredAspect", (String)nodeService.getProperty(destNodeRef, TransferModel.PROP_REPOSITORY_ID));
@@ -869,12 +910,61 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
{ {
endTransaction(); endTransaction();
} }
/**
* Step 5 - update content through transfer
*/
startNewTransaction();
try
{
ContentWriter writer = contentService.getWriter(contentNodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_UPDATE_STRING);
}
finally
{
endTransaction();
}
logger.debug("Transfer again - this is an update to add new content");
startNewTransaction();
try
{
/**
* Step 3:
* Transfer our node again - so this is an update
*/
{
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(contentNodeRef);
definition.setNodes(nodes);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
ContentReader reader = contentService.getReader(destNodeRef, ContentModel.PROP_CONTENT);
assertNotNull("reader is null", reader);
String contentStr = reader.getContentString();
assertEquals("Content is wrong", CONTENT_UPDATE_STRING, contentStr);
}
finally
{
endTransaction();
}
/** /**
* Step 5 * Step 6
* Delete the node through transfer of the archive node * Delete the node through transfer of the archive node
*/ */
logger.debug("Transfer again - with no new content"); logger.debug("Transfer again - to delete a node through transferring an archive node");
startNewTransaction(); startNewTransaction();
try try
{ {
@@ -912,7 +1002,7 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
} }
/** /**
* Step 6 * Step 7
* Negative test transfer nothing * Negative test transfer nothing
*/ */
logger.debug("Transfer again - with no content - should throw exception"); logger.debug("Transfer again - with no content - should throw exception");
@@ -1882,6 +1972,8 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
} }
finally finally
{ {
int status = trx.getStatus();
trx.commit(); trx.commit();
} }
} }
@@ -2022,7 +2114,7 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
} // test async cancel } // test async cancel
/** /**
* Test the transfer report. * Test the transfer report.
* *
* This is a unit test so it does some shenanigans to send to the same instance of alfresco. * This is a unit test so it does some shenanigans to send to the same instance of alfresco.
@@ -2294,6 +2386,24 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
endTransaction(); endTransaction();
} }
} // test transfer report } // test transfer report
private void dumpToSystemOut(NodeRef nodeRef) throws IOException
{
ContentReader reader2 = contentService.getReader(nodeRef, ContentModel.PROP_CONTENT);
assertNotNull("transfer reader is null", reader2);
InputStream is = reader2.getContentInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String s = br.readLine();
while(s != null)
{
System.out.println(s);
s = br.readLine();
}
}
// /** // /**
// * Test the transfer method with big content - commented out since it takes a long time to run. // * Test the transfer method with big content - commented out since it takes a long time to run.
@@ -6746,8 +6856,247 @@ public class TransferServiceImplTest extends BaseAlfrescoSpringTest
} }
} // copy node } // copy node
/**
* Test the transfer method with regard to an empty content property. ALF-4865
*
* Step 1: create a node with an empty content property
* transfer
*
* Step 2: add non empty content property
* transfer
*
* Step 3: update to empty content property
* transfer
*
* This is a unit test so it does some shenanigans to send to the same instance of alfresco.
*/
public void testEmptyContent() throws Exception
{
setDefaultRollback(false);
String CONTENT_TITLE = "ContentTitle";
String CONTENT_TITLE_UPDATED = "ContentTitleUpdated";
Locale CONTENT_LOCALE = Locale.CANADA;
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.
*
* Fake Repository Id
*/
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)));
DescriptorService mockedDescriptorService = getMockDescriptorService(REPO_ID_A);
transferServiceImpl.setDescriptorService(mockedDescriptorService);
/**
* Now go ahead and create our first transfer target
*/
String targetName = "testTransferEmptyContent";
TransferTarget transferMe;
NodeRef contentNodeRef;
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 node with an empty content that we will read and write
*/
String name = GUID.generate();
ChildAssociationRef child = nodeService.createNode(guestHome, ContentModel.ASSOC_CONTAINS, QName.createQName(name), ContentModel.TYPE_CONTENT);
contentNodeRef = child.getChildRef();
nodeService.setProperty(contentNodeRef, ContentModel.PROP_TITLE, CONTENT_TITLE);
nodeService.setProperty(contentNodeRef, ContentModel.PROP_NAME, name);
ContentData cd = new ContentData(null, null, 0, null);
nodeService.setProperty(contentNodeRef, ContentModel.PROP_CONTENT, cd);
if(!transferService.targetExists(targetName))
{
transferMe = createTransferTarget(targetName);
}
else
{
transferMe = transferService.getTransferTarget(targetName);
}
transferService.enableTransferTarget(targetName, true);
}
finally
{
endTransaction();
}
logger.debug("First transfer - create new node (empty content)");
startNewTransaction();
try
{
ContentReader reader = contentService.getReader(contentNodeRef, ContentModel.PROP_CONTENT);
assertNull("test setup content reader not null", reader);
Map<QName, Serializable> props = nodeService.getProperties(contentNodeRef);
assertTrue(props.containsKey(ContentModel.PROP_CONTENT));
/**
* Step 1: Transfer our node which has empty content
*/
{
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(contentNodeRef);
definition.setNodes(nodes);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
NodeRef destinationNodeRef = testNodeFactory.getMappedNodeRef(contentNodeRef);
assertTrue("content node (dest) does not exist", nodeService.exists(destinationNodeRef));
ContentReader reader = contentService.getReader(destinationNodeRef, ContentModel.PROP_CONTENT);
assertNull("content reader not null", reader);
Map<QName, Serializable> props = nodeService.getProperties(destinationNodeRef);
assertTrue(props.containsKey(ContentModel.PROP_CONTENT));
}
finally
{
endTransaction();
}
/**
* Step 2
*/
logger.debug("Second transfer - replace empty content");
startNewTransaction();
try
{
ContentWriter writer = contentService.getWriter(contentNodeRef, ContentModel.PROP_CONTENT, true);
writer.setLocale(CONTENT_LOCALE);
writer.putContent(CONTENT_STRING);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
ContentReader reader = contentService.getReader(contentNodeRef, ContentModel.PROP_CONTENT);
assertNotNull("test setup content reader not null", reader);
Map<QName, Serializable> props = nodeService.getProperties(contentNodeRef);
assertTrue(props.containsKey(ContentModel.PROP_CONTENT));
/**
* Step 2: replace empty content with new content
*/
{
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(contentNodeRef);
definition.setNodes(nodes);
transferService.transfer(targetName, definition);
}
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
NodeRef destinationNodeRef = testNodeFactory.getMappedNodeRef(contentNodeRef);
ContentReader reader = contentService.getReader(destinationNodeRef, ContentModel.PROP_CONTENT);
assertNotNull("content reader is null", reader);
assertTrue("content does not exist", reader.exists());
}
finally
{
endTransaction();
}
/**
* Step 3
*/
logger.debug("Third transfer - remove existing content");
startNewTransaction();
try
{
ContentData cd = new ContentData(null, null, 0, null);
nodeService.setProperty(contentNodeRef, ContentModel.PROP_CONTENT, cd);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
ContentReader reader = contentService.getReader(contentNodeRef, ContentModel.PROP_CONTENT);
assertNull("test setup content reader not null", reader);
Map<QName, Serializable> props = nodeService.getProperties(contentNodeRef);
assertTrue(props.containsKey(ContentModel.PROP_CONTENT));
/**
* Step 3: Transfer our node which has empty content to over-write existing
* content
*/
TransferDefinition definition = new TransferDefinition();
Set<NodeRef>nodes = new HashSet<NodeRef>();
nodes.add(contentNodeRef);
definition.setNodes(nodes);
transferService.transfer(targetName, definition);
}
finally
{
endTransaction();
}
startNewTransaction();
try
{
NodeRef destinationNodeRef = testNodeFactory.getMappedNodeRef(contentNodeRef);
assertTrue("content node (dest) does not exist", nodeService.exists(destinationNodeRef));
ContentReader reader = contentService.getReader(destinationNodeRef, ContentModel.PROP_CONTENT);
assertNull("content reader not null", reader);
Map<QName, Serializable> props = nodeService.getProperties(destinationNodeRef);
assertTrue(props.containsKey(ContentModel.PROP_CONTENT));
}
finally
{
endTransaction();
}
}
private void createUser(String userName, String password) private void createUser(String userName, String password)
{ {