001    /*******************************************************************************
002     * Portions created by Sebastian Thomschke are copyright (c) 2005-2013 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 java.util.Map;
016    
017    import net.sf.oval.exception.ExpressionEvaluationException;
018    import net.sf.oval.internal.Log;
019    import net.sf.oval.internal.util.ObjectCache;
020    
021    import org.apache.commons.jexl2.Expression;
022    import org.apache.commons.jexl2.JexlEngine;
023    import org.apache.commons.jexl2.MapContext;
024    
025    /**
026     * @author Sebastian Thomschke
027     */
028    public class ExpressionLanguageJEXLImpl implements ExpressionLanguage
029    {
030            private static final Log LOG = Log.getLog(ExpressionLanguageJEXLImpl.class);
031    
032            private static final JexlEngine jexl = new JexlEngine();
033    
034            private final ObjectCache<String, Expression> expressionCache = new ObjectCache<String, Expression>();
035    
036            /**
037             * {@inheritDoc}
038             */
039            @SuppressWarnings("unchecked")
040            public Object evaluate(final String expression, final Map<String, ? > values) throws ExpressionEvaluationException
041            {
042                    LOG.debug("Evaluating JEXL expression: {1}", expression);
043                    try
044                    {
045                            Expression expr = expressionCache.get(expression);
046                            if (expr == null)
047                            {
048                                    expr = jexl.createExpression(expression);
049                                    expressionCache.put(expression, expr);
050                            }
051                            return expr.evaluate(new MapContext((Map<String, Object>) values));
052                    }
053                    catch (final Exception ex)
054                    {
055                            throw new ExpressionEvaluationException("Evaluating JEXL expression failed: " + expression, ex);
056                    }
057            }
058    
059            /**
060             * {@inheritDoc}
061             */
062            public boolean evaluateAsBoolean(final String expression, final Map<String, ? > values) throws ExpressionEvaluationException
063            {
064                    final Object result = evaluate(expression, values);
065                    if (!(result instanceof Boolean)) throw new ExpressionEvaluationException("The script must return a boolean value.");
066                    return (Boolean) result;
067            }
068    }