| /** |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.camel.component.exec; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.FileInputStream; |
| import java.io.FileNotFoundException; |
| import java.io.IOException; |
| import java.io.InputStream; |
| |
| import org.w3c.dom.Document; |
| |
| import org.apache.camel.Converter; |
| import org.apache.camel.Exchange; |
| import org.apache.commons.io.IOUtils; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| /** |
| * Default converters for {@link ExecResult}. For details how to extend the |
| * converters check out <a |
| * href="http://camel.apache.org/type-converter.html">the Camel docs for type |
| * converters.</a> |
| */ |
| @Converter |
| public final class ExecResultConverter { |
| |
| private static final Logger LOG = LoggerFactory.getLogger(ExecResultConverter.class); |
| |
| private ExecResultConverter() { |
| } |
| |
| @Converter |
| public static InputStream convertToInputStream(ExecResult result) throws FileNotFoundException { |
| return toInputStream(result); |
| } |
| |
| @Converter |
| public static byte[] convertToByteArray(ExecResult result, Exchange exchange) throws FileNotFoundException, IOException { |
| InputStream stream = toInputStream(result); |
| try { |
| return IOUtils.toByteArray(stream); |
| } finally { |
| IOUtils.closeQuietly(stream); |
| } |
| } |
| |
| @Converter |
| public static String convertToString(ExecResult result, Exchange exchange) throws FileNotFoundException { |
| return convertTo(String.class, exchange, result); |
| } |
| |
| @Converter |
| public static Document convertToDocument(ExecResult result, Exchange exchange) throws FileNotFoundException { |
| return convertTo(Document.class, exchange, result); |
| } |
| |
| /** |
| * Converts <code>ExecResult</code> to the type <code>T</code>. |
| * |
| * @param <T> The type to convert to |
| * @param type Class instance of the type to which to convert |
| * @param exchange a Camel exchange. If exchange is <code>null</code>, no |
| * conversion will be made |
| * @param result the exec result |
| * @return the converted {@link ExecResult} |
| * @throws FileNotFoundException if there is a file in the execResult, and |
| * the file can not be found |
| */ |
| @SuppressWarnings("unchecked") |
| public static <T> T convertTo(Class<T> type, Exchange exchange, ExecResult result) throws FileNotFoundException { |
| InputStream is = toInputStream(result); |
| if (is != null) { |
| return exchange.getContext().getTypeConverter().convertTo(type, exchange, is); |
| } else { |
| // use Void to indicate we cannot convert it |
| // (prevents Camel from using a fallback converter which may convert a String from the instance name) |
| return (T) Void.TYPE; |
| } |
| } |
| |
| /** |
| * Returns <code>InputStream</code> object with the <i>output</i> of the |
| * executable. If there is {@link ExecCommand#getOutFile()}, its content is |
| * preferred to {@link ExecResult#getStdout()}. If no out file is set, and |
| * the stdout of the exec result is <code>null</code> returns the stderr of |
| * the exec result. <br> |
| * If the output stream is of type <code>ByteArrayInputStream</code>, its |
| * <code>reset()</code> method is called. |
| * |
| * @param execResult ExecResult object to convert to InputStream. |
| * @return InputStream object with the <i>output</i> of the executable. |
| * Returns <code>null</code> if both {@link ExecResult#getStdout()} |
| * and {@link ExecResult#getStderr()} are <code>null</code> , or if |
| * the <code>execResult</code> is <code>null</code>. |
| * @throws FileNotFoundException if the {@link ExecCommand#getOutFile()} can |
| * not be opened. In this case the out file must have had a not |
| * <code>null</code> value |
| */ |
| public static InputStream toInputStream(ExecResult execResult) throws FileNotFoundException { |
| if (execResult == null) { |
| LOG.warn("Received a null ExecResult instance to convert!"); |
| return null; |
| } |
| // prefer the out file for output |
| InputStream result; |
| if (execResult.getCommand().getOutFile() != null) { |
| result = new FileInputStream(execResult.getCommand().getOutFile()); |
| } else { |
| // if the stdout is null, return the stderr. |
| if (execResult.getStdout() == null && execResult.getCommand().isUseStderrOnEmptyStdout()) { |
| LOG.warn("ExecResult has no stdout, will fallback to use stderr."); |
| result = execResult.getStderr(); |
| } else { |
| result = execResult.getStdout() != null ? execResult.getStdout() : null; |
| } |
| } |
| // reset the stream if it was already read. |
| resetIfByteArrayInputStream(result); |
| return result; |
| } |
| |
| /** |
| * Resets the stream, only if it's a ByteArrayInputStream. |
| */ |
| private static void resetIfByteArrayInputStream(InputStream stream) { |
| if (stream != null && stream instanceof ByteArrayInputStream) { |
| try { |
| stream.reset(); |
| } catch (IOException ioe) { |
| LOG.error("Unable to reset the stream ", ioe); |
| } |
| } |
| } |
| } |