1
2
3
4
5
6
7
8
9
10
11
12
13 package net.sf.oval.expression;
14
15 import java.util.ArrayList;
16 import java.util.Map;
17 import java.util.Map.Entry;
18
19 import net.sf.oval.exception.ExpressionEvaluationException;
20 import net.sf.oval.internal.Log;
21
22 import org.jruby.CompatVersion;
23 import org.jruby.Ruby;
24 import org.jruby.RubyInstanceConfig;
25 import org.jruby.javasupport.JavaEmbedUtils;
26 import org.jruby.runtime.builtin.IRubyObject;
27
28
29
30
31
32 public class ExpressionLanguageJRubyImpl implements ExpressionLanguage
33 {
34 private static final Log LOG = Log.getLog(ExpressionLanguageJRubyImpl.class);
35
36
37
38
39 public Object evaluate(final String expression, final Map<String, ? > values) throws ExpressionEvaluationException
40 {
41 LOG.debug("Evaluating JRuby expression: {1}", expression);
42 try
43 {
44 final RubyInstanceConfig config = new RubyInstanceConfig();
45 config.setCompatVersion(CompatVersion.RUBY1_9);
46 final Ruby runtime = JavaEmbedUtils.initialize(new ArrayList<String>(), config);
47
48 final StringBuilder localVars = new StringBuilder();
49 for (final Entry<String, ? > entry : values.entrySet())
50 {
51 runtime.getGlobalVariables().set("$" + entry.getKey(), JavaEmbedUtils.javaToRuby(runtime, entry.getValue()));
52 localVars.append(entry.getKey())
53 .append("=$")
54 .append(entry.getKey())
55 .append("\n");
56 }
57 final IRubyObject result = runtime.evalScriptlet(localVars + expression);
58 return JavaEmbedUtils.rubyToJava(runtime, result, Object.class);
59 }
60 catch (final RuntimeException ex)
61 {
62 throw new ExpressionEvaluationException("Evaluating JRuby expression failed: " + expression, ex);
63 }
64 }
65
66
67
68
69 public boolean evaluateAsBoolean(final String expression, final Map<String, ? > values) throws ExpressionEvaluationException
70 {
71 final Object result = evaluate(expression, values);
72 if (!(result instanceof Boolean)) throw new ExpressionEvaluationException("The script must return a boolean value.");
73 return (Boolean) result;
74 }
75 }