📄 expressionevaluatorimpl.java
字号:
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.jbpm.jpdl.el.impl;
import java.io.Reader;
import java.io.StringReader;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.jbpm.jpdl.el.ELException;
import org.jbpm.jpdl.el.ExpressionEvaluator;
import org.jbpm.jpdl.el.FunctionMapper;
import org.jbpm.jpdl.el.VariableResolver;
import org.jbpm.jpdl.el.parser.ELParser;
import org.jbpm.jpdl.el.parser.ParseException;
import org.jbpm.jpdl.el.parser.ELToken;
import org.jbpm.jpdl.el.parser.ELTokenMgrError;
/**
*
* <p>This is the main class for evaluating expression Strings. An
* expression String is a String that may contain expressions of the
* form ${...}. Multiple expressions may appear in the same
* expression String. In such a case, the expression String's value
* is computed by concatenating the String values of those evaluated
* expressions and any intervening non-expression text, then
* converting the resulting String to the expected type using the
* PropertyEditor mechanism.
*
* <p>In the special case where the expression String is a single
* expression, the value of the expression String is determined by
* evaluating the expression, without any intervening conversion to a
* String.
*
* <p>The evaluator maintains a cache mapping expression Strings to
* their parsed results. For expression Strings containing no
* expression elements, it maintains a cache mapping
* ExpectedType/ExpressionString to parsed value, so that static
* expression Strings won't have to go through a conversion step every
* time they are used. All instances of the evaluator share the same
* cache. The cache may be bypassed by setting a flag on the
* evaluator's constructor.
*
* <p>The evaluator must be passed a VariableResolver in its
* constructor. The VariableResolver is used to resolve variable
* names encountered in expressions, and can also be used to implement
* "implicit objects" that are always present in the namespace.
* Different applications will have different policies for variable
* lookups and implicit objects - these differences can be
* encapsulated in the VariableResolver passed to the evaluator's
* constructor.
*
* <p>Most VariableResolvers will need to perform their resolution
* against some context. For example, a JSP environment needs a
* PageContext to resolve variables. The evaluate() method takes a
* generic Object context which is eventually passed to the
* VariableResolver - the VariableResolver is responsible for casting
* the context to the proper type.
*
* <p>Once an evaluator instance has been constructed, it may be used
* multiple times, and may be used by multiple simultaneous Threads.
* In other words, an evaluator instance is well-suited for use as a
* singleton.
*
* @author Nathan Abramson - Art Technology Group
* @author Shawn Bayern
* @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: tombaeyens $
**/
public class ExpressionEvaluatorImpl
extends ExpressionEvaluator
{
//-------------------------------------
// Properties
//-------------------------------------
//-------------------------------------
// Member variables
//-------------------------------------
/** The mapping from expression String to its parsed form (String,
Expression, or ExpressionString) **/
static Map sCachedExpressionStrings =
Collections.synchronizedMap (new HashMap ());
/** The mapping from ExpectedType to Maps mapping literal String to
parsed value **/
static Map sCachedExpectedTypes = new HashMap ();
/** The static Logger **/
static Logger sLogger = new Logger (System.out);
/** Flag if the cache should be bypassed **/
boolean mBypassCache;
//-------------------------------------
/**
*
* Constructor
**/
public ExpressionEvaluatorImpl () { }
/**
*
* Constructor
*
* @param pBypassCache flag indicating if the cache should be
* bypassed
**/
public ExpressionEvaluatorImpl (boolean pBypassCache)
{
mBypassCache = pBypassCache;
}
//-------------------------------------
/**
*
* Evaluates the given expression String
*
* @param pExpressionString The expression to be evaluated.
* @param pExpectedType The expected type of the result of the evaluation
* @param pResolver A VariableResolver instance that can be used at
* runtime to resolve the name of implicit objects into Objects.
* @param functions A FunctionMapper to resolve functions found in
* the expression. It can be null, in which case no functions
* are supported for this invocation.
* @return the expression String evaluated to the given expected
* type
**/
public Object evaluate (String pExpressionString,
Class pExpectedType,
VariableResolver pResolver,
FunctionMapper functions)
throws ELException
{
return evaluate (pExpressionString,
pExpectedType,
pResolver,
functions,
sLogger);
}
/**
*
* Prepare an expression for later evaluation. This method should perform
* syntactic validation of the expression; if in doing so it detects
* errors, it should raise an ELParseException.
*
* @param expression The expression to be evaluated.
* @param expectedType The expected type of the result of the evaluation
* @param fMapper A FunctionMapper to resolve functions found in
* the expression. It can be null, in which case no functions
* are supported for this invocation. The ExpressionEvaluator
* must not hold on to the FunctionMapper reference after
* returning from <code>parseExpression()</code>. The
* <code>Expression</code> object returned must invoke the same
* functions regardless of whether the mappings in the
* provided <code>FunctionMapper</code> instance change between
* calling <code>ExpressionEvaluator.parseExpression()</code>
* and <code>Expression.evaluate()</code>.
* @return The Expression object encapsulating the arguments.
*
* @exception ELException Thrown if parsing errors were found.
**/
public org.jbpm.jpdl.el.Expression parseExpression(String expression,
Class expectedType,
FunctionMapper fMapper)
throws ELException
{
// Validate and then create an Expression object.
parseExpressionString(expression);
// Create an Expression object that knows how to evaluate this.
return new JSTLExpression(this, expression, expectedType, fMapper);
}
//-------------------------------------
/**
*
* Evaluates the given expression string
**/
Object evaluate (String pExpressionString,
Class pExpectedType,
VariableResolver pResolver,
FunctionMapper functions,
Logger pLogger)
throws ELException
{
// Check for null expression strings
if (pExpressionString == null) {
throw new ELException
(Constants.NULL_EXPRESSION_STRING);
}
// Get the parsed version of the expression string
Object parsedValue = parseExpressionString (pExpressionString);
// Evaluate differently based on the parsed type
if (parsedValue instanceof String) {
// Convert the String, and cache the conversion
String strValue = (String) parsedValue;
return convertStaticValueToExpectedType (strValue,
pExpectedType,
pLogger);
}
else if (parsedValue instanceof Expression) {
// Evaluate the expression and convert
Object value =
((Expression) parsedValue).evaluate (pResolver,
functions,
pLogger);
return convertToExpectedType (value,
pExpectedType,
pLogger);
}
else if (parsedValue instanceof ExpressionString) {
// Evaluate the expression/string list and convert
String strValue =
((ExpressionString) parsedValue).evaluate (pResolver,
functions,
pLogger);
return convertToExpectedType (strValue,
pExpectedType,
pLogger);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -