package org.jtheque.osgi;
import org.jtheque.utils.SystemProperty;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.BuildListener;
import org.apache.tools.ant.BuildLogger;
import org.apache.tools.ant.DefaultLogger;
import org.apache.tools.ant.DemuxOutputStream;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Java;
import java.io.File;
import java.io.PrintStream;
/*
* Copyright JTheque (Baptiste Wicht)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* The main launcher of JTheque. Using this launcher enable the feature of hot restart. This class use Ant to launch a
* new virtual machine.
*
* @author Baptiste Wicht
*/
public final class JTheque {
/**
* Main class, cannot be created.
*/
private JTheque() {
throw new AssertionError();
}
/**
* Main method of the JTheque Launcher.
*
* @param args The first arg is the user dir.
*/
public static void main(String[] args) {
if (args.length > 0) {
SystemProperty.USER_DIR.set(args[0]);
}
launch();
}
/**
* Launch the application. If the return code if greater than 0, the application will be restarted.
*/
private static void launch() {
int ret = launchJTheque();
if (ret > 0) {
launch();
}
}
/**
* Launch JTheque.
*
* @return The return code.
*/
@SuppressWarnings({"UseOfSystemOutOrSystemErr"})
private static int launchJTheque() {
int returnCode;
Thread.currentThread().setName("Kernel-MainThread");
Project project = new Project();
project.setBasedir(System.getProperty("user.dir"));
project.init();
PrintStream out = System.out;
PrintStream err = System.err;
project.addBuildListener(createLogger(out, err));
System.setOut(new PrintStream(new DemuxOutputStream(project, false)));
System.setErr(new PrintStream(new DemuxOutputStream(project, true)));
project.fireBuildStarted();
Throwable caught = null;
try {
project.log("Launch JTheque Kernel");
Java javaTask = createJavaTask(project);
returnCode = javaTask.executeJava();
} catch (BuildException e) {
caught = e;
returnCode = -1;
}
project.fireBuildFinished(caught);
System.setOut(out);
System.setErr(err);
return returnCode;
}
/**
* Create a simple logger to out and err streams.
*
* @param out The output stream.
* @param err The error stream.
*
* @return The create logger.
*/
private static BuildListener createLogger(PrintStream out, PrintStream err) {
BuildLogger logger = new DefaultLogger();
logger.setOutputPrintStream(out);
logger.setErrorPrintStream(err);
logger.setMessageOutputLevel(Project.MSG_INFO);
return logger;
}
/**
* Create the Java Task for launching the Kernel.
*
* @param project The project to launch the task in.
*
* @return The created Java Task.
*/
private static Java createJavaTask(Project project) {
Java javaTask = new Java();
javaTask.setTaskName("JTheque");
javaTask.setProject(project);
javaTask.setFork(true);
javaTask.setFailonerror(true);
javaTask.setCloneVm(true);
javaTask.setClassname(Kernel.class.getName());
javaTask.setDir(new File(SystemProperty.USER_DIR.get(), "core"));
javaTask.init();
return javaTask;
}
}