View Javadoc

1   /*******************************************************************************
2    * Portions created by Sebastian Thomschke are copyright (c) 2005-2013 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 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   * @author Sebastian Thomschke
30   *
31   */
32  public class ExpressionLanguageJRubyImpl implements ExpressionLanguage
33  {
34  	private static final Log LOG = Log.getLog(ExpressionLanguageJRubyImpl.class);
35  
36  	/**
37  	 * {@inheritDoc}
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  	 * {@inheritDoc}
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  }