001
014
015 package com.liferay.portal.scripting.groovy;
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 import com.liferay.portal.kernel.util.AggregateClassLoader;
022 import com.liferay.portal.security.pacl.PACLClassLoaderUtil;
023
024 import groovy.lang.Binding;
025 import groovy.lang.GroovyShell;
026 import groovy.lang.Script;
027
028 import java.util.HashMap;
029 import java.util.Map;
030 import java.util.Set;
031 import java.util.WeakHashMap;
032
033
037 public class GroovyExecutor extends BaseScriptingExecutor {
038
039 @Override
040 public void clearCache() {
041 SingleVMPoolUtil.clear(_CACHE_NAME);
042 }
043
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 Groovy");
052 }
053
054 Script compiledScript = getCompiledScript(script, classLoaders);
055
056 Binding binding = new Binding(inputObjects);
057
058 compiledScript.setBinding(binding);
059
060 compiledScript.run();
061
062 if (outputNames == null) {
063 return null;
064 }
065
066 Map<String, Object> outputObjects = new HashMap<String, Object>();
067
068 for (String outputName : outputNames) {
069 outputObjects.put(outputName, binding.getVariable(outputName));
070 }
071
072 return outputObjects;
073 }
074
075 public String getLanguage() {
076 return _LANGUAGE;
077 }
078
079 protected Script getCompiledScript(
080 String script, ClassLoader[] classLoaders) {
081
082 GroovyShell groovyShell = getGroovyShell(classLoaders);
083
084 String key = String.valueOf(script.hashCode());
085
086 Script compiledScript = (Script)SingleVMPoolUtil.get(_CACHE_NAME, key);
087
088 if (compiledScript == null) {
089 compiledScript = groovyShell.parse(script);
090
091 SingleVMPoolUtil.put(_CACHE_NAME, key, compiledScript);
092 }
093
094 return compiledScript;
095 }
096
097 protected GroovyShell getGroovyShell(ClassLoader[] classLoaders) {
098 if ((classLoaders == null) || (classLoaders.length == 0)) {
099 if (_groovyShell == null) {
100 synchronized (this) {
101 if (_groovyShell == null) {
102 _groovyShell = new GroovyShell();
103 }
104 }
105 }
106
107 return _groovyShell;
108 }
109
110 ClassLoader aggregateClassLoader =
111 AggregateClassLoader.getAggregateClassLoader(
112 PACLClassLoaderUtil.getPortalClassLoader(), classLoaders);
113
114 GroovyShell groovyShell = null;
115
116 if (!_groovyShells.containsKey(aggregateClassLoader)) {
117 synchronized (this) {
118 if (!_groovyShells.containsKey(aggregateClassLoader)) {
119 groovyShell = new GroovyShell(aggregateClassLoader);
120
121 _groovyShells.put(aggregateClassLoader, groovyShell);
122 }
123 }
124 }
125
126 return groovyShell;
127 }
128
129 private static final String _CACHE_NAME = GroovyExecutor.class.getName();
130
131 private static final String _LANGUAGE = "groovy";
132
133 private volatile GroovyShell _groovyShell = new GroovyShell();
134 private volatile Map<ClassLoader, GroovyShell> _groovyShells =
135 new WeakHashMap<ClassLoader, GroovyShell>();
136
137 }