001
014
015 package com.liferay.portal.scripting.groovy;
016
017 import com.liferay.portal.kernel.concurrent.ConcurrentReferenceKeyHashMap;
018 import com.liferay.portal.kernel.memory.FinalizeManager;
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.concurrent.ConcurrentMap;
034
035
039 public class GroovyExecutor extends BaseScriptingExecutor {
040
041 @Override
042 public Map<String, Object> eval(
043 Set<String> allowedClasses, Map<String, Object> inputObjects,
044 Set<String> outputNames, String script, ClassLoader... classLoaders)
045 throws ScriptingException {
046
047 if (allowedClasses != null) {
048 throw new ExecutionException(
049 "Constrained execution not supported for Groovy");
050 }
051
052 GroovyShell groovyShell = getGroovyShell(classLoaders);
053
054 Script compiledScript = groovyShell.parse(script);
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 @Override
076 public String getLanguage() {
077 return _LANGUAGE;
078 }
079
080 protected GroovyShell getGroovyShell(ClassLoader[] classLoaders) {
081 if (ArrayUtil.isEmpty(classLoaders)) {
082 if (_groovyShell == null) {
083 synchronized (this) {
084 if (_groovyShell == null) {
085 _groovyShell = new GroovyShell();
086 }
087 }
088 }
089
090 return _groovyShell;
091 }
092
093 ClassLoader aggregateClassLoader =
094 AggregateClassLoader.getAggregateClassLoader(
095 ClassLoaderUtil.getPortalClassLoader(), classLoaders);
096
097 GroovyShell groovyShell = _groovyShells.get(aggregateClassLoader);
098
099 if (groovyShell == null) {
100 groovyShell = new GroovyShell(aggregateClassLoader);
101
102 GroovyShell oldGroovyShell = _groovyShells.putIfAbsent(
103 aggregateClassLoader, groovyShell);
104
105 if (oldGroovyShell != null) {
106 groovyShell = oldGroovyShell;
107 }
108 }
109
110 return groovyShell;
111 }
112
113 private static final String _LANGUAGE = "groovy";
114
115 private volatile GroovyShell _groovyShell = new GroovyShell();
116 private final ConcurrentMap<ClassLoader, GroovyShell> _groovyShells =
117 new ConcurrentReferenceKeyHashMap<ClassLoader, GroovyShell>(
118 FinalizeManager.WEAK_REFERENCE_FACTORY);
119
120 }