org.squale.squalix.util.process.ProcessManager.java Source code

Java tutorial

Introduction

Here is the source code for org.squale.squalix.util.process.ProcessManager.java

Source

/**
 * Copyright (C) 2008-2010, Squale Project - http://www.squale.org
 *
 * This file is part of Squale.
 *
 * Squale is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or any later version.
 *
 * Squale is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Squale.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.squale.squalix.util.process;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.StringTokenizer;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.squale.squalix.messages.Messages;

/**
 * Manager de lancement de processus externe Une processus permet le lancement d'une commande externe et son suivi en
 * terme de flux de sortie sur stdout et stderr
 */
public class ProcessManager {
    /**
     * Logger.
     */
    private static final Log LOGGER = LogFactory.getLog(ProcessManager.class);

    /** Rpertoire d'excution */
    private File mDir;

    /** Environnement d'excution */
    private String[] mEnvp;

    /** Commande  excuter */
    private String[] mCommand;

    /** Handler de sortie */
    private ProcessOutputHandler mOutputHandler;

    /** le fichier de log */
    private File mLog;

    /**
     * Constructeur
     * 
     * @param pCommand commande  lancer
     * @param pEnvp environnement d'excution
     * @param pDir rpertoire d'excution
     */
    public ProcessManager(String[] pCommand, String pEnvp[], File pDir) {
        this(pCommand, pEnvp, pDir, null);
    }

    /**
     * Constructeur
     * 
     * @param pCommand commande  lancer
     * @param pEnvp environnement d'excution
     * @param pDir rpertoire d'excution
     * @param pLog le fichier de log
     */
    public ProcessManager(String[] pCommand, String pEnvp[], File pDir, File pLog) {
        mCommand = pCommand;
        mEnvp = pEnvp;
        mDir = pDir;
        mLog = pLog;
    }

    /**
     * Constructeur
     * 
     * @param pCommand commande  lancer
     * @param pEnvp environnement d'excution
     * @param pDir rpertoire d'excution
     */
    public ProcessManager(String pCommand, String pEnvp[], File pDir) {
        this(pCommand, pEnvp, pDir, null);
    }

    /**
     * Constructeur
     * 
     * @param pCommand commande  lancer
     * @param pEnvp environnement d'excution
     * @param pDir rpertoire d'excution
     * @param pLog le fichier de log
     */
    public ProcessManager(String pCommand, String pEnvp[], File pDir, File pLog) {
        mCommand = splitCommand(pCommand);
        mEnvp = pEnvp;
        mDir = pDir;
        mLog = pLog;
    }

    /**
     * affectation du handler d'output
     * 
     * @param pOutputHandler handler de sortie
     */
    public void setOutputHandler(ProcessOutputHandler pOutputHandler) {
        mOutputHandler = pOutputHandler;
    }

    /**
     * Lancement du processus externe
     * 
     * @param pHandler interface de traitement des erreurs
     * @return code de retour d'excution
     * @throws IOException si erreur
     * @throws InterruptedException si erreur
     */
    public int startProcess(ProcessErrorHandler pHandler) throws IOException, InterruptedException {
        int result;
        Runtime runtime = Runtime.getRuntime();
        // Informations de debug
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug(Messages.getString("process.dir") + mDir);
            for (int i = 0; i < mCommand.length; i++) {
                LOGGER.debug(Messages.getString("process.argument") + i + " " + mCommand[i]);
            }
        }
        // Vrification de l'existence du rpertoire de lancement
        // cel peut tre  l'origine de situations de blocage
        if ((mDir != null) && (!mDir.exists() || !mDir.isDirectory())) {
            throw new IOException("unexisting directory: " + mDir);
        }
        Process processCheck = runtime.exec(mCommand, mEnvp, mDir);

        /*
         * Pour viter le lock du process, il faut envoyer le flux d'erreur et le flux de sortie sur des threads.
         */
        ProcessErrorStream err = new ProcessErrorStream(processCheck.getErrorStream(), pHandler);
        Thread errorThread = new Thread(err, "StderrStreamConsumer");
        errorThread.start();

        ProcessOutputStream outp = createOutputStream(processCheck.getInputStream(), mOutputHandler);
        Thread outputThread = new Thread(outp, "StdoutStreamConsumer");
        outputThread.start();

        /* Obtention du code de retour du process */
        result = processCheck.waitFor();
        // Attente de la terminaison des threads
        // pour etre certain de recuperer les donnes
        // Voir bugid 4422496 de Sun
        outputThread.join();
        errorThread.join();

        return result;
    }

    /**
     * @param pInput l'entre
     * @param pHandler le handler de sortie
     * @return le process de sortie  utiliser
     * @throws IOException si erreur
     */
    public ProcessOutputStream createOutputStream(InputStream pInput, ProcessOutputHandler pHandler)
            throws IOException {
        ProcessOutputStream process = null;
        if (null == mLog) {
            process = new ProcessOutputStream(pInput, mOutputHandler);
        } else {
            // Si le fichier contient dj des traces, on ne les crase pas (le true du FileWriter)
            process = new ProcessOutputStreamInFile(pInput, mOutputHandler,
                    new BufferedWriter(new FileWriter(mLog, true)));
        }
        return process;
    }

    /**
     * Dcoupage de la commande en plusieurs paramtres
     * 
     * @param pCommand ligne de commande
     * @return la commande splitte
     */
    private String[] splitCommand(String pCommand) {
        int count = 0;
        String cmdarray[];
        StringTokenizer st;

        if (pCommand.length() == 0) {
            throw new IllegalArgumentException("Empty command");
        }

        st = new StringTokenizer(pCommand);
        count = st.countTokens();

        cmdarray = new String[count];
        st = new StringTokenizer(pCommand);
        count = 0;
        while (st.hasMoreTokens()) {
            cmdarray[count++] = st.nextToken();
        }
        return cmdarray;
    }

    /**
     * @return l'outputHandler
     */
    public ProcessOutputHandler getOutputHandler() {
        return mOutputHandler;
    }

}