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);
}
}
}