All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.archive.util.ProcessUtils Maven / Gradle / Ivy

There is a newer version: 1.1.9
Show newest version
/*
 *  This file is part of the Heritrix web crawler (crawler.archive.org).
 *
 *  Licensed to the Internet Archive (IA) by one or more individual 
 *  contributors. 
 *
 *  The IA 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.archive.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Class to run an external process.
 * @author stack
 * @version $Date$ $Revision$
 */
public class ProcessUtils {
    private static final Logger LOGGER =
        Logger.getLogger(ProcessUtils.class.getName());
    
    protected ProcessUtils() {
        super();
    }
    
    /**
     * Thread to gobble up an output stream.
     * See http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html
     */
    protected class StreamGobbler extends Thread {
        private final InputStream is;
        private final StringBuffer sink = new StringBuffer();

        protected StreamGobbler(InputStream is, String name) {
            this.is = is;
            setName(name);
        }

        public void run() {
            try {
                BufferedReader br =
                    new BufferedReader(new InputStreamReader(this.is));
                for (String line = null; (line = br.readLine()) != null;) {
                    this.sink.append(line);
                }
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
        }
        
        public String getSink() {
            return this.sink.toString();
        }
    }
    
    /**
     * Data structure to hold result of a process exec.
     * @author stack
     * @version $Date$ $Revision$
     */
    public class ProcessResult {
        private final String [] args;
        private final int result;
        private final String stdout;
        private final String stderr;
            
        protected ProcessResult(String [] args, int result, String stdout,
                    String stderr) {
            this.args = args;
            this.result = result;
            this.stderr = stderr;
            this.stdout = stdout;
        }
            
        public int getResult() {
            return this.result;
        }
            
        public String getStdout() {
            return this.stdout;
        }
            
        public String getStderr() {
            return this.stderr;
        }
                
        public String toString() {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < this.args.length; i++) {
                sb.append(this.args[i]);
                sb.append(", ");
            }
            return sb.toString() + " exit code: " + this.result +
                ((this.stderr != null && this.stderr.length() > 0)?
                    "\nSTDERR: " + this.stderr: "") +
                ((this.stdout != null && this.stdout.length() > 0)?
                    "\nSTDOUT: " + this.stdout: "");
        }
    }
        
    /**
     * Runs process.
     * @param args List of process args.
     * @return A ProcessResult data structure.
     * @throws IOException If interrupted, we throw an IOException. If non-zero
     * exit code, we throw an IOException (This may need to change).
     */
    public static ProcessUtils.ProcessResult exec(String [] args)
    throws IOException {
        Process p = Runtime.getRuntime().exec(args);
        ProcessUtils pu = new ProcessUtils();
        // Gobble up any output.
        StreamGobbler err = pu.new StreamGobbler(p.getErrorStream(), "stderr");
        err.setDaemon(true);
        err.start();
        StreamGobbler out = pu.new StreamGobbler(p.getInputStream(), "stdout");
        out.setDaemon(true);
        out.start();
        int exitVal;
        try {
            exitVal = p.waitFor();
        } catch (InterruptedException e) {
            throw new IOException("Wait on process " + Arrays.toString(args) + " interrupted: "
                + e.getMessage());
        }
        ProcessUtils.ProcessResult result =
            pu.new ProcessResult(args, exitVal, out.getSink(), err.getSink());
        if (exitVal != 0) {
            throw new IOException(result.toString());
        } else if (LOGGER.isLoggable(Level.INFO)) {
            LOGGER.info(result.toString());
        }
        return result;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy