1 21 22 package org.armedbear.lisp; 23 24 import java.lang.reflect.InvocationHandler ; 25 import java.lang.reflect.Method ; 26 import java.lang.reflect.Proxy ; 27 import java.util.HashMap ; 28 import java.util.Map ; 29 import java.util.WeakHashMap ; 30 31 public final class JProxy extends Lisp 32 { 33 private static final Map table = new WeakHashMap (); 34 35 private static final Primitive _JNEW_PROXY = 38 new Primitive("%jnew-proxy", PACKAGE_JAVA, false, "interface &rest method-names-and-defs") 39 { 40 public LispObject execute(LispObject[] args) throws ConditionThrowable 41 { 42 int length = args.length; 43 if (length < 3 || length % 2 != 1) 44 return signal(new WrongNumberOfArgumentsException(this)); 45 Map lispDefinedMethods = new HashMap (); 46 for (int i = 1; i < length; i = i+2) 47 lispDefinedMethods.put(args[i].getStringValue(),(Function)args[i+1]); 48 Class iface = (Class ) args[0].javaInstance(); 49 Object proxy = 50 Proxy.newProxyInstance(iface.getClassLoader(), new Class [] { iface }, new LispHandler(table)); 51 table.put(proxy, new Entry(iface, lispDefinedMethods)); 52 return new JavaObject(proxy); 53 } 54 }; 55 56 private static class LispHandler implements InvocationHandler 57 { 58 Map table; 59 60 LispHandler (Map table) 61 { 62 this.table = table; 63 } 64 65 public Object invoke(Object proxy, Method method, Object [] args) 66 { 67 String methodName = method.getName(); 68 69 if (methodName.equals("hashCode")) { 70 return new Integer (System.identityHashCode(proxy)); 71 } else if (methodName.equals("equals")) { 72 return (proxy == args[0] ? Boolean.TRUE : Boolean.FALSE); 73 } else if (methodName.equals("toString")) { 74 return proxy.getClass().getName() + '@' + Integer.toHexString(proxy.hashCode()); 75 } 76 77 if (table.containsKey(proxy)) { 78 Entry entry = (Entry)table.get(proxy); 79 Function f = entry.getLispMethod(methodName); 80 if (f != null) { 81 if (args == null) args = new Object [0]; 83 LispObject[] lispArgs = new LispObject[args.length]; 84 for (int i = 0 ; i< args.length; i++) 85 lispArgs[i] = new JavaObject(args[i]); 86 try { 87 LispObject result = f.execute(lispArgs); 88 return (method.getReturnType() == void.class ? null : result.javaInstance()); 89 } 90 catch (ConditionThrowable t) { 91 t.printStackTrace(); 92 } 93 } 94 } 95 return null; 96 } 97 } 98 99 private static class Entry 100 { 101 Class iface; 102 Map lispDefinedMethods; 103 104 public Entry (Class iface, Map lispDefinedMethods) 105 { 106 this.iface = iface; 107 this.lispDefinedMethods = lispDefinedMethods; 108 } 109 110 public Function getLispMethod(String methodName) 111 { 112 if (lispDefinedMethods.containsKey(methodName)) 113 return (Function)lispDefinedMethods.get(methodName); 114 return null; 115 } 116 } 117 } 118 | Popular Tags |