📄 ognl.java
字号:
//--------------------------------------------------------------------------
// Copyright (c) 1998-2004, Drew Davidson and Luke Blanshard
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// 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.
// Neither the name of the Drew Davidson nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS 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
// COPYRIGHT OWNER OR 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.
//--------------------------------------------------------------------------
package ognl;
import java.io.StringReader;
import java.util.Map;
/**
* <P>This class provides static methods for parsing and interpreting OGNL expressions.</P>
*
* <P>The simplest use of the Ognl class is to get the value of an expression from
* an object, without extra context or pre-parsing.</P>
*
* <PRE>
* import ognl.Ognl;
* import ognl.OgnlException;
*
* try {
* result = Ognl.getValue(expression, root);
* } catch (OgnlException ex) {
* // Report error or recover
* }
* </PRE>
*
* <P>This will parse the expression given and evaluate it against the root object
* given, returning the result. If there is an error in the expression, such
* as the property is not found, the exception is encapsulated into an
* {@link ognl.OgnlException OgnlException}.</P>
*
* <P>Other more sophisticated uses of Ognl can pre-parse expressions. This
* provides two advantages: in the case of user-supplied expressions it
* allows you to catch parse errors before evaluation and it allows you to
* cache parsed expressions into an AST for better speed during repeated use.
* The pre-parsed expression is always returned as an <CODE>Object</CODE>
* to simplify use for programs that just wish to store the value for
* repeated use and do not care that it is an AST. If it does care
* it can always safely cast the value to an <CODE>AST</CODE> type.</P>
*
* <P>The Ognl class also takes a <I>context map</I> as one of the parameters
* to the set and get methods. This allows you to put your own variables
* into the available namespace for OGNL expressions. The default context
* contains only the <CODE>#root</CODE> and <CODE>#context</CODE> keys,
* which are required to be present. The <CODE>addDefaultContext(Object, Map)</CODE>
* method will alter an existing <CODE>Map</CODE> to put the defaults in.
* Here is an example that shows how to extract the <CODE>documentName</CODE>
* property out of the root object and append a string with the current user
* name in parens:</P>
*
* <PRE>
* private Map context = new HashMap();
*
* public void setUserName(String value)
* {
* context.put("userName", value);
* }
*
* try {
* // get value using our own custom context map
* result = Ognl.getValue("documentName + \" (\" + ((#userName == null) ? \"<nobody>\" : #userName) + \")\"", context, root);
* } catch (OgnlException ex) {
* // Report error or recover
* }
*
* </PRE>
*
* @author Luke Blanshard (blanshlu@netscape.net)
* @author Drew Davidson (drew@ognl.org)
* @version 27 June 1999
*/
public abstract class Ognl
{
/**
* Parses the given OGNL expression and returns a tree representation of the
* expression that can be used by <CODE>Ognl</CODE> static methods.
*
* @param expression the OGNL expression to be parsed
* @return a tree representation of the expression
* @throws ExpressionSyntaxException if the expression is malformed
* @throws OgnlException if there is a pathological environmental problem
*/
public static Object parseExpression( String expression ) throws OgnlException
{
try {
OgnlParser parser = new OgnlParser( new StringReader(expression) );
return parser.topLevelExpression();
}
catch (ParseException e) {
throw new ExpressionSyntaxException( expression, e );
}
catch (TokenMgrError e) {
throw new ExpressionSyntaxException( expression, e );
}
}
/**
* Creates and returns a new standard naming context for evaluating an OGNL
* expression.
*
* @param root the root of the object graph
* @return a new Map with the keys <CODE>root</CODE> and <CODE>context</CODE>
* set appropriately
*/
public static Map createDefaultContext( Object root )
{
return addDefaultContext( root, null, null, null, new OgnlContext() );
}
/**
* Creates and returns a new standard naming context for evaluating an OGNL
* expression.
*
* @param root the root of the object graph
* @return a new OgnlContext with the keys <CODE>root</CODE> and <CODE>context</CODE>
* set appropriately
*/
public static Map createDefaultContext( Object root, ClassResolver classResolver )
{
return addDefaultContext( root, classResolver, null, null, new OgnlContext() );
}
/**
* Creates and returns a new standard naming context for evaluating an OGNL
* expression.
*
* @param root the root of the object graph
* @return a new Map with the keys <CODE>root</CODE> and <CODE>context</CODE>
* set appropriately
*/
public static Map createDefaultContext( Object root, ClassResolver classResolver, TypeConverter converter )
{
return addDefaultContext( root, classResolver, converter, null, new OgnlContext() );
}
/**
* Creates and returns a new standard naming context for evaluating an OGNL
* expression.
*
* @param root the root of the object graph
* @return a new Map with the keys <CODE>root</CODE> and <CODE>context</CODE>
* set appropriately
*/
public static Map createDefaultContext( Object root, ClassResolver classResolver, TypeConverter converter, MemberAccess memberAccess )
{
return addDefaultContext( root, classResolver, converter, memberAccess, new OgnlContext() );
}
/**
* Appends the standard naming context for evaluating an OGNL expression
* into the context given so that cached maps can be used as a context.
*
* @param root the root of the object graph
* @param context the context to which OGNL context will be added.
* @return Context Map with the keys <CODE>root</CODE> and <CODE>context</CODE>
* set appropriately
*/
public static Map addDefaultContext( Object root, Map context )
{
return addDefaultContext( root, null, null, null, context );
}
/**
* Appends the standard naming context for evaluating an OGNL expression
* into the context given so that cached maps can be used as a context.
*
* @param root the root of the object graph
* @param context the context to which OGNL context will be added.
* @return Context Map with the keys <CODE>root</CODE> and <CODE>context</CODE>
* set appropriately
*/
public static Map addDefaultContext( Object root, ClassResolver classResolver, Map context )
{
return addDefaultContext(root, classResolver, null, null, context);
}
/**
* Appends the standard naming context for evaluating an OGNL expression
* into the context given so that cached maps can be used as a context.
*
* @param root the root of the object graph
* @param context the context to which OGNL context will be added.
* @return Context Map with the keys <CODE>root</CODE> and <CODE>context</CODE>
* set appropriately
*/
public static Map addDefaultContext( Object root, ClassResolver classResolver, TypeConverter converter, Map context )
{
return addDefaultContext(root, classResolver, converter, null, context);
}
/**
* Appends the standard naming context for evaluating an OGNL expression
* into the context given so that cached maps can be used as a context.
*
* @param root the root of the object graph
* @param context the context to which OGNL context will be added.
* @return Context Map with the keys <CODE>root</CODE> and <CODE>context</CODE>
* set appropriately
*/
public static Map addDefaultContext( Object root, ClassResolver classResolver, TypeConverter converter, MemberAccess memberAccess, Map context )
{
OgnlContext result;
if (!(context instanceof OgnlContext)) {
result = new OgnlContext();
result.setValues(context);
} else {
result = (OgnlContext)context;
}
if (classResolver != null) {
result.setClassResolver(classResolver);
}
if (converter != null) {
result.setTypeConverter(converter);
}
if (memberAccess != null) {
result.setMemberAccess(memberAccess);
}
result.setRoot(root);
return result;
}
public static void setClassResolver( Map context, ClassResolver classResolver)
{
context.put(OgnlContext.CLASS_RESOLVER_CONTEXT_KEY, classResolver);
}
public static ClassResolver getClassResolver( Map context )
{
return (ClassResolver)context.get(OgnlContext.CLASS_RESOLVER_CONTEXT_KEY);
}
public static void setTypeConverter( Map context, TypeConverter converter)
{
context.put(OgnlContext.TYPE_CONVERTER_CONTEXT_KEY, converter);
}
public static TypeConverter getTypeConverter( Map context )
{
return (TypeConverter)context.get(OgnlContext.TYPE_CONVERTER_CONTEXT_KEY);
}
public static void setMemberAccess(Map context, MemberAccess memberAccess)
{
context.put(OgnlContext.MEMBER_ACCESS_CONTEXT_KEY, memberAccess);
}
public static MemberAccess getMemberAccess(Map context)
{
return (MemberAccess)context.get(OgnlContext.MEMBER_ACCESS_CONTEXT_KEY);
}
public static void setRoot( Map context, Object root)
{
context.put(OgnlContext.ROOT_CONTEXT_KEY, root);
}
public static Object getRoot( Map context )
{
return context.get(OgnlContext.ROOT_CONTEXT_KEY);
}
public static Evaluation getLastEvaluation( Map context )
{
return (Evaluation)context.get(OgnlContext.LAST_EVALUATION_CONTEXT_KEY);
}
/**
* Evaluates the given OGNL expression tree to extract a value from the given root
* object. The default context is set for the given context and root via
* <CODE>addDefaultContext()</CODE>.
*
* @param tree the OGNL expression tree to evaluate, as returned by parseExpression()
* @param context the naming context for the evaluation
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -