src/server/plugins/java/javasrc/webserver/ServerPlugin.java

changeset 84
afd57ce39ec9
--- /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<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) {
+            // 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();
+    }
+}

mercurial