UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2013 Olaf Wintermann. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 package webserver; 29 30 import java.io.File; 31 import java.lang.reflect.InvocationTargetException; 32 import java.lang.reflect.Method; 33 import java.net.MalformedURLException; 34 import java.net.URL; 35 import java.net.URLClassLoader; 36 import java.util.ArrayList; 37 import java.util.logging.Level; 38 import java.util.logging.Logger; 39 import webserver.nsapi.Module; 40 import webserver.nsapi.PBlock; 41 import webserver.nsapi.Request; 42 import webserver.nsapi.SAF; 43 import webserver.nsapi.Session; 44 45 class ServerPlugin { 46 private ArrayList<ServerFunction> registeredFunctions = new ArrayList<>(32); 47 48 public ServerPlugin() { 49 50 } 51 52 public native void addMethod(String name, int safIndex); 53 54 static { 55 System.loadLibrary("nsapi_jni"); 56 } 57 58 public int loadModule(String jar, String classes) { 59 System.out.println("load-jmodule jar=\""+jar+"\" classes=\""+classes+"\""); 60 61 File jarFile = new File(jar); 62 if(!jarFile.exists()) { 63 System.err.println("jar file does not exist"); 64 return -1; 65 } 66 try { 67 URL[] urls = new URL[]{jarFile.toURI().toURL()}; 68 URLClassLoader cl = new URLClassLoader(urls, this.getClass().getClassLoader()); 69 70 for(String className : classes.split(",")) { 71 Class moduleClass = Class.forName(className, true, cl); 72 loadClass(moduleClass); 73 } 74 } catch (MalformedURLException e) { 75 System.err.println("ServerPlugin.loadModule: "+e); 76 return -1; 77 } catch (ClassNotFoundException e) { 78 System.err.println("Java Module Class not found: "+e); 79 return -1; 80 } catch (InstantiationException e) { 81 System.err.println("ServerPlugin.loadModule: "+e); 82 return -1; 83 } catch (IllegalAccessException e) { 84 System.err.println("ServerPlugin.loadModule: "+e); 85 return -1; 86 } 87 88 System.out.println("Java Module loaded"); 89 return 0; 90 } 91 92 public void loadClass(Class cl) throws InstantiationException, IllegalAccessException { 93 Module module = (Module)cl.getAnnotation(Module.class); 94 if(module == null) { 95 System.err.println("Missing Module annotation for class: "+cl.getCanonicalName()); 96 return; 97 } 98 99 Object moduleInstance = cl.newInstance(); 100 for(Method m : cl.getMethods()) { 101 if(isSAF(m)) { 102 SAF saf = m.getAnnotation(SAF.class); 103 if(saf.init()) { 104 105 } 106 if(saf.name().length() > 0) { 107 ServerFunction f = new ServerFunction(); 108 f.module = moduleInstance; 109 f.method = m; 110 111 String safName = module.name() + "." + saf.name(); 112 registeredFunctions.add(f); 113 int index = registeredFunctions.lastIndexOf(f); 114 addMethod(safName, index); 115 } 116 } 117 } 118 } 119 120 private boolean isSAF(Method m) { 121 SAF saf = m.getAnnotation(SAF.class); 122 if(saf != null) { 123 // check method signature 124 if(m.getReturnType() != int.class) { 125 System.err.println("wrong return type for SAF: "+m.getName()); 126 return false; 127 } 128 Class paramTypes[] = m.getParameterTypes(); 129 if(paramTypes.length != 3) { 130 System.err.println("wrong number of parameters for SAF: "+m.getName()); 131 return false; 132 } 133 if(paramTypes[0] != PBlock.class) { 134 System.err.println("wrong method signature for SAF: "+m.getName()); 135 return false; 136 } 137 if(paramTypes[1] != Session.class) { 138 System.err.println("wrong method signature for SAF: "+m.getName()); 139 return false; 140 } 141 if(paramTypes[2] != Request.class) { 142 System.err.println("wrong method signature for SAF: "+m.getName()); 143 return false; 144 } 145 return true; 146 } 147 return false; 148 } 149 150 public int exec(int safIndex) { 151 System.out.println("(Java) exec: "+safIndex); 152 ServerFunction saf = registeredFunctions.get(safIndex); 153 if(saf == null) { 154 return -1; 155 } 156 Integer ret = new Integer(-1); 157 try { 158 ret = (Integer)saf.method.invoke(saf.module, null, null, null); 159 } catch (IllegalAccessException e) { 160 e.printStackTrace(); 161 } catch (IllegalArgumentException e) { 162 e.printStackTrace(); 163 } catch (InvocationTargetException e) { 164 e.printStackTrace(); 165 } 166 return ret.intValue(); 167 } 168 } 169