Changeset 11369


Ignore:
Timestamp:
10/30/08 06:30:25 (13 years ago)
Author:
astalla
Message:

Introduced jmake-invocation-handler and jmake-proxy.

Location:
branches/scripting/j/src/org/armedbear/lisp
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • branches/scripting/j/src/org/armedbear/lisp/Autoload.java

    r11368 r11369  
    490490        autoload(PACKAGE_JAVA, "%jnew-proxy", "JProxy");
    491491        autoload(PACKAGE_JAVA, "%jimplement-interface", "JProxy");
     492        autoload(PACKAGE_JAVA, "%jmake-invocation-handler", "JProxy");
     493        autoload(PACKAGE_JAVA, "%jmake-proxy", "JProxy");
    492494        autoload(PACKAGE_JAVA, "%jnew-runtime-class", "RuntimeClass");
    493495        autoload(PACKAGE_JAVA, "%jredefine-method", "RuntimeClass");
  • branches/scripting/j/src/org/armedbear/lisp/JProxy.java

    r11368 r11369  
    123123  }
    124124 
    125     //NEW IMPLEMENTATION by Alessio Stalla
    126  
    127    
    128  
     125    //NEW IMPLEMENTATION by Alessio Stalla
     126 
     127    public static class LispInvocationHandler implements InvocationHandler {
     128     
     129      private Function function;
     130      private static Method hashCodeMethod;
     131      private static Method equalsMethod;
     132      private static Method toStringMethod;
     133     
     134      static {
     135        try {
     136        hashCodeMethod = Object.class.getMethod("hashCode", new Class[] {});
     137        equalsMethod = Object.class.getMethod("equals", new Class[] { Object.class });
     138        toStringMethod = Object.class.getMethod("toString", new Class[] {});
     139      } catch (Exception e) {
     140        throw new Error("Something got horribly wrong - can't get a method from Object.class", e);
     141      }
     142      }
     143
     144      public LispInvocationHandler(Function function) {
     145        this.function = function;
     146      }
     147     
     148    @Override
     149    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
     150        if(hashCodeMethod.equals(method)) {
     151          return proxy.hashCode();
     152        }
     153        if(equalsMethod.equals(method)) {
     154          return proxy.equals(args[0]);
     155        }
     156        if(toStringMethod.equals(method)) {
     157          return proxy.toString();
     158        }
     159       
     160      LispObject[] lispArgs = new LispObject[args.length + 2];
     161      lispArgs[0] = toLispObject(proxy);
     162      lispArgs[1] = new JavaObject(method);
     163      for(int i = 0; i < args.length; i++) {
     164        lispArgs[i + 2] = toLispObject(args[i]);
     165      }
     166      Object retVal = (function.execute(lispArgs)).javaInstance();
     167      /* DOES NOT WORK due to autoboxing!
     168      if(retVal != null && !method.getReturnType().isAssignableFrom(retVal.getClass())) {
     169        return error(new TypeError(new JavaObject(retVal), new JavaObject(method.getReturnType())));
     170      }*/
     171      return retVal;
     172    }
     173  }
     174 
     175    private static final Primitive _JMAKE_INVOCATION_HANDLER =
     176      new Primitive("%jmake-invocation-handler", PACKAGE_JAVA, false,
     177                    "function") {
     178   
     179          public LispObject execute(LispObject[] args) throws ConditionThrowable {
     180            int length = args.length;
     181            if (length != 1) {
     182              return error(new WrongNumberOfArgumentsException(this));
     183            }
     184            if(!(args[0] instanceof Function)) {
     185              return error(new TypeError(args[0], Symbol.FUNCTION));
     186            }
     187           
     188            return new JavaObject(new LispInvocationHandler((Function) args[0]));
     189          }
     190      };
     191
     192    private static final Primitive _JMAKE_PROXY =
     193      new Primitive("%jmake-proxy", PACKAGE_JAVA, false,
     194                    "interface invocation-handler") {
     195   
     196          public LispObject execute(final LispObject[] args) throws ConditionThrowable {
     197            int length = args.length;
     198            if (length != 2) {
     199              return error(new WrongNumberOfArgumentsException(this));
     200            }
     201            if(!(args[0] instanceof JavaObject) ||
     202               !(((JavaObject) args[0]).javaInstance() instanceof Class)) {
     203              return error(new TypeError(args[0], new SimpleString(Class.class.getName())));
     204            }
     205            if(!(args[1] instanceof JavaObject) ||
     206               !(((JavaObject) args[1]).javaInstance() instanceof InvocationHandler)) {
     207                return error(new TypeError(args[1], new SimpleString(InvocationHandler.class.getName())));
     208              }
     209            Class<?> iface = (Class<?>) ((JavaObject) args[0]).javaInstance();
     210            InvocationHandler invocationHandler = (InvocationHandler) ((JavaObject) args[1]).javaInstance();
     211            Object proxy = Proxy.newProxyInstance(
     212                iface.getClassLoader(),
     213                new Class[] { iface },
     214                invocationHandler);
     215            return new JavaObject(proxy);
     216          }
     217      };   
     218     
     219  private static LispObject toLispObject(Object obj) {
     220    return (obj instanceof LispObject) ? (LispObject) obj : new JavaObject(obj);
     221  }   
     222     
    129223    private static final Primitive _JIMPLEMENT_INTERFACE =
    130224      new Primitive("%jimplement-interface", PACKAGE_JAVA, false,
  • branches/scripting/j/src/org/armedbear/lisp/autoloads.lisp

    r11368 r11369  
    190190(export 'jimplement-interface "JAVA")
    191191(autoload 'jimplement-interface "java")
     192(export 'jmake-invocation-handler "JAVA")
     193(autoload 'jmake-invocation-handler "java")
     194(export 'jmake-proxy "JAVA")
     195(autoload 'jmake-proxy "java")
    192196(export 'jobject-class "JAVA")
    193197(autoload 'jobject-class "java")
  • branches/scripting/j/src/org/armedbear/lisp/java.lisp

    r11368 r11369  
    102102        (push method-name method-names-and-defs)))
    103103    (apply #'%jimplement-interface interface method-names-and-defs)))
     104
     105(defun jmake-invocation-handler (function)
     106  (%jmake-invocation-handler function))
     107
     108(defun jmake-proxy (interface invocation-handler)
     109  (let ((handler (if (functionp invocation-handler)
     110         (jmake-invocation-handler invocation-handler)
     111         invocation-handler)))
     112    (%jmake-proxy (jclass interface) handler)))
    104113
    105114(defun jobject-class (obj)
  • branches/scripting/j/src/org/armedbear/lisp/scripting/AbclScriptEngine.java

    r11368 r11369  
    278278      in = new ReaderInputStream(ctx.getReader());
    279279      out = new WriterOutputStream(ctx.getWriter());
     280      Stream outStream = new Stream(out, Symbol.CHARACTER);
    280281      retVal = evalScript.execute(makeBindings(ctx.getBindings(ScriptContext.GLOBAL_SCOPE)),
    281282                    makeBindings(ctx.getBindings(ScriptContext.ENGINE_SCOPE)),
    282283                    new Stream(in, Symbol.CHARACTER),
    283                     new Stream(out, Symbol.CHARACTER),
     284                    outStream,
    284285                    new SimpleString(code), new JavaObject(ctx));
     286      outStream._finishOutput();
     287      out.flush();
     288      in.close();
     289      out.close();
    285290      return toJava(retVal);
    286291    } catch (ConditionThrowable e) {
Note: See TracChangeset for help on using the changeset viewer.