/*
* Jabox Open Source Version
* Copyright (C) 2009-2010 Dimitris Kapanidis
*
* This file is part of Jabox
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.JarURLConnection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Iterator;
/**
* Launcher class for stand-alone execution of Jabox as
* <tt>java -jar jabox.jar</tt>.
*
* Credit goes to Kohsuke Kawaguchi for his implementation in hudson.
*
* @author Kohsuke Kawaguchi
*/
public class Main {
public static void main(String[] args) throws Exception {
// this is so that JFreeChart can work nicely even if we are launched as
// a daemon
System.setProperty("java.awt.headless", "true");
File me = whoAmI();
// locate Winstone jar
URL jar = Main.class.getResource("winstone.jar");
// put this jar in a file system so that we can load jars from there
File tmpJar;
try {
tmpJar = File.createTempFile("winstone", "jar");
} catch (IOException e) {
String tmpdir = System.getProperty("java.io.tmpdir");
IOException x = new IOException(
"Hudson has failed to create a temporary file in " + tmpdir);
x.initCause(e);
throw x;
}
copyStream(jar.openStream(), new FileOutputStream(tmpJar));
tmpJar.deleteOnExit();
// clean up any previously extracted copy, since
// winstone doesn't do so and that causes problems when newer version of
// Jabox is deployed.
File tempFile = File.createTempFile("dummy", "dummy");
deleteContents(new File(tempFile.getParent(), "winstone/"
+ me.getName()));
tempFile.delete();
// locate the Winstone launcher
ClassLoader cl = new URLClassLoader(new URL[] { tmpJar.toURL() });
Class launcher = cl.loadClass("winstone.Launcher");
Method mainMethod = launcher.getMethod("main",
new Class[] { String[].class });
// figure out the arguments
List arguments = new ArrayList(Arrays.asList(args));
arguments.add(0, "--warfile=" + me.getAbsolutePath());
if (!hasWebRoot(arguments))
// defaults to ~/.hudson/war since many users reported that cron job
// attempts to clean up
// the contents in the temporary directory.
arguments.add("--webroot="
+ new File(System.getProperty("user.home"), ".jabox/war"));
// run
mainMethod.invoke(null,
new Object[] { arguments.toArray(new String[0]) });
}
private static boolean hasWebRoot(List arguments) {
for (Iterator itr = arguments.iterator(); itr.hasNext();) {
String s = (String) itr.next();
if (s.startsWith("--webroot="))
return true;
}
return false;
}
/**
* Figures out the URL of <tt>jabox.war</tt>.
*/
public static File whoAmI() throws IOException, URISyntaxException {
URL classFile = Main.class.getClassLoader().getResource("Main.class");
// JNLP returns the URL where the jar was originally placed
// not the local cached file. So we need a rather round about approach
// to get to
// the local file name.
return new File(((JarURLConnection) classFile.openConnection())
.getJarFile().getName());
}
private static void copyStream(InputStream in, OutputStream out)
throws IOException {
byte[] buf = new byte[8192];
int len;
while ((len = in.read(buf)) > 0)
out.write(buf, 0, len);
in.close();
out.close();
}
private static void deleteContents(File file) throws IOException {
if (file.isDirectory()) {
File[] files = file.listFiles();
if (files != null) {// be defensive
for (int i = 0; i < files.length; i++)
deleteContents(files[i]);
}
}
file.delete();
}
}