/*
 * Copyright 2004 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

/**
 *
 */

import java.io.*;
import java.util.Properties;

public class JavaProcess {

    protected Process process = null;

    private String classname;
    private StringBuilder classArgs;
    private StringBuilder javaOptions;

    private static String java = System.getProperty("java.home")
                                 + File.separator + "bin"
                                 + File.separator + "java";

    public JavaProcess(String classname) {
        this(classname, "", "");
    }

    public JavaProcess(String classname, String classArgs) {
        this(classname, "", classArgs);
    }

    public JavaProcess(String classname, String javaOptions, String classArgs) {
        this.classname = classname;
        this.javaOptions = new StringBuilder(javaOptions);
        this.classArgs = new StringBuilder(classArgs);
    }

    /**
     * add java options to the java command
     */
    public void addOptions(String[] opts) {
        if (javaOptions != null && javaOptions.length() > 0) {
            javaOptions.append(" ");
        }

        for (int i = 0; i < opts.length; i++) {
            if (i != 0) {
                javaOptions.append(" ");
            }
            javaOptions.append(opts[i]);
        }
    }

    /**
     * add arguments to the class arguments
     */
    public void addArguments(String[] args) {
        if (classArgs != null && classArgs.length() > 0) {
            classArgs.append(" ");
        }

        for (int i = 0; i < args.length; i++) {
            if (i != 0) {
                classArgs.append(" ");
            }
            classArgs.append(args[i]);
        }
    }

    /**
     * start the java process
     */
    public void start() throws IOException {
        if (process != null) {
            return;
        }

        String javaCommand = java + " " + javaOptions + " "
                             + classname + " " + classArgs;

        System.out.println("exec'ing: " + javaCommand);

        process = Runtime.getRuntime().exec(javaCommand);
    }

    /**
     * destroy the java process
     */
    public void destroy() {
        if (process != null) {
            process.destroy();
        }
        process = null;
    }

    public int exitValue() {
        if (process != null) {
            return process.exitValue();
        }
        throw new RuntimeException("exitValue called with process == null");
    }

    public InputStream getErrorStream() {
        if (process != null) {
            return process.getErrorStream();
        }
        throw new RuntimeException(
                "getErrorStream() called with process == null");
    }

    public InputStream getInputStream() {
        if (process != null) {
            return process.getInputStream();
        }
        throw new RuntimeException(
                "getInputStream() called with process == null");
    }

    public OutputStream getOutputStream() {
        if (process != null) {
            return process.getOutputStream();
        }
        throw new RuntimeException(
                "getOutputStream() called with process == null");
    }

    public int waitFor() throws InterruptedException {
        if (process != null) {
            return process.waitFor();
        }
        throw new RuntimeException("waitFor() called with process == null");
    }
}
