001/*
002 * (C) Copyright 2014 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl-2.1.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Thomas Roger
016 */
017
018package org.nuxeo.ecm.platform.convert.plugins;
019
020import java.io.File;
021import java.io.IOException;
022import java.io.Serializable;
023import java.nio.file.Files;
024import java.nio.file.Path;
025import java.nio.file.Paths;
026import java.util.ArrayList;
027import java.util.Arrays;
028import java.util.HashMap;
029import java.util.List;
030import java.util.Map;
031
032import org.nuxeo.ecm.core.api.Blob;
033import org.nuxeo.ecm.core.api.Blobs;
034import org.nuxeo.ecm.core.api.blobholder.BlobHolder;
035import org.nuxeo.ecm.core.convert.api.ConversionException;
036import org.nuxeo.ecm.core.convert.cache.SimpleCachableBlobHolder;
037import org.nuxeo.ecm.platform.commandline.executor.api.CmdParameters;
038
039/**
040 * Generic converter executing a contributed command line.
041 * <p>
042 * The command line to call is stored in the {@code CommandLineName} parameter.
043 * <p>
044 * The target file name is in the {@code targetFileName} parameter. If it's null, a temporary one will be created.
045 * <p>
046 * All the converter parameters are passed to the command line.
047 * <p>
048 * A sample contribution using this converter:
049 *
050 * <pre>
051 *     <converter name="pdf2image" class="org.nuxeo.ecm.platform.convert.plugins.CommandLineConverter">
052 *       <sourceMimeType>application/pdf</sourceMimeType>
053 *       <destinationMimeType>image/jpeg</destinationMimeType>
054 *       <destinationMimeType>image/png</destinationMimeType>
055 *       <destinationMimeType>image/gif</destinationMimeType>
056 *       <parameters>
057 *         <parameter name="CommandLineName">pdftoimage</parameter>
058 *       </parameters>
059 *     </converter>
060 * </pre>
061 *
062 * @since 7.1
063 */
064public class CommandLineConverter extends CommandLineBasedConverter {
065
066    public static final String SOURCE_FILE_PATH_KEY = "sourceFilePath";
067
068    public static final String OUT_DIR_PATH_KEY = "outDirPath";
069
070    public static final String TARGET_FILE_NAME_KEY = "targetFileName";
071
072    public static final String TARGET_FILE_PATH_KEY = "targetFilePath";
073
074    public static final List<String> RESERVED_PARAMETERS = Arrays.asList(SOURCE_FILE_PATH_KEY, OUT_DIR_PATH_KEY,
075            TARGET_FILE_PATH_KEY);
076
077    @Override
078    protected Map<String, Blob> getCmdBlobParameters(BlobHolder blobHolder, Map<String, Serializable> parameters)
079            throws ConversionException {
080        Map<String, Blob> cmdBlobParams = new HashMap<>();
081        cmdBlobParams.put(SOURCE_FILE_PATH_KEY, blobHolder.getBlob());
082        return cmdBlobParams;
083    }
084
085    @Override
086    protected Map<String, String> getCmdStringParameters(BlobHolder blobHolder, Map<String, Serializable> parameters)
087            throws ConversionException {
088        String tmpDir = getTmpDirectory(parameters);
089        Path tmpDirPath = tmpDir != null ? Paths.get(tmpDir) : null;
090        try {
091            Path outDirPath = tmpDirPath != null ? Files.createTempDirectory(tmpDirPath, null)
092                    : Files.createTempDirectory(null);
093
094            Map<String, String> cmdStringParams = new HashMap<>();
095            cmdStringParams.put(OUT_DIR_PATH_KEY, outDirPath.toString());
096
097            String targetFileName = (String) parameters.get(TARGET_FILE_NAME_KEY);
098            Path targetFilePath;
099            if (targetFileName == null) {
100                targetFilePath = tmpDirPath != null ? Files.createTempFile(tmpDirPath, null, null)
101                        : Files.createTempFile(null, null);
102            } else {
103                targetFilePath = Paths.get(outDirPath.toString(), targetFileName);
104            }
105            cmdStringParams.put(TARGET_FILE_PATH_KEY, targetFilePath.toString());
106
107            // pass all converter parameters to the command line
108            for (Map.Entry<String, Serializable> entry : parameters.entrySet()) {
109                if (!RESERVED_PARAMETERS.contains(entry.getKey())) {
110                    cmdStringParams.put(entry.getKey(), (String) entry.getValue());
111                }
112            }
113
114            return cmdStringParams;
115        } catch (IOException e) {
116            throw new ConversionException(e.getMessage(), e);
117        }
118    }
119
120    @Override
121    protected BlobHolder buildResult(List<String> cmdOutput, CmdParameters cmdParams) throws ConversionException {
122        String outputPath = cmdParams.getParameter(OUT_DIR_PATH_KEY);
123        List<Blob> blobs = new ArrayList<>();
124        File outputDir = new File(outputPath);
125        if (outputDir.exists() && outputDir.isDirectory()) {
126            File[] files = outputDir.listFiles();
127            if (files != null) {
128                for (File file : files) {
129                    try {
130                        Blob blob = Blobs.createBlob(file);
131                        blob.setFilename(file.getName());
132                        blobs.add(blob);
133                    } catch (IOException e) {
134                        throw new ConversionException("Cannot create blob", e);
135                    }
136                }
137            }
138        }
139        return new SimpleCachableBlobHolder(blobs);
140    }
141
142}