package webserver;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import webserver.nsapi.Module;
import webserver.nsapi.PBlock;
import webserver.nsapi.Request;
import webserver.nsapi.SAF;
import webserver.nsapi.Session;
class ServerPlugin {
private ArrayList<ServerFunction> registeredFunctions = new ArrayList<>(32);
public ServerPlugin() {
}
public native void addMethod(String name, int safIndex);
static {
System.loadLibrary("nsapi_jni");
}
public int loadModule(String jar, String classes) {
System.out.println("load-jmodule jar=\""+jar+"\" classes=\""+classes+"\"");
File jarFile = new File(jar);
if(!jarFile.exists()) {
System.err.println("jar file does not exist");
return -1;
}
try {
URL[] urls = new URL[]{jarFile.toURI().toURL()};
URLClassLoader cl = new URLClassLoader(urls, this.getClass().getClassLoader());
for(String className : classes.split(",")) {
Class moduleClass = Class.forName(className, true, cl);
loadClass(moduleClass);
}
} catch (MalformedURLException e) {
System.err.println("ServerPlugin.loadModule: "+e);
return -1;
} catch (ClassNotFoundException e) {
System.err.println("Java Module Class not found: "+e);
return -1;
} catch (InstantiationException e) {
System.err.println("ServerPlugin.loadModule: "+e);
return -1;
} catch (IllegalAccessException e) {
System.err.println("ServerPlugin.loadModule: "+e);
return -1;
}
System.out.println("Java Module loaded");
return 0;
}
public void loadClass(Class cl) throws InstantiationException, IllegalAccessException {
Module module = (Module)cl.getAnnotation(Module.class);
if(module == null) {
System.err.println("Missing Module annotation for class: "+cl.getCanonicalName());
return;
}
Object moduleInstance = cl.newInstance();
for(Method m : cl.getMethods()) {
if(isSAF(m)) {
SAF saf = m.getAnnotation(SAF.class);
if(saf.init()) {
}
if(saf.name().length() > 0) {
ServerFunction f = new ServerFunction();
f.module = moduleInstance;
f.method = m;
String safName = module.name() + "." + saf.name();
registeredFunctions.add(f);
int index = registeredFunctions.lastIndexOf(f);
addMethod(safName, index);
}
}
}
}
private boolean isSAF(Method m) {
SAF saf = m.getAnnotation(SAF.class);
if(saf != null) {
if(m.getReturnType() != int.class) {
System.err.println("wrong return type for SAF: "+m.getName());
return false;
}
Class paramTypes[] = m.getParameterTypes();
if(paramTypes.length != 3) {
System.err.println("wrong number of parameters for SAF: "+m.getName());
return false;
}
if(paramTypes[0] != PBlock.class) {
System.err.println("wrong method signature for SAF: "+m.getName());
return false;
}
if(paramTypes[1] != Session.class) {
System.err.println("wrong method signature for SAF: "+m.getName());
return false;
}
if(paramTypes[2] != Request.class) {
System.err.println("wrong method signature for SAF: "+m.getName());
return false;
}
return true;
}
return false;
}
public int exec(int safIndex) {
System.out.println("(Java) exec: "+safIndex);
ServerFunction saf = registeredFunctions.get(safIndex);
if(saf == null) {
return -1;
}
Integer ret = new Integer(-1);
try {
ret = (Integer)saf.method.invoke(saf.module, null, null, null);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return ret.intValue();
}
}