Hi Folks,

Here's a little holiday present as I head off on vacation. It's a
Userfunction, written in Java, which effectively lets you implement
any Java interface by writing a single Jess deffunction. I think this
is the tip of the iceberg as far as the kinds of features we'll see in
Jess 7. There's going to be a lot of code generation, embedding bits
of Java in Jess code, etc.

For now, though, it's a fun toy. You can easily use it to run a Jess
function in another thread, for example, or to create a new kind of
Swing-related event listener. The comment at the beginning of the
source file shows how to use it, once it's compiled.

Happy holidays to everyone.


---------------------------------------------------------
Ernest Friedman-Hill  
Distributed Systems Research        Phone: (925) 294-2154
Sandia National Labs                FAX:   (925) 294-2234
Org. 8920, MS 9012                  [EMAIL PROTECTED]
PO Box 969                  http://herzberg.ca.sandia.gov
Livermore, CA 94550
import java.lang.reflect.*;
import jess.*;

/**
 * IH
 * Lets you implement any interface from Jess. Requires JDK
 * 1.3. Here's an example of creating a Runnable object entirely from Jess:
 *
 * (load-function MakeProxy) 
 * 
 * ;; Function's arguments will be: name of function (my-runnable),
 * ;; name of method called on proxy object (run), individual arguments
 * ;; passed to called method (none here).
 * (deffunction my-runnable ($?rest)
 *   (printout t "Hello, World" crlf))  
 * 
 * ;; Make a java.lang.Runnable whose run() method will call my-runnable
 * ;; Unfortunately, can't use Jess's import tables from outside the Jess
 * ;; package -- the necessary methods will be made public in Jess 6.1 --
 * ;; so we have to spell out the class name.
 * (bind ?r (make-proxy java.lang.Runnable my-runnable)) 
 * 
 * ;; Use the runnable
 * ((new Thread ?r) start)     
 * 
 * (C) 2001 E.J. Friedman-Hill and Sandia National Labs
 * $Id$ */

public class MakeProxy implements Userfunction {

    public String getName() {
        return "make-proxy";
    }

    public Value call(ValueVector vv, Context context) throws JessException {
        try {
            Class clazz = Class.forName(vv.get(1).stringValue(context));
            String name = vv.get(2).stringValue(context);
            Rete engine = context.getEngine();
            Userfunction uf = engine.findUserfunction(name);

            Object proxy = 
                Proxy.newProxyInstance(clazz.getClassLoader(),
                                       new Class[] {clazz},
                                       new IH(uf,engine.getGlobalContext()));
            return new Value(proxy);
            
        } catch (Exception e) {
            throw new JessException("make-proxy",
                                    "Can't make proxy:",
                                    e.getMessage());
        }
    }        

    private class IH implements InvocationHandler {
        private Userfunction m_function;
        private Context m_context;
    
        IH(Userfunction theFunction, Context theContext) {
            m_function = theFunction;
            m_context = theContext;
        }

        public Object invoke(Object proxy,
                         Method method, 
                         Object[] args)
            throws Throwable {
            
            ValueVector vv = new ValueVector();
            vv.add(new Value(m_function.getName(), RU.ATOM));
            vv.add(new Value(method.getName(), RU.ATOM));
            if (args != null)
                for (int i=0; i<args.length; ++i)
                    vv.add(new Value(args[i]));
       
            return m_function.call(vv, m_context);
        }
    }
}


Reply via email to