001/*
002 * (C) Copyright 2014-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.convert.plugins;
021
022import java.io.File;
023import java.io.IOException;
024import java.io.Serializable;
025import java.nio.file.Files;
026import java.nio.file.Path;
027import java.nio.file.Paths;
028import java.util.ArrayList;
029import java.util.Arrays;
030import java.util.HashMap;
031import java.util.List;
032import java.util.Map;
033
034import org.nuxeo.ecm.core.api.Blob;
035import org.nuxeo.ecm.core.api.Blobs;
036import org.nuxeo.ecm.core.api.blobholder.BlobHolder;
037import org.nuxeo.ecm.core.convert.api.ConversionException;
038import org.nuxeo.ecm.core.convert.cache.SimpleCachableBlobHolder;
039import org.nuxeo.ecm.platform.commandline.executor.api.CmdParameters;
040import org.nuxeo.runtime.api.Framework;
041
042/**
043 * Generic converter executing a contributed command line.
044 * <p>
045 * The command line to call is stored in the {@code CommandLineName} parameter.
046 * <p>
047 * The target file name is in the {@code targetFileName} parameter. If it's null, a temporary one will be created.
048 * <p>
049 * All the converter parameters are passed to the command line.
050 * <p>
051 * A sample contribution using this converter:
052 *
053 * <pre>
054 *     <converter name="pdf2image" class="org.nuxeo.ecm.platform.convert.plugins.CommandLineConverter">
055 *       <sourceMimeType>application/pdf</sourceMimeType>
056 *       <destinationMimeType>image/jpeg</destinationMimeType>
057 *       <destinationMimeType>image/png</destinationMimeType>
058 *       <destinationMimeType>image/gif</destinationMimeType>
059 *       <parameters>
060 *         <parameter name="CommandLineName">pdftoimage</parameter>
061 *       </parameters>
062 *     </converter>
063 * </pre>
064 *
065 * @since 7.1
066 */
067public class CommandLineConverter extends CommandLineBasedConverter {
068
069    public static final String SOURCE_FILE_PATH_KEY = "sourceFilePath";
070
071    public static final String OUT_DIR_PATH_KEY = "outDirPath";
072
073    public static final String TARGET_FILE_NAME_KEY = "targetFileName";
074
075    public static final String TARGET_FILE_PATH_KEY = "targetFilePath";
076
077    public static final List<String> RESERVED_PARAMETERS = Arrays.asList(SOURCE_FILE_PATH_KEY, OUT_DIR_PATH_KEY,
078            TARGET_FILE_PATH_KEY);
079
080    @Override
081    protected Map<String, Blob> getCmdBlobParameters(BlobHolder blobHolder, Map<String, Serializable> parameters)
082            throws ConversionException {
083        Map<String, Blob> cmdBlobParams = new HashMap<>();
084        cmdBlobParams.put(SOURCE_FILE_PATH_KEY, blobHolder.getBlob());
085        return cmdBlobParams;
086    }
087
088    @Override
089    protected Map<String, String> getCmdStringParameters(BlobHolder blobHolder, Map<String, Serializable> parameters)
090            throws ConversionException {
091        String tmpDir = getTmpDirectory(parameters);
092        Path tmpDirPath = tmpDir != null ? Paths.get(tmpDir) : null;
093        try {
094            Path outDirPath = tmpDirPath != null ? Files.createTempDirectory(tmpDirPath, null)
095                    : Framework.createTempDirectory(null);
096
097            Map<String, String> cmdStringParams = new HashMap<>();
098            cmdStringParams.put(OUT_DIR_PATH_KEY, outDirPath.toString());
099
100            String targetFileName = (String) parameters.get(TARGET_FILE_NAME_KEY);
101            Path targetFilePath;
102            if (targetFileName == null) {
103                targetFilePath = tmpDirPath != null ? Files.createTempFile(tmpDirPath, null, null)
104                        : Framework.createTempFilePath(null, null);
105            } else {
106                targetFilePath = Paths.get(outDirPath.toString(), targetFileName);
107            }
108            cmdStringParams.put(TARGET_FILE_PATH_KEY, targetFilePath.toString());
109
110            // pass all converter parameters to the command line
111            for (Map.Entry<String, Serializable> entry : parameters.entrySet()) {
112                if (!RESERVED_PARAMETERS.contains(entry.getKey())) {
113                    cmdStringParams.put(entry.getKey(), (String) entry.getValue());
114                }
115            }
116
117            return cmdStringParams;
118        } catch (IOException e) {
119            throw new ConversionException(e.getMessage(), e);
120        }
121    }
122
123    @Override
124    protected BlobHolder buildResult(List<String> cmdOutput, CmdParameters cmdParams) throws ConversionException {
125        String outputPath = cmdParams.getParameter(OUT_DIR_PATH_KEY);
126        List<Blob> blobs = new ArrayList<>();
127        File outputDir = new File(outputPath);
128        if (outputDir.exists() && outputDir.isDirectory()) {
129            File[] files = outputDir.listFiles();
130            if (files != null) {
131                for (File file : files) {
132                    try {
133                        Blob blob = Blobs.createBlob(file);
134                        blob.setFilename(file.getName());
135                        blobs.add(blob);
136                    } catch (IOException e) {
137                        throw new ConversionException("Cannot create blob", e);
138                    }
139                }
140            }
141        }
142        return new SimpleCachableBlobHolder(blobs);
143    }
144
145}