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";
}
}
}
|