diff -r 28433f06d5ee -r afd57ce39ec9 src/server/plugins/java/javasrc/webserver/ServerPlugin.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/server/plugins/java/javasrc/webserver/ServerPlugin.java Mon Jul 08 11:10:54 2013 +0200 @@ -0,0 +1,168 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +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 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) { + // check method signature + 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(); + } +}