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