View Javadoc

1   /*******************************************************************************
2    * Portions created by Sebastian Thomschke are copyright (c) 2005-2012 Sebastian
3    * Thomschke.
4    * 
5    * All Rights Reserved. This program and the accompanying materials
6    * are made available under the terms of the Eclipse Public License v1.0
7    * which accompanies this distribution, and is available at
8    * http://www.eclipse.org/legal/epl-v10.html
9    * 
10   * Contributors:
11   *     Sebastian Thomschke - initial implementation.
12   *******************************************************************************/
13  package net.sf.oval.expression;
14  
15  import groovy.lang.Binding;
16  import groovy.lang.GroovyShell;
17  import groovy.lang.Script;
18  
19  import java.util.Map;
20  import java.util.Map.Entry;
21  
22  import net.sf.oval.exception.ExpressionEvaluationException;
23  import net.sf.oval.internal.Log;
24  import net.sf.oval.internal.util.ObjectCache;
25  import net.sf.oval.internal.util.ThreadLocalObjectCache;
26  
27  /**
28   * @author Sebastian Thomschke
29   */
30  public class ExpressionLanguageGroovyImpl implements ExpressionLanguage
31  {
32  	private static final Log LOG = Log.getLog(ExpressionLanguageGroovyImpl.class);
33  
34  	private static final GroovyShell GROOVY_SHELL = new GroovyShell();
35  
36  	private final ThreadLocalObjectCache<String, Script> threadScriptCache = new ThreadLocalObjectCache<String, Script>();
37  
38  	/**
39  	 * {@inheritDoc}
40  	 */
41  	public Object evaluate(final String expression, final Map<String, ? > values) throws ExpressionEvaluationException
42  	{
43  		LOG.debug("Evaluating Groovy expression: {1}", expression);
44  		try
45  		{
46  			final ObjectCache<String, Script> scriptCache = threadScriptCache.get();
47  			Script script = scriptCache.get(expression);
48  			if (script == null)
49  			{
50  				script = GROOVY_SHELL.parse(expression);
51  				scriptCache.put(expression, script);
52  			}
53  
54  			final Binding binding = new Binding();
55  			for (final Entry<String, ? > entry : values.entrySet())
56  				binding.setVariable(entry.getKey(), entry.getValue());
57  			script.setBinding(binding);
58  			return script.run();
59  		}
60  		catch (final Exception ex)
61  		{
62  			throw new ExpressionEvaluationException("Evaluating script with Groovy failed.", ex);
63  		}
64  	}
65  
66  	/**
67  	 * {@inheritDoc}
68  	 */
69  	public boolean evaluateAsBoolean(final String expression, final Map<String, ? > values)
70  			throws ExpressionEvaluationException
71  	{
72  		final Object result = evaluate(expression, values);
73  		if (!(result instanceof Boolean))
74  			throw new ExpressionEvaluationException("The script must return a boolean value.");
75  		return (Boolean) result;
76  	}
77  }