001/* 002 * Copyright 2002-2016 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.scripting.groovy; 018 019import java.io.IOException; 020import java.util.Map; 021 022import groovy.lang.Binding; 023import groovy.lang.GroovyRuntimeException; 024import groovy.lang.GroovyShell; 025import org.codehaus.groovy.control.CompilerConfiguration; 026import org.codehaus.groovy.control.customizers.CompilationCustomizer; 027 028import org.springframework.beans.factory.BeanClassLoaderAware; 029import org.springframework.scripting.ScriptCompilationException; 030import org.springframework.scripting.ScriptEvaluator; 031import org.springframework.scripting.ScriptSource; 032import org.springframework.scripting.support.ResourceScriptSource; 033 034/** 035 * Groovy-based implementation of Spring's {@link ScriptEvaluator} strategy interface. 036 * 037 * @author Juergen Hoeller 038 * @since 4.0 039 * @see GroovyShell#evaluate(String, String) 040 */ 041public class GroovyScriptEvaluator implements ScriptEvaluator, BeanClassLoaderAware { 042 043 private ClassLoader classLoader; 044 045 private CompilerConfiguration compilerConfiguration = new CompilerConfiguration(); 046 047 048 /** 049 * Construct a new GroovyScriptEvaluator. 050 */ 051 public GroovyScriptEvaluator() { 052 } 053 054 /** 055 * Construct a new GroovyScriptEvaluator. 056 * @param classLoader the ClassLoader to use as a parent for the {@link GroovyShell} 057 */ 058 public GroovyScriptEvaluator(ClassLoader classLoader) { 059 this.classLoader = classLoader; 060 } 061 062 063 /** 064 * Set a custom compiler configuration for this evaluator. 065 * @since 4.3.3 066 * @see #setCompilationCustomizers 067 */ 068 public void setCompilerConfiguration(CompilerConfiguration compilerConfiguration) { 069 this.compilerConfiguration = 070 (compilerConfiguration != null ? compilerConfiguration : new CompilerConfiguration()); 071 } 072 073 /** 074 * Return this evaluator's compiler configuration (never {@code null}). 075 * @since 4.3.3 076 * @see #setCompilerConfiguration 077 */ 078 public CompilerConfiguration getCompilerConfiguration() { 079 return this.compilerConfiguration; 080 } 081 082 /** 083 * Set one or more customizers to be applied to this evaluator's compiler configuration. 084 * <p>Note that this modifies the shared compiler configuration held by this evaluator. 085 * @since 4.3.3 086 * @see #setCompilerConfiguration 087 */ 088 public void setCompilationCustomizers(CompilationCustomizer... compilationCustomizers) { 089 this.compilerConfiguration.addCompilationCustomizers(compilationCustomizers); 090 } 091 092 @Override 093 public void setBeanClassLoader(ClassLoader classLoader) { 094 this.classLoader = classLoader; 095 } 096 097 098 @Override 099 public Object evaluate(ScriptSource script) { 100 return evaluate(script, null); 101 } 102 103 @Override 104 public Object evaluate(ScriptSource script, Map<String, Object> arguments) { 105 GroovyShell groovyShell = new GroovyShell( 106 this.classLoader, new Binding(arguments), this.compilerConfiguration); 107 try { 108 String filename = (script instanceof ResourceScriptSource ? 109 ((ResourceScriptSource) script).getResource().getFilename() : null); 110 if (filename != null) { 111 return groovyShell.evaluate(script.getScriptAsString(), filename); 112 } 113 else { 114 return groovyShell.evaluate(script.getScriptAsString()); 115 } 116 } 117 catch (IOException ex) { 118 throw new ScriptCompilationException(script, "Cannot access Groovy script", ex); 119 } 120 catch (GroovyRuntimeException ex) { 121 throw new ScriptCompilationException(script, ex); 122 } 123 } 124 125}