Java tutorial
/* * #%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 <http://www.gnu.org/licenses/>. * #L% */ package org.alfresco.repo.exporter; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.MimetypeService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.Path; import org.alfresco.service.cmr.repository.Path.ChildAssocElement; import org.alfresco.service.cmr.view.ExportPackageHandler; import org.alfresco.service.cmr.view.ExporterException; import org.alfresco.util.TempFileProvider; import org.apache.commons.compress.archivers.zip.Zip64Mode; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream.UnicodeExtraFieldPolicy; /** * Handler for exporting Repository to ACP (Alfresco Content Package) file * * @author David Caruana */ public class ACPExportPackageHandler implements ExportPackageHandler { /** ACP File Extension */ public final static String ACP_EXTENSION = "acp"; protected MimetypeService mimetypeService; protected NodeService nodeService; protected OutputStream outputStream; protected File dataFile; protected File contentDir; protected File tempDataFile; protected OutputStream tempDataFileStream; protected ZipArchiveOutputStream zipStream; protected int iFileCnt = 0; protected boolean exportAsFolders; /** * Construct * * @param destDir File * @param zipFile File * @param dataFile File * @param contentDir File * @param overwrite boolean * @param mimetypeService MimetypeService */ public ACPExportPackageHandler(File destDir, File zipFile, File dataFile, File contentDir, boolean overwrite, MimetypeService mimetypeService) { try { // Ensure ACP file has appropriate ACP extension String zipFilePath = zipFile.getPath(); if (!zipFilePath.endsWith("." + ACP_EXTENSION)) { zipFilePath += (zipFilePath.charAt(zipFilePath.length() - 1) == '.') ? ACP_EXTENSION : "." + ACP_EXTENSION; } File absZipFile = new File(destDir, zipFilePath); log("Exporting to package zip file " + absZipFile.getAbsolutePath()); if (absZipFile.exists()) { if (overwrite == false) { throw new ExporterException( "Package zip file " + absZipFile.getAbsolutePath() + " already exists."); } log("Warning: Overwriting existing package zip file " + absZipFile.getAbsolutePath()); } this.outputStream = new FileOutputStream(absZipFile); this.dataFile = dataFile; this.contentDir = contentDir; this.mimetypeService = mimetypeService; } catch (FileNotFoundException e) { throw new ExporterException("Failed to create zip file", e); } } /** * Construct * * @param outputStream OutputStream * @param dataFile File * @param contentDir File * @param mimetypeService MimetypeService */ public ACPExportPackageHandler(OutputStream outputStream, File dataFile, File contentDir, MimetypeService mimetypeService) { this.outputStream = outputStream; this.dataFile = dataFile; this.contentDir = contentDir; this.mimetypeService = mimetypeService; } /** * @param nodeService NodeService */ public void setNodeService(NodeService nodeService) { this.nodeService = nodeService; } /** * Export content into folder structure of nodes * * @param exportAsFolders boolean */ public void setExportAsFolders(boolean exportAsFolders) { this.exportAsFolders = exportAsFolders; } /* (non-Javadoc) * @see org.alfresco.service.cmr.view.ExportPackageHandler#startExport() */ public void startExport() { // ALF-2016 zipStream = new ZipArchiveOutputStream(outputStream); // NOTE: This encoding allows us to workaround bug... // http://bugs.sun.com/bugdatabase/view_bug.do;:WuuT?bug_id=4820807 zipStream.setEncoding("UTF-8"); zipStream.setCreateUnicodeExtraFields(UnicodeExtraFieldPolicy.ALWAYS); zipStream.setUseLanguageEncodingFlag(true); zipStream.setFallbackToUTF8(true); zipStream.setUseZip64(Zip64Mode.Always); } /* (non-Javadoc) * @see org.alfresco.service.cmr.view.ExportPackageHandler#createDataStream() */ public OutputStream createDataStream() { tempDataFile = TempFileProvider.createTempFile("exportDataStream", ".xml"); try { tempDataFileStream = new FileOutputStream(tempDataFile); return tempDataFileStream; } catch (FileNotFoundException e) { throw new ExporterException("Failed to create data file stream", e); } } /* (non-Javadoc) * @see org.alfresco.service.cmr.view.ExportStreamHandler#exportStream(java.io.InputStream) */ public ContentData exportContent(InputStream content, ContentData contentData) { // if the content stream to output is empty, then just return content descriptor as is if (content == null) { return contentData; } // create zip entry for stream to export String contentDirPath = contentDir.getPath(); if (contentDirPath.charAt(contentDirPath.length() - 1) != '.' && contentDirPath.lastIndexOf('.') != -1) { contentDirPath = contentDirPath.substring(0, contentDirPath.lastIndexOf(".")); } File file; if (exportAsFolders && nodeService != null && contentData instanceof NodeContentData) { NodeContentData nodeContentData = (NodeContentData) contentData; file = new File(contentDirPath + toDisplayPath(nodeService.getPath(nodeContentData.getNodeRef()))); } else { String extension = "bin"; if (mimetypeService != null) { String mimetype = contentData.getMimetype(); if (mimetype != null && mimetype.length() > 0) { try { extension = mimetypeService.getExtension(mimetype); } catch (AlfrescoRuntimeException e) { // use default extension } } } file = new File(contentDirPath, "content" + iFileCnt++ + "." + extension); } try { // ALF-2016 ZipArchiveEntry zipEntry = new ZipArchiveEntry(file.getPath()); zipStream.putArchiveEntry(zipEntry); // copy export stream to zip copyStream(zipStream, content); } catch (IOException e) { throw new ExporterException("Failed to zip export stream", e); } return new ContentData(file.getPath(), contentData.getMimetype(), contentData.getSize(), contentData.getEncoding()); } /* (non-Javadoc) * @see org.alfresco.service.cmr.view.ExportPackageHandler#endExport() */ public void endExport() { // ensure data file has .xml extension String dataFilePath = dataFile.getPath(); if (!dataFilePath.endsWith(".xml")) { dataFilePath += (dataFilePath.charAt(dataFilePath.length() - 1) == '.') ? "xml" : ".xml"; } // add data file to zip stream // ALF-2016 ZipArchiveEntry zipEntry = new ZipArchiveEntry(dataFilePath); try { // close data file stream and place temp data file into zip output stream tempDataFileStream.close(); // ALF-2016 zipStream.putArchiveEntry(zipEntry); InputStream dataFileStream = new FileInputStream(tempDataFile); copyStream(zipStream, dataFileStream); // ALF-2016 zipStream.closeArchiveEntry(); dataFileStream.close(); } catch (IOException e) { throw new ExporterException("Failed to zip data stream file", e); } try { // close zip stream zipStream.close(); } catch (IOException e) { throw new ExporterException("Failed to close zip package stream", e); } } /** * Log Export Message * * @param message message to log */ protected void log(String message) { } /** * Copy input stream to output stream * * @param output output stream * @param in input stream * @throws IOException */ private void copyStream(OutputStream output, InputStream in) throws IOException { byte[] buffer = new byte[2048 * 10]; int read = in.read(buffer, 0, 2048 * 10); while (read != -1) { output.write(buffer, 0, read); read = in.read(buffer, 0, 2048 * 10); } } /** * @param path Path * @return display path */ private String toDisplayPath(Path path) { StringBuffer displayPath = new StringBuffer(); if (path.size() == 1) { displayPath.append("/"); } else { for (int i = 1; i < path.size(); i++) { Path.Element element = path.get(i); if (element instanceof ChildAssocElement) { ChildAssociationRef assocRef = ((ChildAssocElement) element).getRef(); NodeRef node = assocRef.getChildRef(); displayPath.append("/"); displayPath.append(nodeService.getProperty(node, ContentModel.PROP_NAME)); } } } return displayPath.toString(); } }