MNT-21671 : Download as zip REST api does not include custom folders (#1090)

Add dictionaryService to CreateDwonloadArchiveAction
   ZipDownloadExporter constructor now required dictionaryService
   ZipDownloadExporter#startNode will include into archive all subclasses of node type cm:folder.
   Add a custom model and create a custom node in DownloadServiceIntegrationTest, this use case will be tested in DownloadServiceIntegrationTest#createDownload()
This commit is contained in:
Alexandru-Eusebiu Epure
2020-07-14 12:23:24 +03:00
committed by GitHub
parent ba76d3c0d9
commit 3a31ac3634
4 changed files with 86 additions and 15 deletions

View File

@@ -43,6 +43,7 @@ import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransacti
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.download.DownloadRequest;
import org.alfresco.service.cmr.download.DownloadStatus;
import org.alfresco.service.cmr.download.DownloadStatus.Status;
@@ -84,6 +85,7 @@ public class CreateDownloadArchiveAction extends ActionExecuterAbstractBase
private NodeService nodeService;
private RetryingTransactionHelper transactionHelper;
private DownloadStatusUpdateService updateService;
private DictionaryService dictionaryService;
private long maximumContentSize = -1l;
@@ -167,6 +169,11 @@ public class CreateDownloadArchiveAction extends ActionExecuterAbstractBase
this.updateService = updateService;
}
public void setDictionaryService(DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
/**
* Create an archive file containing content from the repository.
*
@@ -246,7 +253,7 @@ public class CreateDownloadArchiveAction extends ActionExecuterAbstractBase
{
// perform the actual export
final File tempFile = TempFileProvider.createTempFile(TEMP_FILE_PREFIX, TEMP_FILE_SUFFIX);
final ZipDownloadExporter handler = new ZipDownloadExporter(tempFile, checkOutCheckInService, nodeService, transactionHelper, updateService, downloadStorage, actionedUponNodeRef, estimator.getSize(), estimator.getFileCount());
final ZipDownloadExporter handler = new ZipDownloadExporter(tempFile, checkOutCheckInService, nodeService, transactionHelper, updateService, downloadStorage, dictionaryService, actionedUponNodeRef, estimator.getSize(), estimator.getFileCount());
try {
exporterService.exportView(handler, crawlerParameters, null);

View File

@@ -39,6 +39,7 @@ import org.alfresco.model.ContentModel;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.download.DownloadStatus;
import org.alfresco.service.cmr.download.DownloadStatus.Status;
import org.alfresco.service.cmr.repository.ContentData;
@@ -77,6 +78,7 @@ public class ZipDownloadExporter extends BaseExporter
private RetryingTransactionHelper transactionHelper;
private DownloadStorage downloadStorage;
private DictionaryService dictionaryService;
private DownloadStatusUpdateService updateService;
private Deque<Pair<String, NodeRef>> path = new LinkedList<Pair<String, NodeRef>>();
@@ -93,11 +95,12 @@ public class ZipDownloadExporter extends BaseExporter
* @param transactionHelper RetryingTransactionHelper
* @param updateService DownloadStatusUpdateService
* @param downloadStorage DownloadStorage
* @param dictionaryService DictionaryService
* @param downloadNodeRef NodeRef
* @param total long
* @param totalFileCount long
*/
public ZipDownloadExporter(File zipFile, CheckOutCheckInService checkOutCheckInService, NodeService nodeService, RetryingTransactionHelper transactionHelper, DownloadStatusUpdateService updateService, DownloadStorage downloadStorage, NodeRef downloadNodeRef, long total, long totalFileCount)
public ZipDownloadExporter(File zipFile, CheckOutCheckInService checkOutCheckInService, NodeService nodeService, RetryingTransactionHelper transactionHelper, DownloadStatusUpdateService updateService, DownloadStorage downloadStorage, DictionaryService dictionaryService, NodeRef downloadNodeRef, long total, long totalFileCount)
{
super(checkOutCheckInService, nodeService);
try
@@ -106,6 +109,7 @@ public class ZipDownloadExporter extends BaseExporter
this.updateService = updateService;
this.transactionHelper = transactionHelper;
this.downloadStorage = downloadStorage;
this.dictionaryService = dictionaryService;
this.downloadNodeRef = downloadNodeRef;
this.total = total;
@@ -134,7 +138,7 @@ public class ZipDownloadExporter extends BaseExporter
{
this.currentName = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
path.push(new Pair<String, NodeRef>(currentName, nodeRef));
if (ContentModel.TYPE_FOLDER.equals(nodeService.getType(nodeRef)))
if (dictionaryService.isSubClass(nodeService.getType(nodeRef), ContentModel.TYPE_FOLDER))
{
String path = getPath() + PATH_SEPARATOR;
ZipArchiveEntry archiveEntry = new ZipArchiveEntry(path);

View File

@@ -89,18 +89,19 @@
<bean id="downloadContentServiceHelper" class="org.alfresco.repo.download.LocalContentServiceHelper">
<property name="contentService" ref="contentService"/>
</bean>
<bean id="createDownloadArchiveAction" class="org.alfresco.repo.download.CreateDownloadArchiveAction" parent="action-executer">
<property name="checkOutCheckInSerivce" ref="checkOutCheckInService"/>
<property name="contentServiceHelper" ref="downloadContentServiceHelper" />
<property name="downloadStorage" ref="downloadStorage" />
<property name="exporterService" ref="downloadExporterComponent" />
<property name="maximumContentSize" value="${download.maxContentSize}" />
<property name="nodeService" ref="nodeService" />
<property name="publicAction" value="false"/>
<property name="transactionHelper" ref="retryingTransactionHelper"/>
<property name="updateService" ref="downloadStatusUpdateService"/>
</bean>
<bean id="createDownloadArchiveAction" class="org.alfresco.repo.download.CreateDownloadArchiveAction" parent="action-executer">
<property name="checkOutCheckInSerivce" ref="checkOutCheckInService"/>
<property name="contentServiceHelper" ref="downloadContentServiceHelper"/>
<property name="downloadStorage" ref="downloadStorage"/>
<property name="exporterService" ref="downloadExporterComponent"/>
<property name="maximumContentSize" value="${download.maxContentSize}"/>
<property name="nodeService" ref="nodeService"/>
<property name="publicAction" value="false"/>
<property name="transactionHelper" ref="retryingTransactionHelper"/>
<property name="updateService" ref="downloadStatusUpdateService"/>
<property name="dictionaryService" ref="dictionaryService"/>
</bean>
<bean id="downloadExporterComponent" parent="exporterComponent">
<property name="exportSecondaryNodes" value="true"/>

View File

@@ -34,6 +34,7 @@ import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.cmr.admin.RepoAdminService;
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
import org.alfresco.service.cmr.download.DownloadService;
import org.alfresco.service.cmr.download.DownloadStatus;
@@ -69,8 +70,11 @@ import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.rules.RuleChain;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -123,6 +127,7 @@ public class DownloadServiceIntegrationTest
private static PermissionService PERMISSION_SERVICE;
private static RetryingTransactionHelper TRANSACTION_HELPER;
private static IntegrityChecker INTEGRITY_CHECKER;
private static RepoAdminService REPO_ADMIN_SERVICE;
// Test Content
private NodeRef rootFolder;
@@ -136,6 +141,41 @@ public class DownloadServiceIntegrationTest
private Set<String> allEntries;
private NodeRef fileToCheckout;
// MNT-21671 Download as zip does not include custom folders.
// Define a custom model that is child of cm:folder
private static final String CUSTOM_FOLDER_MODEL_XML =
"<model name=\"custom:customModel\" xmlns=\"http://www.alfresco.org/model/dictionary/1.0\">" +
" <description>Custom Model</description>" +
" <author></author>" +
" <version>1.0</version>" +
" <imports>" +
" <import uri=\"http://www.alfresco.org/model/dictionary/1.0\" prefix=\"d\"/>" +
" <import uri=\"http://www.alfresco.org/model/content/1.0\" prefix=\"cm\"/>" +
" </imports>" +
" <namespaces>" +
" <namespace uri=\"custom.model\" prefix=\"custom\"/>" +
" </namespaces>" +
" <types>" +
" <type name=\"custom:folderx\">" +
" <title>Custom FolderX</title>" +
" <parent>cm:folder</parent>" +
" <properties>" +
" <property name=\"custom:invoice\">" +
" <type>d:text</type>" +
" </property>" +
" </properties>" +
" <associations>" +
" </associations>" +
" </type>" +
" </types>" +
" <aspects>" +
" </aspects>" +
"</model>";
@BeforeClass public static void init()
{
@@ -151,6 +191,7 @@ public class DownloadServiceIntegrationTest
INTEGRITY_CHECKER.setEnabled(true);
INTEGRITY_CHECKER.setFailOnViolation(true);
INTEGRITY_CHECKER.setTraceOn(true);
REPO_ADMIN_SERVICE = APP_CONTEXT_INIT.getApplicationContext().getBean("RepoAdminService", RepoAdminService.class);
}
/**
@@ -203,6 +244,24 @@ public class DownloadServiceIntegrationTest
allEntries.add("rootFolder/level1Folder2/fileToCheckout.txt");
PERMISSION_SERVICE.setPermission(level1Folder2, TEST_USER.getUsername(), PermissionService.ALL_PERMISSIONS, true);
PERMISSION_SERVICE.setPermission(fileToCheckout, TEST_USER.getUsername(), PermissionService.ALL_PERMISSIONS, true);
// MNT-21671 Download as zip does not include custom folders.
// deploy custom model
final String modelFileName1 = "model-MNT-21671.xml";
InputStream modelStream = null;
try
{
modelStream = new ByteArrayInputStream(CUSTOM_FOLDER_MODEL_XML.getBytes("UTF-8"));
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
REPO_ADMIN_SERVICE.deployModel(modelStream, modelFileName1);
final QName customFolderType = QName.createQName("{custom.model}folderx");
testNodes.createNode(rootFolder, "level1CustomFolder", customFolderType, AuthenticationUtil.getAdminUserName());
allEntries.add("rootFolder/level1CustomFolder/");
}
@Test public void createDownload() throws IOException, InterruptedException