package com.metaweb.gridworks.expr; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Properties; import org.python.core.PyException; import org.python.core.PyNone; import org.python.core.PyObject; import org.python.core.PyString; import org.python.util.PythonInterpreter; public class JythonEvaluable implements Evaluable { private static final String s_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"); StringBuffer sb = new StringBuffer(); sb.append("def " + s_functionName + "():"); for (int i = 0; i < lines.length; i++) { sb.append("\n " + lines[i]); } _engine.exec(sb.toString()); } public Object evaluate(Properties bindings) { try { for (Object key : bindings.keySet()) { String k = (String) key; Object v = bindings.get(k); _engine.set( k, (v instanceof HasFields) ? new JythonHasFieldsWrapper((HasFields) v, bindings) : v ); } Object result = _engine.eval(s_functionName + "()"); return unwrap(result); } catch (PyException e) { return new EvalError(e.toString()); } } protected Object unwrap(Object result) { if (result != null) { if (result instanceof JythonObjectWrapper) { return ((JythonObjectWrapper) result)._obj; } else if (result instanceof JythonHasFieldsWrapper) { return ((JythonHasFieldsWrapper) result)._obj; } else if (result instanceof PyString) { return ((PyString) result).asString(); } else if (result instanceof PyObject) { return unwrap((PyObject) result); } } return result; } protected Object unwrap(PyObject po) { if (po instanceof PyNone) { return null; } else if (po.isNumberType()) { return po.asDouble(); } else if (po.isSequenceType()) { Iterator i = po.asIterable().iterator(); List list = new ArrayList(); while (i.hasNext()) { list.add(unwrap(i.next())); } return list.toArray(); } else { return po; } } }