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