001
014
015 package com.liferay.portal.scripting.python;
016
017 import com.liferay.portal.kernel.cache.SingleVMPoolUtil;
018 import com.liferay.portal.kernel.scripting.ExecutionException;
019 import com.liferay.portal.kernel.scripting.ScriptingException;
020 import com.liferay.portal.kernel.scripting.ScriptingExecutor;
021
022 import java.util.HashMap;
023 import java.util.Map;
024 import java.util.Set;
025
026 import org.python.core.CompileMode;
027 import org.python.core.Py;
028 import org.python.core.PyCode;
029 import org.python.core.PySystemState;
030 import org.python.util.InteractiveInterpreter;
031
032
035 public class PythonExecutor implements ScriptingExecutor {
036
037 public static final String CACHE_NAME = PythonExecutor.class.getName();
038
039 public static final String LANGUAGE = "python";
040
041 public void clearCache() {
042 SingleVMPoolUtil.clear(CACHE_NAME);
043 }
044
045 public String getLanguage() {
046 return LANGUAGE;
047 }
048
049 public Map<String, Object> eval(
050 Set<String> allowedClasses, Map<String, Object> inputObjects,
051 Set<String> outputNames, String script)
052 throws ScriptingException {
053
054 if (allowedClasses != null) {
055 throw new ExecutionException(
056 "Constrained execution not supported for Python");
057 }
058
059 PyCode compiledScript = getCompiledScript(script);
060
061 InteractiveInterpreter interactiveInterpreter =
062 new InteractiveInterpreter();
063
064 for (Map.Entry<String, Object> entry : inputObjects.entrySet()) {
065 String key = entry.getKey();
066 Object value = entry.getValue();
067
068 interactiveInterpreter.set(key, value);
069 }
070
071 interactiveInterpreter.exec(compiledScript);
072
073 if (outputNames == null) {
074 return null;
075 }
076
077 Map<String, Object> outputObjects = new HashMap<String, Object>();
078
079 for (String outputName : outputNames) {
080 outputObjects.put(
081 outputName, interactiveInterpreter.get(outputName));
082 }
083
084 return outputObjects;
085 }
086
087 protected PyCode getCompiledScript(String script) {
088 if (!_initialized) {
089 synchronized (this) {
090 PySystemState.initialize();
091
092 _initialized = true;
093 }
094 }
095
096 String key = String.valueOf(script.hashCode());
097
098 PyCode compiledScript = (PyCode)SingleVMPoolUtil.get(CACHE_NAME, key);
099
100 if (compiledScript == null) {
101 compiledScript = Py.compile_flags(
102 script, "<string>", CompileMode.exec, Py.getCompilerFlags());
103
104 SingleVMPoolUtil.put(CACHE_NAME, key, compiledScript);
105 }
106
107 return compiledScript;
108 }
109
110 private boolean _initialized;
111
112 }