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.BaseScriptingExecutor;
019 import com.liferay.portal.kernel.scripting.ExecutionException;
020 import com.liferay.portal.kernel.scripting.ScriptingException;
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 extends BaseScriptingExecutor {
036
037 @Override
038 public void clearCache() {
039 SingleVMPoolUtil.clear(_CACHE_NAME);
040 }
041
042 @Override
043 public Map<String, Object> eval(
044 Set<String> allowedClasses, Map<String, Object> inputObjects,
045 Set<String> outputNames, String script, ClassLoader... classLoaders)
046 throws ScriptingException {
047
048 if (allowedClasses != null) {
049 throw new ExecutionException(
050 "Constrained execution not supported for Python");
051 }
052
053 PyCode compiledScript = getCompiledScript(script);
054
055 InteractiveInterpreter interactiveInterpreter =
056 new InteractiveInterpreter();
057
058 for (Map.Entry<String, Object> entry : inputObjects.entrySet()) {
059 String key = entry.getKey();
060 Object value = entry.getValue();
061
062 interactiveInterpreter.set(key, value);
063 }
064
065 interactiveInterpreter.exec(compiledScript);
066
067 if (outputNames == null) {
068 return null;
069 }
070
071 Map<String, Object> outputObjects = new HashMap<String, Object>();
072
073 for (String outputName : outputNames) {
074 outputObjects.put(
075 outputName, interactiveInterpreter.get(outputName));
076 }
077
078 return outputObjects;
079 }
080
081 @Override
082 public String getLanguage() {
083 return _LANGUAGE;
084 }
085
086 protected PyCode getCompiledScript(String script) {
087 if (!_initialized) {
088 synchronized (this) {
089 if (!_initialized) {
090 PySystemState.initialize();
091
092 _initialized = true;
093 }
094 }
095 }
096
097 String key = String.valueOf(script.hashCode());
098
099 PyCode compiledScript = (PyCode)SingleVMPoolUtil.get(_CACHE_NAME, key);
100
101 if (compiledScript == null) {
102 compiledScript = Py.compile_flags(
103 script, "<string>", CompileMode.exec, Py.getCompilerFlags());
104
105 SingleVMPoolUtil.put(_CACHE_NAME, key, compiledScript);
106 }
107
108 return compiledScript;
109 }
110
111 private static final String _CACHE_NAME = PythonExecutor.class.getName();
112
113 private static final String _LANGUAGE = "python";
114
115 private volatile boolean _initialized;
116
117 }