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.Py; import org.python.core.PyException; import org.python.core.PyFunction; 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 + "(value, cell, cells, row, rowIndex):"); for (int i = 0; i < lines.length; i++) { sb.append("\n " + lines[i]); } _engine.exec(sb.toString()); } public Object evaluate(Properties bindings) { try { // call the temporary PyFunction directly Object result = ((PyFunction)_engine.get(s_functionName)).__call__( new PyObject[] { Py.java2py( bindings.get("value") ), new JythonHasFieldsWrapper((HasFields) bindings.get("cell"), bindings), new JythonHasFieldsWrapper((HasFields) bindings.get("cells"), bindings), new JythonHasFieldsWrapper((HasFields) bindings.get("row"), bindings), Py.java2py( bindings.get("rowIndex") ) } ); 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; } } }