diff --git a/source/java/org/alfresco/repo/web/scripts/content/StreamArchive.java b/source/java/org/alfresco/repo/web/scripts/content/StreamACP.java similarity index 52% rename from source/java/org/alfresco/repo/web/scripts/content/StreamArchive.java rename to source/java/org/alfresco/repo/web/scripts/content/StreamACP.java index 637332a54a..34a2e1fc92 100644 --- a/source/java/org/alfresco/repo/web/scripts/content/StreamArchive.java +++ b/source/java/org/alfresco/repo/web/scripts/content/StreamACP.java @@ -53,19 +53,24 @@ import org.json.JSONObject; import org.json.JSONTokener; /** - * Base class for Java backed webscripts that wish to stream the contents - * of an archive back to the caller. + * Base class for Java backed webscripts that wish to generate an ACP and + * stream the contents back to the caller. + *

+ * The default implementation generates an ACP file containing the provided + * NodeRefs and all their respective children. * * @author Gavin Cornwell */ -public class StreamArchive extends StreamContent +public class StreamACP extends StreamContent { /** Logger */ - private static Log logger = LogFactory.getLog(StreamArchive.class); + private static Log logger = LogFactory.getLog(StreamACP.class); protected static final String TEMP_FILE_PREFIX = "export_"; - protected static final String PARAM_NODE_REFS = "nodeRefs"; protected static final String MULTIPART_FORMDATA = "multipart/form-data"; + protected static final String ZIP_EXTENSION = "zip"; + + protected static final String PARAM_NODE_REFS = "nodeRefs"; protected ExporterService exporterService; @@ -84,8 +89,7 @@ public class StreamArchive extends StreamContent */ public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException { - JSONObject json = null; - File tempArchiveFile = null; + File tempACPFile = null; try { NodeRef[] nodeRefs = null; @@ -93,60 +97,30 @@ public class StreamArchive extends StreamContent if (MULTIPART_FORMDATA.equals(contentType)) { // get nodeRefs parameter from form - String nodeRefsParam = req.getParameter(PARAM_NODE_REFS); - - // check the list of NodeRefs is present - if (nodeRefsParam == null) - { - throw new WebScriptException(Status.STATUS_BAD_REQUEST, - "Mandatory 'nodeRefs' parameter was not provided in form data"); - } - - List listNodeRefs = new ArrayList(8); - StringTokenizer tokenizer = new StringTokenizer(nodeRefsParam, ","); - while (tokenizer.hasMoreTokens()) - { - listNodeRefs.add(new NodeRef(tokenizer.nextToken().trim())); - } - - nodeRefs = new NodeRef[listNodeRefs.size()]; - nodeRefs = listNodeRefs.toArray(nodeRefs); + nodeRefs = getNodeRefs(req.getParameter(PARAM_NODE_REFS)); } else { - // presume the request is a JSON request so get JSON body - json = new JSONObject(new JSONTokener(req.getContent().getContent())); - - // check the list of NodeRefs is present - if (!json.has(PARAM_NODE_REFS)) - { - throw new WebScriptException(Status.STATUS_BAD_REQUEST, - "Mandatory 'nodeRefs' parameter was not provided in request body"); - } - - JSONArray jsonArray = json.getJSONArray(PARAM_NODE_REFS); - if (jsonArray.length() != 0) - { - // build the list of NodeRefs - nodeRefs = new NodeRef[jsonArray.length()]; - for (int i = 0; i < jsonArray.length(); i++) - { - NodeRef nodeRef = new NodeRef(jsonArray.getString(i)); - nodeRefs[i] = nodeRef; - } - } + // presume the request is a JSON request so get nodeRefs from JSON body + nodeRefs = getNodeRefs(new JSONObject(new JSONTokener(req.getContent().getContent()))); } - // create an archive of the nodes - tempArchiveFile = createArchive(nodeRefs); + // setup the ACP parameters + ExporterCrawlerParameters params = new ExporterCrawlerParameters(); + params.setCrawlSelf(true); + params.setCrawlChildNodes(true); + params.setExportFrom(new Location(nodeRefs)); + + // create an ACP of the nodes + tempACPFile = createACP(params, ACPExportPackageHandler.ACP_EXTENSION, false); - // stream the archive back to the client as an attachment (forcing save as) - streamContent(req, res, tempArchiveFile, true, tempArchiveFile.getName()); + // stream the ACP back to the client as an attachment (forcing save as) + streamContent(req, res, tempACPFile, true, tempACPFile.getName()); } - catch (IOException iox) + catch (IOException ioe) { throw new WebScriptException(Status.STATUS_BAD_REQUEST, - "Could not read content from req.", iox); + "Could not read content from req.", ioe); } catch (JSONException je) { @@ -156,67 +130,102 @@ public class StreamArchive extends StreamContent finally { // try and delete the temporary file - if (tempArchiveFile != null) + if (tempACPFile != null) { - tempArchiveFile.delete(); + tempACPFile.delete(); if (logger.isDebugEnabled()) - logger.debug("Deleted temporary archive: " + tempArchiveFile.getAbsolutePath()); + logger.debug("Deleted temporary archive: " + tempACPFile.getAbsolutePath()); } } } /** - * Returns an Alfresco archive file containing the nodes represented - * by the given list of NodeRefs. + * Converts the given comma delimited string of NodeRefs to an array + * of NodeRefs. If the string is null a WebScriptException is thrown. * - * @param nodeRefs List of nodes to create archive from - * @return File object representing the created archive + * @param nodeRefsParam Comma delimited string of NodeRefs + * @return Array of NodeRef objects */ - protected File createArchive(List nodeRefs) + protected NodeRef[] getNodeRefs(String nodeRefsParam) { - NodeRef[] nodeRefArr = new NodeRef[nodeRefs.size()]; - return createArchive(nodeRefs.toArray(nodeRefArr)); + // check the list of NodeRefs is present + if (nodeRefsParam == null) + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, + "Mandatory 'nodeRefs' parameter was not provided in form data"); + } + + List listNodeRefs = new ArrayList(8); + StringTokenizer tokenizer = new StringTokenizer(nodeRefsParam, ","); + while (tokenizer.hasMoreTokens()) + { + listNodeRefs.add(new NodeRef(tokenizer.nextToken().trim())); + } + + NodeRef[] nodeRefs = new NodeRef[listNodeRefs.size()]; + nodeRefs = listNodeRefs.toArray(nodeRefs); + + return nodeRefs; } /** - * Returns an Alfresco archive file containing the nodes represented - * by the given list of NodeRefs. + * Attempts to retrieve and convert a JSON array of + * NodeRefs from the given JSON object. If the nodeRefs + * property is not present a WebScriptException is thrown. * - * @param nodeRefs Array of nodes to create archive from - * @return File object representing the created archive + * @param nodeRefs Comma delimited string of NodeRefs + * @return Array of NodeRef objects */ - protected File createArchive(NodeRef[] nodeRefs) + protected NodeRef[] getNodeRefs(JSONObject json) throws JSONException + { + // check the list of NodeRefs is present + if (!json.has(PARAM_NODE_REFS)) + { + throw new WebScriptException(Status.STATUS_BAD_REQUEST, + "Mandatory 'nodeRefs' parameter was not provided in request body"); + } + + NodeRef[] nodeRefs = new NodeRef[0]; + JSONArray jsonArray = json.getJSONArray(PARAM_NODE_REFS); + if (jsonArray.length() != 0) + { + // build the list of NodeRefs + nodeRefs = new NodeRef[jsonArray.length()]; + for (int i = 0; i < jsonArray.length(); i++) + { + NodeRef nodeRef = new NodeRef(jsonArray.getString(i)); + nodeRefs[i] = nodeRef; + } + } + + return nodeRefs; + } + + /** + * Returns an ACP file containing the nodes represented by the given list of NodeRefs. + * + * @param params The parameters for the ACP exporter + * @param extension The file extenstion to use for the ACP file + * @param keepFolderStructure Determines whether the folder structure is maintained for + * the content inside the ACP file + * @return File object representing the created ACP + */ + protected File createACP(ExporterCrawlerParameters params, String extension, boolean keepFolderStructure) { try { - if (logger.isDebugEnabled()) - { - StringBuilder builder = new StringBuilder("Creating archive for "); - builder.append(nodeRefs.length); - builder.append(" nodes: "); - for (int idx = 0; idx < nodeRefs.length; idx++) - { - if (idx != 0) builder.append(", "); - builder.append(nodeRefs[idx]); - } - - logger.debug(builder.toString()); - } - // generate temp file and folder name File dataFile = new File(GUID.generate()); File contentDir = new File(GUID.generate()); // setup export package handler - File acpFile = TempFileProvider.createTempFile(TEMP_FILE_PREFIX, "." + ACPExportPackageHandler.ACP_EXTENSION); + File acpFile = TempFileProvider.createTempFile(TEMP_FILE_PREFIX, "." + extension); ACPExportPackageHandler handler = new ACPExportPackageHandler(new FileOutputStream(acpFile), dataFile, contentDir, this.mimetypeService); - - // setup parameters for export - ExporterCrawlerParameters params = setupCrawlerParameters(); - params.setExportFrom(new Location(nodeRefs)); - + handler.setExportAsFolders(keepFolderStructure); + handler.setNodeService(this.nodeService); + // perform the actual export this.exporterService.exportView(handler, params, null); @@ -231,23 +240,4 @@ public class StreamArchive extends StreamContent "Failed to create archive", fnfe); } } - - /** - * Creates and sets up a ExporterCrawlerParameters object to - * use to create the archive, subclasses can override this - * method to change the output of the generated archive. - *

- * NOTE: The location and includeContent flag will be setup - * after this method is called. - * - * @return ExporterCrawlerParameters object - */ - protected ExporterCrawlerParameters setupCrawlerParameters() - { - ExporterCrawlerParameters params = new ExporterCrawlerParameters(); - params.setCrawlSelf(true); - params.setCrawlChildNodes(true); - params.setCrawlAssociations(false); - return params; - } } \ No newline at end of file