diff --git a/source/java/org/alfresco/repo/imap/AlfrescoImapFolder.java b/source/java/org/alfresco/repo/imap/AlfrescoImapFolder.java index 50b3fdcf5e..6b0d65e52c 100644 --- a/source/java/org/alfresco/repo/imap/AlfrescoImapFolder.java +++ b/source/java/org/alfresco/repo/imap/AlfrescoImapFolder.java @@ -317,7 +317,11 @@ public class AlfrescoImapFolder extends AbstractImapFolder implements Serializab NodeRef sourceNodeRef = extractNodeRef(message); if (isMoveOperation(sourceNodeRef)) { - uid = moveNode(this.folderInfo, message, flags, sourceNodeRef); + uid = copyOrmoveNode(this.folderInfo, message, flags, sourceNodeRef, true); + } + else if (sourceNodeRef != null) + { + uid = copyOrmoveNode(this.folderInfo, message, flags, sourceNodeRef, false); } else { @@ -341,13 +345,21 @@ public class AlfrescoImapFolder extends AbstractImapFolder implements Serializab * @throws FileNotFoundException */ @SuppressWarnings("deprecation") - private long moveNode(FileInfo folderInfo, MimeMessage message, Flags flags, NodeRef sourceNodeRef) + private long copyOrmoveNode(FileInfo folderInfo, MimeMessage message, Flags flags, NodeRef sourceNodeRef, boolean move) throws FileExistsException, FileNotFoundException { FileFolderService fileFolderService = serviceRegistry.getFileFolderService(); FileFilterMode.setClient(FileFilterMode.Client.imap); fileFolderService.setHidden(sourceNodeRef, false); - FileInfo messageFile = fileFolderService.move(sourceNodeRef, folderInfo.getNodeRef(), null); + FileInfo messageFile = null; + if (move) + { + messageFile = fileFolderService.move(sourceNodeRef, folderInfo.getNodeRef(), null); + } + else + { + messageFile = fileFolderService.copy(sourceNodeRef, folderInfo.getNodeRef(), null); + } final long newMessageUid = (Long) messageFile.getProperties().get(ContentModel.PROP_NODE_DBID); imapService.setFlag(messageFile, Flag.RECENT, true); imapService.setFlag(messageFile, Flag.DELETED, false); @@ -367,6 +379,7 @@ public class AlfrescoImapFolder extends AbstractImapFolder implements Serializab String uuid = null; String messageId = null; NodeRef result = null; + NodeService nodeService = serviceRegistry.getNodeService(); try { messageId = message.getMessageID(); @@ -391,6 +404,28 @@ public class AlfrescoImapFolder extends AbstractImapFolder implements Serializab uuid = messageId; } result = new NodeRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore", uuid); + if (nodeService.exists(result) == false) + { + result = null; + } + } + + if(result == null) + { + //check X-Alfresco-NodeRef-ID header + try + { + uuid = message.getHeader(AlfrescoImapConst.X_ALF_NODEREF_ID)[0]; + result = new NodeRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore", uuid); + if (nodeService.exists(result) == false) + { + result = null; + } + } + catch (MessagingException e) + { + //Do nothing + } } return result; } diff --git a/source/test-java/org/alfresco/repo/imap/ImapServiceImplTest.java b/source/test-java/org/alfresco/repo/imap/ImapServiceImplTest.java index b4a3387b37..ad0caea97b 100644 --- a/source/test-java/org/alfresco/repo/imap/ImapServiceImplTest.java +++ b/source/test-java/org/alfresco/repo/imap/ImapServiceImplTest.java @@ -921,6 +921,56 @@ public class ImapServiceImplTest extends TestCase assertEquals("There should be only one node in the destination folder", 1, nodeService.getChildAssocs(destinationNode.getNodeRef()).size()); } + /** + * Test for MNT-12420 + * + * @throws Exception + */ + public void testMoveViaAppendAndDelete() throws Exception + { + AlfrescoImapUser poweredUser = new AlfrescoImapUser((USER_NAME + "@alfresco.com"), USER_NAME, USER_PASSWORD); + String fileName = "testfile" + GUID.generate(); + String destinationName = "testFolder" + GUID.generate(); + String destinationPath = IMAP_ROOT + AlfrescoImapConst.HIERARCHY_DELIMITER + destinationName; + String nodeContent = "test content"; + NodeRef root = findCompanyHomeNodeRef(); + AuthenticationUtil.setRunAsUserSystem(); + + // Create node and destination folder + FileInfo origFile = fileFolderService.create(root, fileName, ContentModel.TYPE_CONTENT); + ContentWriter contentWriter = contentService.getWriter(origFile.getNodeRef(), ContentModel.PROP_CONTENT, true); + contentWriter.setMimetype("text/plain"); + contentWriter.setEncoding("UTF-8"); + contentWriter.putContent(nodeContent); + + FileInfo destinationNode = fileFolderService.create(root, destinationName, ContentModel.TYPE_FOLDER); + nodeService.addAspect(origFile.getNodeRef(), ImapModel.ASPECT_IMAP_CONTENT, null); + nodeService.addAspect(origFile.getNodeRef(), ContentModel.ASPECT_TAGGABLE, null); + + // Save the message and set X-Alfresco-NodeRef-ID header + SimpleStoredMessage origMessage = imapService.getMessage(origFile); + origMessage.getMimeMessage().addHeader(AlfrescoImapConst.X_ALF_NODEREF_ID, origFile.getNodeRef().getId()); + origMessage.getMimeMessage().saveChanges(); + + // Append the message to destination + AlfrescoImapFolder destinationMailbox = imapService.getOrCreateMailbox(poweredUser, destinationPath, true, false); + long uuid = destinationMailbox.appendMessage(origMessage.getMimeMessage(), flags, null); + + // Delete the node + imapService.setFlag(origFile, Flags.Flag.DELETED, true); + imapService.expungeMessage(origFile); + + // Check the destination has copy of original file and only this file + FileInfo copiedNode = fileFolderService.getFileInfo(nodeService.getNodeRef(uuid)); + assertNotNull("The file should exist.", copiedNode); + assertEquals("The file name should not change.", fileName, copiedNode.getName()); + NodeRef copiedParentNodeRef = nodeService.getPrimaryParent(copiedNode.getNodeRef()).getParentRef(); + assertEquals("The parent should change to destination.", destinationNode.getNodeRef(), copiedParentNodeRef); + assertEquals("There should be only one node in the destination folder", 1, nodeService.getChildAssocs(destinationNode.getNodeRef()).size()); + assertTrue("New node should have original node aspects", nodeService.hasAspect(copiedNode.getNodeRef(), ContentModel.ASPECT_TAGGABLE)); + } + + /** * @param mailbox - {@link AlfrescoImapFolder} instance which should be checked */