001/*
002 * (C) Copyright 2015-2016 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Thomas Roger
018 */
019
020package org.nuxeo.ecm.platform.io.operation;
021
022import java.io.File;
023import java.io.FileOutputStream;
024import java.io.IOException;
025import java.io.OutputStream;
026import org.nuxeo.ecm.automation.core.Constants;
027import org.nuxeo.ecm.automation.core.annotations.Context;
028import org.nuxeo.ecm.automation.core.annotations.Operation;
029import org.nuxeo.ecm.automation.core.annotations.OperationMethod;
030import org.nuxeo.ecm.automation.core.annotations.Param;
031import org.nuxeo.ecm.core.api.Blob;
032import org.nuxeo.ecm.core.api.Blobs;
033import org.nuxeo.ecm.core.api.CoreSession;
034import org.nuxeo.ecm.core.api.DocumentModel;
035import org.nuxeo.ecm.core.io.DocumentPipe;
036import org.nuxeo.ecm.core.io.DocumentReader;
037import org.nuxeo.ecm.core.io.DocumentWriter;
038import org.nuxeo.ecm.core.io.impl.DocumentPipeImpl;
039import org.nuxeo.ecm.core.io.impl.plugins.DocumentTreeReader;
040import org.nuxeo.ecm.core.io.impl.plugins.NuxeoArchiveWriter;
041import org.nuxeo.ecm.core.io.impl.plugins.SingleDocumentReader;
042import org.nuxeo.ecm.core.io.impl.plugins.XMLDocumentTreeWriter;
043import org.nuxeo.ecm.core.io.impl.plugins.XMLDocumentWriter;
044import org.nuxeo.runtime.api.Framework;
045
046/**
047 * Operation that export a document.
048 *
049 * @since 7.2
050 */
051@Operation(id = ExportDocument.ID, category = Constants.CAT_SERVICES, label = "Document Export", description = "Export the given document.")
052public class ExportDocument {
053
054    public static final String ID = "Document.Export";
055
056    @Param(name = "exportAsTree", description = "Export the document and all its children", required = false)
057    protected boolean exportAsTree = false;
058
059    @Param(name = "exportAsZip", description = "Create a ZIP of the export. If 'exportAsTree' is true, exportAsZip is force to true", required = false)
060    protected boolean exportAsZip = false;
061
062    @Context
063    protected CoreSession session;
064
065    @OperationMethod
066    public Blob run(DocumentModel doc) throws IOException {
067        if (exportAsTree) {
068            exportAsZip = true;
069        }
070
071        File tempFile = Framework.createTempFilePath(null, null).toFile();
072        Framework.trackFile(tempFile, tempFile);
073
074        DocumentReader documentReader = null;
075        DocumentWriter documentWriter = null;
076        try {
077            documentReader = makeDocumentReader(session, doc, exportAsTree, exportAsZip);
078            @SuppressWarnings("resource") // closed by documentWriter.close()
079            FileOutputStream out = new FileOutputStream(tempFile);
080            documentWriter = makeDocumentWriter(out, exportAsTree, exportAsZip);
081            DocumentPipe pipe = makePipe(exportAsTree);
082            pipe.setReader(documentReader);
083            pipe.setWriter(documentWriter);
084            pipe.run();
085        } finally {
086            if (documentReader != null) {
087                documentReader.close();
088            }
089            if (documentWriter != null) {
090                documentWriter.close();
091            }
092        }
093
094        String filename = exportAsZip ? "export.zip" : "document.xml";
095        String mimeType = exportAsZip ? "application/zip" : "text/xml";
096        return Blobs.createBlob(tempFile, mimeType, null, filename);
097    }
098
099    protected DocumentPipe makePipe(boolean exportAsTree) {
100        if (exportAsTree) {
101            return new DocumentPipeImpl(10);
102        } else {
103            return new DocumentPipeImpl();
104        }
105    }
106
107    protected DocumentReader makeDocumentReader(CoreSession session, DocumentModel doc, boolean exportAsTree,
108            boolean exportAsZip) {
109        DocumentReader documentReader;
110        if (exportAsTree) {
111            documentReader = new DocumentTreeReader(session, doc, false);
112            if (!exportAsZip) {
113                ((DocumentTreeReader) documentReader).setInlineBlobs(true);
114            }
115        } else {
116            documentReader = new SingleDocumentReader(session, doc);
117        }
118        return documentReader;
119    }
120
121    protected DocumentWriter makeDocumentWriter(OutputStream outputStream, boolean exportAsTree, boolean exportAsZip)
122            throws IOException {
123        DocumentWriter documentWriter;
124        if (exportAsZip) {
125            documentWriter = new NuxeoArchiveWriter(outputStream);
126        } else {
127            if (exportAsTree) {
128                documentWriter = new XMLDocumentTreeWriter(outputStream);
129            } else {
130                documentWriter = new XMLDocumentWriter(outputStream);
131            }
132        }
133        return documentWriter;
134    }
135}