diff --git a/amps/share-services/src/main/resources/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/action/unzip-to.post.json.js b/amps/share-services/src/main/resources/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/action/unzip-to.post.json.js index ca0a33a309..d34c581b0e 100644 --- a/amps/share-services/src/main/resources/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/action/unzip-to.post.json.js +++ b/amps/share-services/src/main/resources/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/action/unzip-to.post.json.js @@ -80,6 +80,11 @@ function runAction(p_params) { result.fileExist = true; } + if (error.indexOf("FolderExistsException") != -1) + { + result.fileExist = true; + result.type = "folder"; + } } results.push(result); diff --git a/repository/src/main/java/org/alfresco/repo/action/executer/ImporterActionExecuter.java b/repository/src/main/java/org/alfresco/repo/action/executer/ImporterActionExecuter.java index b0b93c7172..4459873452 100644 --- a/repository/src/main/java/org/alfresco/repo/action/executer/ImporterActionExecuter.java +++ b/repository/src/main/java/org/alfresco/repo/action/executer/ImporterActionExecuter.java @@ -58,6 +58,7 @@ import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.model.FileExistsException; import org.alfresco.service.cmr.model.FileFolderService; import org.alfresco.service.cmr.model.FileInfo; +import org.alfresco.service.cmr.model.FolderExistsException; import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.ContentWriter; @@ -366,7 +367,11 @@ public class ImporterActionExecuter extends ActionExecuterAbstractBase catch (FileExistsException e) { // TODO: add failed file info to status message? - throw new AlfrescoRuntimeException("Failed to process ZIP file.", e); + if (e.getType().equalsIgnoreCase("folder")) + { + throw new FolderExistsException(root, file.getName()); + } + throw e; } } } diff --git a/repository/src/main/java/org/alfresco/repo/model/filefolder/FileFolderServiceImpl.java b/repository/src/main/java/org/alfresco/repo/model/filefolder/FileFolderServiceImpl.java index fef6163644..e9290280b1 100644 --- a/repository/src/main/java/org/alfresco/repo/model/filefolder/FileFolderServiceImpl.java +++ b/repository/src/main/java/org/alfresco/repo/model/filefolder/FileFolderServiceImpl.java @@ -63,13 +63,7 @@ import org.alfresco.repo.security.permissions.PermissionCheckedValue.PermissionC import org.alfresco.service.Auditable; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.dictionary.DictionaryService; -import org.alfresco.service.cmr.model.FileExistsException; -import org.alfresco.service.cmr.model.FileFolderService; -import org.alfresco.service.cmr.model.FileFolderServiceType; -import org.alfresco.service.cmr.model.FileFolderUtil; -import org.alfresco.service.cmr.model.FileInfo; -import org.alfresco.service.cmr.model.FileNotFoundException; -import org.alfresco.service.cmr.model.SubFolderFilter; +import org.alfresco.service.cmr.model.*; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.ContentReader; @@ -1314,7 +1308,7 @@ public class FileFolderServiceImpl extends AbstractBaseCopyService implements Fi } catch (DuplicateChildNodeNameException e) { - throw new FileExistsException(parentNodeRef, name); + throw new FileExistsException(parentNodeRef, name, typeQName.getLocalName()); } NodeRef nodeRef = assocRef.getChildRef(); diff --git a/repository/src/main/java/org/alfresco/service/cmr/model/FileExistsException.java b/repository/src/main/java/org/alfresco/service/cmr/model/FileExistsException.java index f8be1e758e..007f7eab46 100644 --- a/repository/src/main/java/org/alfresco/service/cmr/model/FileExistsException.java +++ b/repository/src/main/java/org/alfresco/service/cmr/model/FileExistsException.java @@ -43,6 +43,7 @@ public class FileExistsException extends AlfrescoRuntimeException private NodeRef parentNodeRef; private String name; + private String type; public FileExistsException(NodeRef parentNodeRef, String name) { @@ -51,6 +52,14 @@ public class FileExistsException extends AlfrescoRuntimeException this.name = name; } + public FileExistsException(NodeRef parentNodeRef, String name, String type) + { + super(MESSAGE_ID, new Object[]{name}); + this.parentNodeRef = parentNodeRef; + this.name = name; + this.type = type; + } + public NodeRef getParentNodeRef() { return parentNodeRef; @@ -60,4 +69,9 @@ public class FileExistsException extends AlfrescoRuntimeException { return name; } + + public String getType() + { + return type; + } } diff --git a/repository/src/main/java/org/alfresco/service/cmr/model/FolderExistsException.java b/repository/src/main/java/org/alfresco/service/cmr/model/FolderExistsException.java new file mode 100644 index 0000000000..724ab96b97 --- /dev/null +++ b/repository/src/main/java/org/alfresco/service/cmr/model/FolderExistsException.java @@ -0,0 +1,62 @@ +/* + * #%L + * Alfresco Repository + * %% + * Copyright (C) 2005 - 2016 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * 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 . + * #L% + */ +package org.alfresco.service.cmr.model; + +import org.alfresco.api.AlfrescoPublicApi; +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.service.cmr.repository.NodeRef; + +/** + * Common exception thrown when an operation fails because of a name clash of folder. + * + */ +@AlfrescoPublicApi +public class FolderExistsException extends AlfrescoRuntimeException +{ + private static final String MESSAGE_ID = "file_folder_service.file_exists_message"; + + private static final long serialVersionUID = -4133713912784624118L; + + private NodeRef parentNodeRef; + private String name; + + public FolderExistsException(NodeRef parentNodeRef, String name) + { + super(MESSAGE_ID, new Object[]{name}); + this.parentNodeRef = parentNodeRef; + this.name = name; + } + + public NodeRef getParentNodeRef() + { + return parentNodeRef; + } + + public String getName() + { + return name; + } +} diff --git a/repository/src/test/java/org/alfresco/repo/action/executer/ImporterActionExecuterTest.java b/repository/src/test/java/org/alfresco/repo/action/executer/ImporterActionExecuterTest.java index f636f9f8b1..7489d77408 100644 --- a/repository/src/test/java/org/alfresco/repo/action/executer/ImporterActionExecuterTest.java +++ b/repository/src/test/java/org/alfresco/repo/action/executer/ImporterActionExecuterTest.java @@ -25,10 +25,7 @@ */ package org.alfresco.repo.action.executer; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; +import static org.junit.Assert.*; import java.io.File; import java.io.IOException; @@ -48,6 +45,7 @@ import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.action.Action; +import org.alfresco.service.cmr.model.FolderExistsException; import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.service.cmr.repository.NodeRef; @@ -340,6 +338,49 @@ public class ImporterActionExecuterTest }); } + @Test + public void testDuplicateUnzipping() throws IOException + { + final RetryingTransactionHelper retryingTransactionHelper = serviceRegistry.getRetryingTransactionHelper(); + + retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback() { + @Override + public Void execute() throws Throwable + + { + NodeRef rootNodeRef = nodeService.getRootNode(storeRef); + + // create test data + NodeRef zipFileNodeRef = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, ContentModel.ASSOC_CHILDREN, ContentModel.TYPE_CONTENT).getChildRef(); + NodeRef targetFolderNodeRef = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, ContentModel.ASSOC_CHILDREN, ContentModel.TYPE_FOLDER).getChildRef(); + + putContent(zipFileNodeRef, "import-archive-test/accentCharTestZip.zip"); + + Action action = createAction(zipFileNodeRef, "ImporterActionExecuterTestActionDefinition", targetFolderNodeRef); + + try + { + importerActionExecuter.setUncompressedBytesLimit("100000"); + importerActionExecuter.execute(action, zipFileNodeRef); + // unzip again to duplicate node + importerActionExecuter.execute(action, zipFileNodeRef); + } + catch (FolderExistsException e) + { + assertTrue(e.getMessage().contains("File or folder accentCharTestZip already exists")); + } + finally + { + // clean test data + nodeService.deleteNode(targetFolderNodeRef); + nodeService.deleteNode(zipFileNodeRef); + } + + return null; + } + }); + } + private void putContent(NodeRef zipFileNodeRef, String resource) { URL url = AbstractContentTransformerTest.class.getClassLoader().getResource(resource);