1
2
3
4
5
6
7
8
9
10
11
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
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
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
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 }