package org.perl.inline.java ; import java.net.* ; import java.util.* ; import java.io.* ; import java.lang.reflect.* ; /* This is the ClassLoader that loads the users code. It is also used to pass reflection calls to the InlineJavaUserClassLink so that it will execute them. */ class InlineJavaUserClassLoader extends URLClassLoader { private HashMap urls = new HashMap() ; private Object link = null ; private Method invoke = null ; private Method get = null ; private Method set = null ; private Method array_get = null ; private Method array_set = null ; private Method create = null ; public InlineJavaUserClassLoader(){ // Added Thread.currentThread().getContextClassLoader() so that the code works // in Tomcat and possibly other embedded environments asa well. super(new URL [] {}, Thread.currentThread().getContextClassLoader()) ; } public void AddClassPath(String path) throws InlineJavaException { try { File p = new File(path) ; URL u = p.toURL() ; if (urls.get(u) == null){ urls.put(u, "1") ; addURL(u) ; InlineJavaUtils.debug(2, "added " + u + " to classpath") ; } } catch (MalformedURLException e){ throw new InlineJavaException("Can't add invalid classpath entry '" + path + "'") ; } } synchronized private void check_link() throws InlineJavaException { if (link == null){ try { InlineJavaUtils.debug(1, "loading InlineJavaUserClassLink via InlineJavaUserClassLoader") ; Class c = Class.forName("InlineJavaUserClassLink", true, this) ; link = c.newInstance() ; invoke = find_method(c, "invoke") ; get = find_method(c, "get") ; set = find_method(c, "set") ; array_get = find_method(c, "array_get") ; array_set = find_method(c, "array_set") ; create = find_method(c, "create") ; } catch (Exception e){ throw new InlineJavaException("InlineJavaUserClassLoader can't load InlineJavaUserClassLink: invalid classpath setup (" + e.getClass().getName() + ": " + e.getMessage() + ")") ; } } } private Method find_method(Class c, String name) throws InlineJavaException { Method ml[] = c.getMethods() ; for (int i = 0 ; i < ml.length ; i++){ if (ml[i].getName().equals(name)){ return ml[i] ; } } throw new InlineJavaException("Can't find method '" + name + "' in class InlineJavaUserClassLink") ; } private Object invoke_via_link(Method m, Object p[]) throws NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InlineJavaException { try { return m.invoke(link, p) ; } catch (IllegalAccessException e){ throw new InlineJavaException("Can't invoke method from class InlineJavaUserClassLink: IllegalAccessException") ; } catch (IllegalArgumentException e){ throw new InlineJavaException("Can't invoke method from class InlineJavaUserClassLink: IllegalArgumentException") ; } catch (InvocationTargetException e){ Throwable t = e.getTargetException() ; if (t instanceof NoSuchMethodException){ throw (NoSuchMethodException)t ; } else if (t instanceof InstantiationException){ throw (InstantiationException)t ; } else if (t instanceof IllegalAccessException){ throw (IllegalAccessException)t ; } if (t instanceof IllegalAccessException){ throw (IllegalAccessException)t ; } else if (t instanceof IllegalArgumentException){ throw (IllegalArgumentException)t ; } else if (t instanceof InvocationTargetException){ throw (InvocationTargetException)t ; } // Not sure if this is really necessary, but... else if (t instanceof RuntimeException){ RuntimeException re = (RuntimeException)t ; throw re ; } else{ // In theory this case is impossible. throw new InlineJavaException("Unexpected exception of type '" + t.getClass().getName() + "': " + t.getMessage()) ; } } } public Object invoke(Method m, Object o, Object p[]) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InlineJavaException { check_link() ; try { return invoke_via_link(invoke, new Object [] {m, o, p}) ; } catch (NoSuchMethodException me){/* Impossible */} catch (InstantiationException ie){/* Impossible */} return null ; } public Object get(Field f, Object o) throws IllegalAccessException, IllegalArgumentException, InlineJavaException { check_link() ; try { return invoke_via_link(get, new Object [] {f, o}) ; } catch (NoSuchMethodException me){/* Impossible */} catch (InstantiationException ie){/* Impossible */} catch (InvocationTargetException e){/* Impossible */} return null ; } public void set(Field f, Object o, Object p) throws IllegalAccessException, IllegalArgumentException, InlineJavaException { check_link() ; try { invoke_via_link(set, new Object [] {f, o, p}) ; } catch (NoSuchMethodException me){/* Impossible */} catch (InstantiationException ie){/* Impossible */} catch (InvocationTargetException e){/* Impossible */} } public Object array_get(Object o, int idx) throws InlineJavaException { check_link() ; try { return invoke_via_link(array_get, new Object [] {o, new Integer(idx)}) ; } catch (NoSuchMethodException me){/* Impossible */} catch (InstantiationException ie){/* Impossible */} catch (IllegalAccessException iae){/* Impossible */} catch (IllegalArgumentException iae){/* Impossible */} catch (InvocationTargetException e){/* Impossible */} return null ; } public void array_set(Object o, int idx, Object elem) throws IllegalArgumentException, InlineJavaException { check_link() ; try { invoke_via_link(array_set, new Object [] {o, new Integer(idx), elem}) ; } catch (NoSuchMethodException me){/* Impossible */} catch (InstantiationException ie){/* Impossible */} catch (IllegalAccessException iae){/* Impossible */} catch (InvocationTargetException e){/* Impossible */} } public Object create(Class p, Object args[], Class proto[]) throws NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InlineJavaException { check_link() ; return invoke_via_link(create, new Object [] {p, args, proto}) ; } }