Package org.apache.commons.scxml.env.jexl

Source Code of org.apache.commons.scxml.env.jexl.JexlEvaluator

/*
*
*   Copyright 2006 The Apache Software Foundation.
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*
*/
package org.apache.commons.scxml.env.jexl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import org.apache.commons.jexl.Expression;
import org.apache.commons.jexl.ExpressionFactory;
import org.apache.commons.scxml.Context;
import org.apache.commons.scxml.Evaluator;
import org.apache.commons.scxml.SCXMLExpressionException;
import org.w3c.dom.Node;

/**
* Evaluator implementation enabling use of JEXL expressions in
* SCXML documents.
*
*/
public class JexlEvaluator implements Evaluator {

    /** Error message if evaluation context is not a JexlContext. */
    private static final String ERR_CTX_TYPE = "Error evaluating JEXL "
        + "expression, Context must be a org.apache.commons.jexl.JexlContext";

    /** Pattern for recognizing the SCXML In() special predicate. */
    private static Pattern inFct = Pattern.compile("In\\(");
    /** Pattern for recognizing the Commons SCXML Data() builtin function. */
    private static Pattern dataFct = Pattern.compile("Data\\(");

    /** Constructor. */
    public JexlEvaluator() {
        super();
    }

    /**
     * Evaluate an expression.
     *
     * @param ctx variable context
     * @param expr expression
     * @return a result of the evaluation
     * @throws SCXMLExpressionException For a malformed expression
     * @see Evaluator#eval(Context, String)
     */
    public Object eval(final Context ctx, final String expr)
    throws SCXMLExpressionException {
        if (expr == null) {
            return null;
        }
        JexlContext jexlCtx = null;
        if (ctx instanceof JexlContext) {
            jexlCtx = (JexlContext) ctx;
        } else {
            throw new SCXMLExpressionException(ERR_CTX_TYPE);
        }
        Expression exp = null;
        try {
            String evalExpr = inFct.matcher(expr).
                replaceAll("_builtin.isMember(_ALL_STATES, ");
            evalExpr = dataFct.matcher(evalExpr).
                replaceAll("_builtin.data(");
            exp = ExpressionFactory.createExpression(evalExpr);
            return exp.evaluate(getEffectiveContext(jexlCtx));
        } catch (Exception e) {
            throw new SCXMLExpressionException(e);
        }
    }

    /**
     * @see Evaluator#evalCond(Context, String)
     */
    public Boolean evalCond(final Context ctx, final String expr)
    throws SCXMLExpressionException {
        if (expr == null) {
            return null;
        }
        JexlContext jexlCtx = null;
        if (ctx instanceof JexlContext) {
            jexlCtx = (JexlContext) ctx;
        } else {
            throw new SCXMLExpressionException(ERR_CTX_TYPE);
        }
        Expression exp = null;
        try {
            String evalExpr = inFct.matcher(expr).
                replaceAll("_builtin.isMember(_ALL_STATES, ");
            evalExpr = dataFct.matcher(evalExpr).
                replaceAll("_builtin.data(");
            exp = ExpressionFactory.createExpression(evalExpr);
            return (Boolean) exp.evaluate(getEffectiveContext(jexlCtx));
        } catch (Exception e) {
            throw new SCXMLExpressionException(e);
        }
    }

    /**
     * @see Evaluator#evalLocation(Context, String)
     */
    public Node evalLocation(final Context ctx, final String expr)
    throws SCXMLExpressionException {
        if (expr == null) {
            return null;
        }
        JexlContext jexlCtx = null;
        if (ctx instanceof JexlContext) {
            jexlCtx = (JexlContext) ctx;
        } else {
            throw new SCXMLExpressionException(ERR_CTX_TYPE);
        }
        Expression exp = null;
        try {
            String evalExpr = inFct.matcher(expr).
                replaceAll("_builtin.isMember(_ALL_STATES, ");
            evalExpr = dataFct.matcher(evalExpr).
                replaceFirst("_builtin.dataNode(");
            evalExpr = dataFct.matcher(evalExpr).
                replaceAll("_builtin.data(");
            exp = ExpressionFactory.createExpression(evalExpr);
            return (Node) exp.evaluate(getEffectiveContext(jexlCtx));
        } catch (Exception e) {
            throw new SCXMLExpressionException(e);
        }
    }

    /**
     * Create a new child context.
     *
     * @param parent parent context
     * @return new child context
     * @see Evaluator#newContext(Context)
     */
    public Context newContext(final Context parent) {
        return new JexlContext(parent);
    }

    /**
     * Create a new context which is the summation of contexts from the
     * current state to document root, child has priority over parent
     * in scoping rules.
     *
     * @param nodeCtx The JexlContext for this state.
     * @return The effective JexlContext for the path leading up to
     *         document root.
     */
    private JexlContext getEffectiveContext(final JexlContext nodeCtx) {
        List contexts = new ArrayList();
        // trace path to root
        JexlContext currentCtx = nodeCtx;
        while (currentCtx != null) {
            contexts.add(currentCtx);
            currentCtx = (JexlContext) currentCtx.getParent();
        }
        Map vars = new HashMap();
        // summation of the contexts, parent first, child wins
        for (int i = contexts.size() - 1; i > -1; i--) {
            vars.putAll(((JexlContext) contexts.get(i)).getVars());
        }
        return new JexlContext(vars);
    }

}

TOP

Related Classes of org.apache.commons.scxml.env.jexl.JexlEvaluator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.