diff --git a/lib/clojure-1.1.0.jar b/lib/clojure-1.1.0.jar new file mode 100644 index 000000000..b3bc59058 Binary files /dev/null and b/lib/clojure-1.1.0.jar differ diff --git a/lib/jython-2.5.1.jar b/lib/jython-2.5.1.jar new file mode 100644 index 000000000..56b9ce471 Binary files /dev/null and b/lib/jython-2.5.1.jar differ diff --git a/src/main/java/com/metaweb/gridworks/expr/JythonEvaluable.java b/src/main/java/com/metaweb/gridworks/expr/JythonEvaluable.java new file mode 100644 index 000000000..94f697e07 --- /dev/null +++ b/src/main/java/com/metaweb/gridworks/expr/JythonEvaluable.java @@ -0,0 +1,56 @@ +package com.metaweb.gridworks.expr; + +import java.util.Enumeration; +import java.util.Properties; + +import org.python.core.PyException; +import org.python.core.PyString; +import org.python.util.PythonInterpreter; + +public class JythonEvaluable implements Evaluable { + + private String _code; + private static final String _functionName = "temp"; + private static PythonInterpreter _engine = new PythonInterpreter(); + + + public JythonEvaluable(String s) { + // indent and create a function out of the code + String[] lines = s.split("\r\n|\r|\n"); + StringBuilder function = new StringBuilder(); + function.append("def " + _functionName + "():"); + for (int i = 0; i < lines.length; i++) { + function.append("\n " + lines[i]); + } + _code = function.toString(); + } + + public Object evaluate(Properties bindings) { + try { + for (Enumeration e = bindings.keys() ; e.hasMoreElements() ;) { + Object k = e.nextElement(); + Object v = bindings.get(k); + if (v instanceof HasFields) { + _engine.set((String)k, new JythonHasFieldsWrapper((HasFields) v, bindings)); + } else { + _engine.set((String) k, v); + } + } + _engine.exec(_code); + + Object result = _engine.eval(_functionName + "()"); + + // unwrap the underlying Java objects + if (result instanceof JythonObjectWrapper) { + result = ((JythonObjectWrapper) result)._obj; + } else if (result instanceof JythonHasFieldsWrapper) { + result = ((JythonHasFieldsWrapper) result)._obj; + } + + return result; + } catch (PyException e) { + return new EvalError(e.toString()); + } + } + +} diff --git a/src/main/java/com/metaweb/gridworks/expr/JythonHasFieldsWrapper.java b/src/main/java/com/metaweb/gridworks/expr/JythonHasFieldsWrapper.java new file mode 100644 index 000000000..e613330ed --- /dev/null +++ b/src/main/java/com/metaweb/gridworks/expr/JythonHasFieldsWrapper.java @@ -0,0 +1,36 @@ +package com.metaweb.gridworks.expr; + +import java.util.Properties; + +import org.python.core.PyObject; +import org.python.core.PyString; + + +public class JythonHasFieldsWrapper extends PyObject { + public HasFields _obj; + private Properties _bindings; + + public JythonHasFieldsWrapper(HasFields obj, Properties bindings) { + _obj = obj; + _bindings = bindings; + } + + public PyObject __finditem__(PyObject key) { + String k = (String) key.__tojava__(String.class); + Object v = _obj.getField(k, _bindings); + if (v != null) { + if (v instanceof HasFields) { + return new JythonHasFieldsWrapper((HasFields) v, _bindings); + } else if (v instanceof String) { + return new PyString((String) v); + } else if (v instanceof PyObject) { + return (PyObject) v; + } else { + return new JythonObjectWrapper(v); + } + } else { + return null; + } + } + +} diff --git a/src/main/java/com/metaweb/gridworks/expr/JythonObjectWrapper.java b/src/main/java/com/metaweb/gridworks/expr/JythonObjectWrapper.java new file mode 100644 index 000000000..813c74a64 --- /dev/null +++ b/src/main/java/com/metaweb/gridworks/expr/JythonObjectWrapper.java @@ -0,0 +1,15 @@ +package com.metaweb.gridworks.expr; + +import org.python.core.PyObject; + +public class JythonObjectWrapper extends PyObject { + public Object _obj; + + public JythonObjectWrapper(Object obj) { + _obj = obj; + } + + public String toString() { + return _obj.getClass().getSimpleName(); + } +} diff --git a/src/main/java/com/metaweb/gridworks/expr/MetaParser.java b/src/main/java/com/metaweb/gridworks/expr/MetaParser.java index 31202ab6b..399d1a13d 100644 --- a/src/main/java/com/metaweb/gridworks/expr/MetaParser.java +++ b/src/main/java/com/metaweb/gridworks/expr/MetaParser.java @@ -1,5 +1,10 @@ package com.metaweb.gridworks.expr; +import java.io.StringReader; +import java.util.Properties; + +import clojure.lang.IFn; + import com.metaweb.gridworks.gel.Parser; abstract public class MetaParser { @@ -29,19 +34,17 @@ abstract public class MetaParser { } static protected Evaluable parseJython(String s) throws ParsingException { - return null; + return new JythonEvaluable(s); } static protected Evaluable parseClojure(String s) throws ParsingException { - - /* try { IFn fn = (IFn) clojure.lang.Compiler.load(new StringReader( - "(fn [value row cells] " + s + ")" + "(fn [value cell cells row rowIndex] " + s + ")" )); return new Evaluable() { - final private IFn _fn; + private IFn _fn; public Evaluable init(IFn fn) { _fn = fn; @@ -51,9 +54,11 @@ abstract public class MetaParser { public Object evaluate(Properties bindings) { try { return _fn.invoke( - bindings.get("value"), - bindings.get("row"), - bindings.get("cells") + bindings.get("value"), + bindings.get("cell"), + bindings.get("cells"), + bindings.get("row"), + bindings.get("rowIndex") ); } catch (Exception e) { return new EvalError(e.getMessage()); @@ -61,9 +66,7 @@ abstract public class MetaParser { } }.init(fn); } catch (Exception e) { - return new ParsingException(e); + throw new ParsingException(e.getMessage()); } - */ - return null; } }