FileDocCategorySizeDatePackage
TomcatSupport.javaAPI DocExample6139Wed Mar 19 19:38:06 GMT 2003com.oreilly.javaxp.tomcat.tasks

TomcatSupport.java

package com.oreilly.javaxp.tomcat.tasks;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Locale;

/**
 * @author Brian M. Coyner
 * @version $Id: TomcatSupport.java,v 1.8 2003/03/18 00:02:38 jepc Exp $
 */
public class TomcatSupport {

    private Task task;
    private URL testURL;
    private String catalinaHome;
    private String scriptToExecute;
    private long timeout;
    private boolean isStarting;

    /**
     * @param task the task that invoked this class. It's used only
     * for logging.
     * @param scriptToExecute the Tomcat 4.1.12 script used to start
     * or stop the server.
     */
    public TomcatSupport(Task task,
                         String scriptToExecute,
                         boolean isStarting) {
        this.task = task;
        this.scriptToExecute = getScriptWithExtension(scriptToExecute);
        this.isStarting = isStarting;

        // I have a pretty slow machine and this seems to be long enough.
        this.timeout = 20000;
    }

    /**
     * Executes a Tomcat script to start or stop the server.
     */
    public void execute() throws BuildException {

        // if the server is up and we are trying to start it then return
        // if the server is down and we are tryint to stop it then return
        if (isTomcatRunning() == this.isStarting) {
            if (this.isStarting) {
                this.task.log("Tomcat is already started!");
            } else {
                this.task.log("Tomcat is *not* running!");
            }
            return;
        }

        runScript();

        boolean didTimeout = true;
        this.timeout = System.currentTimeMillis() + this.timeout;
        while (System.currentTimeMillis() < this.timeout) {
            sleep(500);
            if (isTomcatRunning() == this.isStarting) {
                didTimeout = false;
                break;
            }
        }

        if (didTimeout) {
            throw new BuildException("The server was not started " +
                                     "successfully. Please make sure that your buildfile " +
                                     "specifies a long enough timeout period AND that " +
                                     "your environment is setup correctly.");
        }

        if (this.isStarting) {
            this.task.log("Tomcat is started!");
        } else {
            this.task.log("Tomcat is stopped!");
        }
    }

    public void runScript() throws BuildException {
        validateScript(this.catalinaHome, this.scriptToExecute);

        this.task.log((this.isStarting ? "Starting" : "Stopping") +
                      " Tomcat...");

        String script = this.catalinaHome +
                File.separator + "bin" + File.separator +
                this.scriptToExecute;


        this.task.log("    Using script: " + script);

        try {
            Runtime.getRuntime().exec(script);
        } catch (IOException e) {
            throw new BuildException(e);
        }
    }

    public void setTestURL(String testURL) {
        try {
            this.testURL = new URL(testURL);
        } catch (MalformedURLException e) {
            throw new BuildException("Invalid URL: " + testURL);
        }
    }

    public void setCatalinaHome(String catalinaHome) {
        this.catalinaHome = catalinaHome;
    }

    public void setScriptToExecute(String scriptToExecute) {
        this.scriptToExecute = scriptToExecute;
    }

    public void setTimeout(long timeout) {
        this.timeout = timeout;
    }

    private static void validateScript(String path, String script) {
        File file = new File(path + File.separator + "bin" +
                             File.separator + script);
        if (!file.exists() || file.isDirectory()) {
            throw new BuildException("Invalid File: " + file.getAbsolutePath());
        }
    }

    private boolean isTomcatRunning() {

        HttpURLConnection conn = null;
        try {
            conn = (HttpURLConnection) this.testURL.openConnection();
            conn.connect();
            isURLValid(conn);
            return true;
        } catch (IOException e) {
            logException(e);
            return false;
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
    }

    private boolean isURLValid(HttpURLConnection conn) {
        int responseCode = 0;
        try {
            responseCode = conn.getResponseCode();
            // Response Codes 400 and above represent errors according
            // to the HTTP 1.1 specification available in RFC 2616 at
            // http://www.ietf.org/rfc/rfc2616.txt
            return (responseCode >= 100 && responseCode < 400);
        } catch (IOException e) {
            logException(e);
            return false;
        }
    }

    private void logException(Exception e) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PrintWriter writer = new PrintWriter(baos);
        e.printStackTrace(writer);
        writer.close();
        this.task.log(new String(baos.toByteArray()), Project.MSG_DEBUG);
    }

    private void sleep(long ms) {
        try {
            Thread.sleep(ms);
        } catch (InterruptedException e) {
        }
    }

    private String getScriptWithExtension(String scriptToExecute) {
        String os = System.getProperty("os.name").toLowerCase(Locale.US);
        // if the OS name is a flavor of windows then execute a .bat file.
        if (os.indexOf("windows") != -1) {
            return scriptToExecute + ".bat";
        } else {
            return scriptToExecute + ".sh";
        }
    }
}