package org.fastcatsearch.server;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.LinkedHashSet;
import java.util.Set;
public class Bootstrap {
private static Bootstrap daemon;
private Object serverDaemon = null;
protected ClassLoader serverLoader = null;
private final String serverClass = "org.fastcatsearch.server.CatServer";
private String serverHome;
private final String LIB_PATH = "/lib/";
public static void main(String[] args) {
if (daemon == null) {
// Don't set daemon until init() has completed
Bootstrap bootstrap = new Bootstrap();
try {
bootstrap.init();
} catch (Throwable t) {
t.printStackTrace();
return;
}
daemon = bootstrap;
} else {
// When running as a service the call to stop will be on a new
// thread so make sure the correct class loader is used to prevent
// a range of class not found exceptions.
Thread.currentThread().setContextClassLoader(daemon.serverLoader);
}
try {
String command = "";
if (args.length > 0) {
command = args[args.length - 1];
}
if (command.equals("run")) {
args[args.length - 1] = "start";
daemon.load(args);
daemon.start();
} else if (command.equals("start")) {
daemon.load(args);
daemon.start();
} else if (command.equals("stop")) {
daemon.stop();
} else if (args.length > 0) {
//TODO -help등을 sh스크립트에서 처리할지, bootstrap에서 처리할지 결정해야한다.
// catserver에 넘겨주면 Catserver의 help가 출력되어 혼동예상.
daemon.load(args);
System.exit(0);
} else if (command.equals("configtest")) {
daemon.load(args);
System.exit(0);
} else {
System.err.println("Bootstrap: command \"" + command + "\" does not exist.");
}
} catch (Throwable t) {
t.printStackTrace();
System.exit(1);
}
}
protected void usage() {
System.out.println("usage: java " + getClass().getName() + " [ -help ]" + " {HomePath}");
}
public void init() throws Exception {
serverHome = System.getProperty("server.home");
if (serverHome == null) {
System.err.println("Warning! Please set env variable \"server.home\".");
usage();
System.exit(1);
}
File f = new File(serverHome);
if (!f.exists()) {
System.err.println("Warning! Path \"" + serverHome + "\" is not exist!");
usage();
System.exit(1);
}
serverLoader = initClassLoader();
Thread.currentThread().setContextClassLoader(serverLoader);
// Load our startup class and call its process() method
Class<?> startupClass = serverLoader.loadClass(serverClass);
Constructor<?> constructor = startupClass.getConstructor(new Class[] { String.class });
serverDaemon = constructor.newInstance(new Object[] { serverHome });
}
public void load(String[] arguments) throws Exception {
// 검색엔진으로 전달되는 args를 받아서 셋팅해준다.
// 대부분 -D옵션을 통해 전달받으므로 아직까지는 셋팅할 내용은 없다.
// Call the load() method
String methodName = "load";
Object[] param = null;
Class<?>[] paramTypes = null;
if (arguments != null && arguments.length > 0) {
paramTypes = new Class[1];
paramTypes[0] = arguments.getClass();
param = new Object[1];
param[0] = arguments;
}
Method method = serverDaemon.getClass().getMethod(methodName, paramTypes);
method.invoke(serverDaemon, param);
}
public void initLibUrls(String libDir, Set<URL> set) throws IOException{
File[] files = new File(libDir).listFiles();
for (File file : files) {
if (file.getName().matches(".*\\.jar$")) {
file = file.getCanonicalFile();
URL url = file.toURI().toURL();
set.add(url);
}
if (file.isDirectory()) {
initLibUrls(file.getAbsolutePath(), set);
}
}
}
private URLClassLoader initClassLoader() {
String libDir = serverHome + LIB_PATH;
Set<URL> set = new LinkedHashSet<URL>();
try {
initLibUrls(libDir, set);
} catch (IOException e) {
e.printStackTrace();
return null;
}
final URL[] urls = set.toArray(new URL[set.size()]);
return new URLClassLoader(urls);
}
public void start() throws Exception {
if (serverDaemon == null)
init();
Method method = serverDaemon.getClass().getMethod("start", (Class[]) null);
method.invoke(serverDaemon, (Object[]) null);
}
public void stop() throws Exception {
Method method = serverDaemon.getClass().getMethod("stop", (Class[]) null);
method.invoke(serverDaemon, (Object[]) null);
}
}