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