001 /******************************************************************************* 002 * Portions created by Sebastian Thomschke are copyright (c) 2005-2012 Sebastian 003 * Thomschke. 004 * 005 * All Rights Reserved. This program and the accompanying materials 006 * are made available under the terms of the Eclipse Public License v1.0 007 * which accompanies this distribution, and is available at 008 * http://www.eclipse.org/legal/epl-v10.html 009 * 010 * Contributors: 011 * Sebastian Thomschke - initial implementation. 012 *******************************************************************************/ 013 package net.sf.oval.expression; 014 015 import groovy.lang.Binding; 016 import groovy.lang.GroovyShell; 017 import groovy.lang.Script; 018 019 import java.util.Map; 020 import java.util.Map.Entry; 021 022 import net.sf.oval.exception.ExpressionEvaluationException; 023 import net.sf.oval.internal.Log; 024 import net.sf.oval.internal.util.ObjectCache; 025 import net.sf.oval.internal.util.ThreadLocalObjectCache; 026 027 /** 028 * @author Sebastian Thomschke 029 */ 030 public class ExpressionLanguageGroovyImpl implements ExpressionLanguage 031 { 032 private static final Log LOG = Log.getLog(ExpressionLanguageGroovyImpl.class); 033 034 private static final GroovyShell GROOVY_SHELL = new GroovyShell(); 035 036 private final ThreadLocalObjectCache<String, Script> threadScriptCache = new ThreadLocalObjectCache<String, Script>(); 037 038 /** 039 * {@inheritDoc} 040 */ 041 public Object evaluate(final String expression, final Map<String, ? > values) throws ExpressionEvaluationException 042 { 043 LOG.debug("Evaluating Groovy expression: {1}", expression); 044 try 045 { 046 final ObjectCache<String, Script> scriptCache = threadScriptCache.get(); 047 Script script = scriptCache.get(expression); 048 if (script == null) 049 { 050 script = GROOVY_SHELL.parse(expression); 051 scriptCache.put(expression, script); 052 } 053 054 final Binding binding = new Binding(); 055 for (final Entry<String, ? > entry : values.entrySet()) 056 binding.setVariable(entry.getKey(), entry.getValue()); 057 script.setBinding(binding); 058 return script.run(); 059 } 060 catch (final Exception ex) 061 { 062 throw new ExpressionEvaluationException("Evaluating script with Groovy failed.", ex); 063 } 064 } 065 066 /** 067 * {@inheritDoc} 068 */ 069 public boolean evaluateAsBoolean(final String expression, final Map<String, ? > values) 070 throws ExpressionEvaluationException 071 { 072 final Object result = evaluate(expression, values); 073 if (!(result instanceof Boolean)) 074 throw new ExpressionEvaluationException("The script must return a boolean value."); 075 return (Boolean) result; 076 } 077 }