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