Ignore:
Timestamp:
07/01/10 21:02:45 (12 years ago)
Author:
astalla
Message:

Added support for implementing multiple interfaces using jmake-proxy

Location:
trunk/abcl/src/org/armedbear/lisp
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/abcl/src/org/armedbear/lisp/JProxy.java

    r12513 r12774  
    211211    private static final Primitive _JMAKE_PROXY =
    212212      new Primitive("%jmake-proxy", PACKAGE_JAVA, false,
    213                     "interface invocation-handler") {
     213                    "interfaces invocation-handler") {
    214214   
    215215          public LispObject execute(final LispObject[] args) {
     
    218218              return error(new WrongNumberOfArgumentsException(this));
    219219            }
    220             if(!(args[0] instanceof JavaObject) ||
    221                !(((JavaObject) args[0]).javaInstance() instanceof Class)) {
    222               return error(new TypeError(args[0], new SimpleString(Class.class.getName())));
    223             }
    224             if(!(args[1] instanceof JavaObject) ||
    225                !(((JavaObject) args[1]).javaInstance() instanceof InvocationHandler)) {
    226               return error(new TypeError(args[1], new SimpleString(InvocationHandler.class.getName())));
    227             }
    228             Class<?> iface = (Class<?>) ((JavaObject) args[0]).javaInstance();
    229             InvocationHandler invocationHandler = (InvocationHandler) ((JavaObject) args[1]).javaInstance();
     220            if(!(args[0] instanceof Cons)) {
     221          return error(new TypeError(args[0], new SimpleString("CONS")));
     222            }
     223      Class[] ifaces = new Class[args[0].length()];
     224      LispObject ifList = args[0];
     225      for(int i = 0; i < ifaces.length; i++) {
     226          ifaces[i] = ifList.car().javaInstance(Class.class);
     227          ifList = ifList.cdr();
     228      }
     229            InvocationHandler invocationHandler = ((JavaObject) args[1]).javaInstance(InvocationHandler.class);
    230230            Object proxy = Proxy.newProxyInstance(
    231                 iface.getClassLoader(),
    232                 new Class[] { iface },
     231                JavaClassLoader.getCurrentClassLoader(),
     232                ifaces,
    233233                invocationHandler);
    234234            synchronized(proxyMap) {
  • trunk/abcl/src/org/armedbear/lisp/java.lisp

    r12715 r12774  
    9393
    9494(defgeneric jmake-proxy (interface implementation &optional lisp-this)
    95   (:documentation "Returns a proxy Java object implementing the provided interface using methods implemented in Lisp - typically closures, but implementations are free to provide other mechanisms. You can pass an optional 'lisp-this' object that will be passed to the implementing methods as their first argument. If you don't provide this object, NIL will be used. The second argument of the Lisp methods is the name of the Java method being implemented. This has the implication that overloaded methods are merged, so you have to manually discriminate them if you want to. The remaining arguments are java-objects wrapping the method's parameters."))
     95  (:documentation "Returns a proxy Java object implementing the provided interface(s) using methods implemented in Lisp - typically closures, but implementations are free to provide other mechanisms. You can pass an optional 'lisp-this' object that will be passed to the implementing methods as their first argument. If you don't provide this object, NIL will be used. The second argument of the Lisp methods is the name of the Java method being implemented. This has the implication that overloaded methods are merged, so you have to manually discriminate them if you want to. The remaining arguments are java-objects wrapping the method's parameters."))
     96
     97(defun canonicalize-jproxy-interfaces (ifaces)
     98  (if (listp ifaces)
     99      (mapcar #'jclass ifaces)
     100      (list (jclass ifaces))))
     101
    96102
    97103(defmethod jmake-proxy (interface invocation-handler &optional lisp-this)
    98104  "Basic implementation that directly uses an invocation handler."
    99   (%jmake-proxy (jclass interface) invocation-handler lisp-this))
     105  (%jmake-proxy (canonicalize-jproxy-interfaces interface) invocation-handler lisp-this))
    100106
    101107(defmethod jmake-proxy (interface (implementation function) &optional lisp-this)
    102108  "Implements a Java interface forwarding method calls to a Lisp function."
    103   (%jmake-proxy (jclass interface) (jmake-invocation-handler implementation) lisp-this))
     109  (%jmake-proxy (canonicalize-jproxy-interfaces interface) (jmake-invocation-handler implementation) lisp-this))
    104110
    105111(defmethod jmake-proxy (interface (implementation package) &optional lisp-this)
     
    115121          (princ (char-upcase char) str)))
    116122        name)))))
    117     (%jmake-proxy (jclass interface)
     123    (%jmake-proxy (canonicalize-jproxy-interfaces interface)
    118124      (jmake-invocation-handler
    119125       (lambda (obj method &rest args)
     
    134140(defmethod jmake-proxy (interface (implementation hash-table) &optional lisp-this)
    135141  "Implements a Java interface using closures in an hash-table keyed by Java method name."
    136   (%jmake-proxy (jclass interface)
     142  (%jmake-proxy (canonicalize-jproxy-interfaces interface)
    137143    (jmake-invocation-handler
    138144     (lambda (obj method &rest args)
Note: See TracChangeset for help on using the changeset viewer.