package jp.co.areaweb.tools.command;
import java.io.*;

public class Command
{
    public static final boolean debug = false;
    private java.lang.String cmd;    /** プロパティ cmd(実行するｺﾏﾝﾄﾞﾗｲﾝ)。 */
    private java.io.File workDir;   /** プロパティ workDir の値 */
    private BufferedReader stdReader = null;   // 標準出力
    private BufferedReader errReader = null;   // エラー出力
    
    /** 
     * ｺﾏﾝﾄﾞを実行しその出力ｽﾄﾘｰﾑを取得
     * @exception IOException I/Oｴﾗｰが発生した場合
     * @exception EDException EDMICSｺﾏﾝﾄﾞでｴﾗｰが発生した場合
     */
    public void execCommand() throws IOException {
        if (debug){
            System.out.println("[Command s] " + cmd);
        }

        if ((getCmd() == null) || getCmd().equals("")) {
            return;
        }

        // ｺﾏﾝﾄﾞを実行
        Process process;
        if (getWorkDir() == null) {
            process = Runtime.getRuntime().exec(getCmd());
        }
        else {
            process = Runtime.getRuntime().exec(getCmd(), null, getWorkDir());
        }
        try { 
            process.waitFor();  // ｺﾏﾝﾄﾞ終了まで待機
        } catch (InterruptedException e) {}

        if (debug) {
            System.out.println("[Command e] "+ getCmd() +"\n");
        }

        // ｺﾏﾝﾄﾞ標準ｴﾗｰ出力を取得
        this.errReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));

        // ｺﾏﾝﾄﾞ標準出力の入力ｽﾄﾘｰﾑを取得
        this.stdReader = new BufferedReader(new InputStreamReader(process.getInputStream()));

        return;
    }
    
    /**
     *  コマンド実行結果
     *  標準出力とエラー出力の結果を合成してかえす。
     *  よって、本メソッドを実行するとgetStdout(),getErrout()は無効になる
     *  このメソッドは、execCommand()メソッドを実行した直後の１回目の実行結果のみ有効
     */
    public String getOutput() throws IOException {
        String std = getStdout();
        if (std.equals("")) {
            return getErrout();
        }
        else {
            return std +"\n"+ getErrout();
        }
    }
    
    /**
     *  コマンド実行結果の標準出力
     *  このメソッドは、execCommand()メソッドを実行した直後の１回目の実行結果のみ有効
     */
    public String getStdout() throws IOException {
        return convBufferedReader(this.stdReader);
    }
    
    /**
     *  コマンド実行結果のエラー出力
     *  このメソッドは、execCommand()メソッドを実行した直後の１回目の実行結果のみ有効
     */
    public String getErrout() throws IOException {
        return convBufferedReader(this.errReader);
    }
    
    private static String convBufferedReader(BufferedReader reader) throws IOException {
        if (reader == null) {
            return "";
        }
        StringBuffer strbuf = new StringBuffer();
        for (String line; (line = reader.readLine()) != null; strbuf.append(line +"\n"));
        reader.close();
        reader = null;
        return strbuf.toString();
    }
    
    /** プロパティ cmd の取得メソッド。
     * @return プロパティ cmd の値。
     */
    public String getCmd() {
        return cmd;
    }
    
    /** プロパティ cmd の設定メソッド。
     * @param cmd プロパティ cmd の新しい値。
     */
    public void setCmd(String cmd) {
        this.cmd = cmd;
    }
    
    /** プロパティ workDir の取得メソッド。
     * @return プロパティ workDir の値。
     */
    public java.io.File getWorkDir() {
        return workDir;
    }
    
    /** プロパティ workDir の設定メソッド。
     * @param workDir プロパティ workDir の新しい値。
     */
    public void setWorkDir(java.io.File workDir) {
        this.workDir = workDir;
    }

    /** 
    *	サンプル
    */
    static public void main(String[] args) {
        if (args.length < 1) {
            System.out.println("exp: java tool.job.Command [commandLine]");
            return;
        }
        String commandLine = "";
        for (int i=0; i < args.length; i++) {
            if (i != 0) {
                commandLine += " ";
            }
            commandLine += args[i];
        }

        // エラー結果と実行結果を別々に取り出す
        System.out.println(commandLine);
        Command command = new Command();
        String stdout = "";
        String errout = "";
        try {
            command.setCmd(commandLine);
            command.setWorkDir(null);
            command.execCommand();
            stdout = command.getStdout();
            errout = command.getErrout();
            System.out.println("STD_OUT:");
            System.out.println(stdout);
            System.out.println("STD_ERROR:");
            System.out.println(errout);
        }
        catch (Exception e) {
            e.printStackTrace();
        }

        // エラー結果と実行結果をいっしょに取り出す
        System.out.println(commandLine);
        command = new Command();
        try {
            command.setCmd(commandLine);
            command.setWorkDir(null);
            command.execCommand();
            System.out.println(command.getOutput());
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}
