001
014
015 package com.liferay.portal.scripting.groovy;
016
017 import com.liferay.portal.kernel.scripting.BaseScriptingExecutor;
018 import com.liferay.portal.kernel.scripting.ExecutionException;
019 import com.liferay.portal.kernel.scripting.ScriptingException;
020 import com.liferay.portal.kernel.util.AggregateClassLoader;
021 import com.liferay.portal.kernel.util.ArrayUtil;
022 import com.liferay.portal.util.ClassLoaderUtil;
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 Map<String, Object> eval(
041 Set<String> allowedClasses, Map<String, Object> inputObjects,
042 Set<String> outputNames, String script, ClassLoader... classLoaders)
043 throws ScriptingException {
044
045 if (allowedClasses != null) {
046 throw new ExecutionException(
047 "Constrained execution not supported for Groovy");
048 }
049
050 GroovyShell groovyShell = getGroovyShell(classLoaders);
051
052 Script compiledScript = groovyShell.parse(script);
053
054 Binding binding = new Binding(inputObjects);
055
056 compiledScript.setBinding(binding);
057
058 compiledScript.run();
059
060 if (outputNames == null) {
061 return null;
062 }
063
064 Map<String, Object> outputObjects = new HashMap<String, Object>();
065
066 for (String outputName : outputNames) {
067 outputObjects.put(outputName, binding.getVariable(outputName));
068 }
069
070 return outputObjects;
071 }
072
073 @Override
074 public String getLanguage() {
075 return _LANGUAGE;
076 }
077
078 protected GroovyShell getGroovyShell(ClassLoader[] classLoaders) {
079 if (ArrayUtil.isEmpty(classLoaders)) {
080 if (_groovyShell == null) {
081 synchronized (this) {
082 if (_groovyShell == null) {
083 _groovyShell = new GroovyShell();
084 }
085 }
086 }
087
088 return _groovyShell;
089 }
090
091 ClassLoader aggregateClassLoader =
092 AggregateClassLoader.getAggregateClassLoader(
093 ClassLoaderUtil.getPortalClassLoader(), classLoaders);
094
095 GroovyShell groovyShell = null;
096
097 if (!_groovyShells.containsKey(aggregateClassLoader)) {
098 synchronized (this) {
099 if (!_groovyShells.containsKey(aggregateClassLoader)) {
100 groovyShell = new GroovyShell(aggregateClassLoader);
101
102 _groovyShells.put(aggregateClassLoader, groovyShell);
103 }
104 }
105 }
106
107 return groovyShell;
108 }
109
110 private static final String _LANGUAGE = "groovy";
111
112 private volatile GroovyShell _groovyShell = new GroovyShell();
113 private volatile Map<ClassLoader, GroovyShell> _groovyShells =
114 new WeakHashMap<ClassLoader, GroovyShell>();
115
116 }