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