001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.scripting.groovy;
016    
017    import com.liferay.portal.kernel.cache.SingleVMPoolUtil;
018    import com.liferay.portal.kernel.scripting.ExecutionException;
019    import com.liferay.portal.kernel.scripting.ScriptingException;
020    import com.liferay.portal.kernel.scripting.ScriptingExecutor;
021    
022    import groovy.lang.Binding;
023    import groovy.lang.GroovyShell;
024    import groovy.lang.Script;
025    
026    import java.util.HashMap;
027    import java.util.Map;
028    import java.util.Set;
029    
030    /**
031     * @author Alberto Montero
032     * @author Brian Wing Shun Chan
033     */
034    public class GroovyExecutor implements ScriptingExecutor {
035    
036            public static final String CACHE_NAME = GroovyExecutor.class.getName();
037    
038            public static final String LANGUAGE = "groovy";
039    
040            public void clearCache() {
041                    SingleVMPoolUtil.clear(CACHE_NAME);
042            }
043    
044            public String getLanguage() {
045                    return LANGUAGE;
046            }
047    
048            public Map<String, Object> eval(
049                            Set<String> allowedClasses, Map<String, Object> inputObjects,
050                            Set<String> outputNames, String script)
051                    throws ScriptingException {
052    
053                    if (allowedClasses != null) {
054                            throw new ExecutionException(
055                                    "Constrained execution not supported for Groovy");
056                    }
057    
058                    Script compiledScript = getCompiledScript(script);
059    
060                    Binding binding = new Binding(inputObjects);
061    
062                    compiledScript.setBinding(binding);
063    
064                    compiledScript.run();
065    
066                    if (outputNames == null) {
067                            return null;
068                    }
069    
070                    Map<String, Object> outputObjects = new HashMap<String, Object>();
071    
072                    for (String outputName : outputNames) {
073                            outputObjects.put(outputName, binding.getVariable(outputName));
074                    }
075    
076                    return outputObjects;
077            }
078    
079            protected Script getCompiledScript(String script) {
080                    if (_groovyShell == null) {
081                            synchronized (this) {
082                                    _groovyShell = new GroovyShell();
083                            }
084                    }
085    
086                    String key = String.valueOf(script.hashCode());
087    
088                    Script compiledScript = (Script)SingleVMPoolUtil.get(CACHE_NAME, key);
089    
090                    if (compiledScript == null) {
091                            compiledScript = _groovyShell.parse(script);
092    
093                            SingleVMPoolUtil.put(CACHE_NAME, key, compiledScript);
094                    }
095    
096                    return compiledScript;
097            }
098    
099            private GroovyShell _groovyShell;
100    
101    }