Created
July 12, 2012 19:19
-
-
Save metlos/3100283 to your computer and use it in GitHub Desktop.
PythonScriptEngineInitializer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class PythonScriptEngineInitializer implements ScriptEngineInitializer { | |
private static final Log LOG = LogFactory.getLog(PythonScriptEngineInitializer.class); | |
static { | |
Properties props = new Properties(); | |
props.put("python.packages.paths", "java.class.path,sun.boot.class.path"); | |
props.put("python.packages.directories", "java.ext.dirs"); | |
props.put("python.cachedir.skip", false); | |
PythonInterpreter.initialize(System.getProperties(), props, null); | |
} | |
private ScriptEngineManager engineManager = new ScriptEngineManager(); | |
@Override | |
public ScriptEngine instantiate(Set<String> packages, PermissionCollection permissions) throws ScriptException { | |
ScriptEngine eng = engineManager.getEngineByName("python"); | |
//XXX this might not work perfectly in jython | |
//but we can't make it work perfectly either, so let's just | |
//keep our fingers crossed.. | |
//http://www.jython.org/jythonbook/en/1.0/ModulesPackages.html#from-import-statements | |
for (String pkg : packages) { | |
try { | |
eng.eval("from " + pkg + " import *\n"); | |
} catch (ScriptException e) { | |
//well, let's just keep things going, this is not fatal... | |
LOG.info("Python script engine could not pre-import members of package '" + pkg + "'."); | |
} | |
} | |
//fingers crossed we can secure jython like this | |
return permissions == null ? eng : new SandboxedScriptEngine(eng, permissions); | |
} | |
@Override | |
public void installScriptSourceProvider(ScriptEngine scriptEngine, ScriptSourceProvider provider) { | |
PySystemState sys = Py.getSystemState(); | |
if (sys != null) { | |
sys.path_hooks.append(new PythonSourceProvider(provider)); | |
} | |
} | |
@Override | |
public Set<String> generateIndirectionMethods(String boundObjectName, Set<Method> overloadedMethods) { | |
if (overloadedMethods == null || overloadedMethods.isEmpty()) { | |
return Collections.emptySet(); | |
} | |
Set<Integer> argCnts = new HashSet<Integer>(); | |
for (Method m : overloadedMethods) { | |
argCnts.add(m.getParameterTypes().length); | |
} | |
String methodName = overloadedMethods.iterator().next().getName(); | |
StringBuilder functionBody = new StringBuilder(); | |
functionBody.append("def ").append(methodName).append("(*args, **kwargs):\n"); | |
functionBody.append("\t").append("if len(kwargs) > 0:\n"); | |
functionBody.append("\t\t").append("raise ValueError(\"Named arguments not supported for Java methods\")\n"); | |
functionBody.append("\t").append("argCnt = len(args)\n"); | |
for (Integer argCnt : argCnts) { | |
functionBody.append("\t").append("if argCnt == ").append(argCnt).append(":\n"); | |
functionBody.append("\t\treturn ").append(boundObjectName).append(".").append(methodName).append("("); | |
int last = argCnt - 1; | |
for (int i = 0; i < argCnt; ++i) { | |
functionBody.append("args[").append(i).append("]"); | |
if (i < last) { | |
functionBody.append(", "); | |
} | |
} | |
functionBody.append(")\n"); | |
} | |
return Collections.singleton(functionBody.toString()); | |
} | |
@Override | |
public String extractUserFriendlyErrorMessage(ScriptException e) { | |
return e.getMessage(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment