Coverage Report - org.apache.commons.ognl.Ognl
 
Classes in this File Line Coverage Branch Coverage Complexity
Ognl
49%
43/87
64%
9/14
1.277
 
 1  
 package org.apache.commons.ognl;
 2  
 
 3  
 /*
 4  
  * Licensed to the Apache Software Foundation (ASF) under one
 5  
  * or more contributor license agreements.  See the NOTICE file
 6  
  * distributed with this work for additional information
 7  
  * regarding copyright ownership.  The ASF licenses this file
 8  
  * to you under the Apache License, Version 2.0 (the
 9  
  * "License"); you may not use this file except in compliance
 10  
  * with the License.  You may obtain a copy of the License at
 11  
  *
 12  
  *   http://www.apache.org/licenses/LICENSE-2.0
 13  
  *
 14  
  * Unless required by applicable law or agreed to in writing,
 15  
  * software distributed under the License is distributed on an
 16  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17  
  * KIND, either express or implied.  See the License for the
 18  
  * specific language governing permissions and limitations
 19  
  * under the License.
 20  
  */
 21  
 
 22  
 import org.apache.commons.ognl.enhance.ExpressionAccessor;
 23  
 
 24  
 import java.io.StringReader;
 25  
 import java.util.Map;
 26  
 
 27  
 /**
 28  
  * <p>
 29  
  * This class provides static methods for parsing and interpreting OGNL expressions.
 30  
  * </p>
 31  
  * <p>
 32  
  * The simplest use of the Ognl class is to get the value of an expression from an object, without extra context or
 33  
  * pre-parsing.
 34  
  * </p>
 35  
  * 
 36  
  * <pre>
 37  
  * 
 38  
  * import org.apache.commons.ognl.Ognl;
 39  
  * import org.apache.commons.ognl.OgnlException;
 40  
  * ...
 41  
  * try
 42  
  * {
 43  
  *     result = Ognl.getValue( expression, root );
 44  
  * }
 45  
  * catch ( OgnlException ex )
 46  
  * {
 47  
  *     // Report error or recover
 48  
  * }
 49  
  * 
 50  
  * </pre>
 51  
  * <p>
 52  
  * This will parse the expression given and evaluate it against the root object given, returning the result. If there is
 53  
  * an error in the expression, such as the property is not found, the exception is encapsulated into an
 54  
  * {@link org.apache.commons.ognl.OgnlException OgnlException}.
 55  
  * </p>
 56  
  * <p>
 57  
  * Other more sophisticated uses of Ognl can pre-parse expressions. This provides two advantages: in the case of
 58  
  * user-supplied expressions it allows you to catch parse errors before evaluation and it allows you to cache parsed
 59  
  * expressions into an AST for better speed during repeated use. The pre-parsed expression is always returned as an
 60  
  * <code>Object</code> to simplify use for programs that just wish to store the value for repeated use and do not care
 61  
  * that it is an AST. If it does care it can always safely cast the value to an <code>AST</code> type.
 62  
  * </p>
 63  
  * <p>
 64  
  * The Ognl class also takes a <I>context map</I> as one of the parameters to the set and get methods. This allows you
 65  
  * to put your own variables into the available namespace for OGNL expressions. The default context contains only the
 66  
  * <code>#root</code> and <code>#context</code> keys, which are required to be present. The
 67  
  * <code>addDefaultContext(Object, Map)</code> method will alter an existing <code>Map</code> to put the defaults in.
 68  
  * Here is an example that shows how to extract the <code>documentName</code> property out of the root object and append
 69  
  * a string with the current user name in parens:
 70  
  * </p>
 71  
  * 
 72  
  * <pre>
 73  
  * 
 74  
  * private Map&lt;String, Object&gt; context = new HashMap&lt;String, Object&gt;();
 75  
  * ...
 76  
  * public void setUserName( String value )
 77  
  * {
 78  
  *     context.put("userName", value);
 79  
  * }
 80  
  * ...
 81  
  * try
 82  
  * {
 83  
  *     // get value using our own custom context map
 84  
  *     result = Ognl.getValue( "documentName + \" (\" + ((#userName == null) ? \"&lt;nobody&gt;\" : #userName ) +
 85  
  * \")\"", context, root );
 86  
  * }
 87  
  * catch ( OgnlException ex )
 88  
  * {
 89  
  *     // Report error or recover
 90  
  * }
 91  
  * 
 92  
  * </pre>
 93  
  * 
 94  
  * @author Luke Blanshard (blanshlu@netscape.net)
 95  
  * @author Drew Davidson (drew@ognl.org)
 96  
  * @version 27 June 1999
 97  
  */
 98  
 public abstract class Ognl
 99  
 {
 100  
 
 101  
     /**
 102  
      * Parses the given OGNL expression and returns a tree representation of the expression that can be used by
 103  
      * <code>Ognl</code> static methods.
 104  
      * 
 105  
      * @param expression the OGNL expression to be parsed
 106  
      * @return a tree representation of the expression
 107  
      * @throws ExpressionSyntaxException if the expression is malformed
 108  
      * @throws OgnlException if there is a pathological environmental problem
 109  
      */
 110  
     public static Object parseExpression( String expression )
 111  
         throws OgnlException
 112  
     {
 113  
         try
 114  
         {
 115  1148
             OgnlParser parser = new OgnlParser( new StringReader( expression ) );
 116  1148
             return parser.topLevelExpression();
 117  
         }
 118  1
         catch ( ParseException e )
 119  
         {
 120  1
             throw new ExpressionSyntaxException( expression, e );
 121  
         }
 122  4
         catch ( TokenMgrError e )
 123  
         {
 124  4
             throw new ExpressionSyntaxException( expression, e );
 125  
         }
 126  
     }
 127  
 
 128  
     /**
 129  
      * Parses and compiles the given expression using the {@link org.apache.commons.ognl.enhance.OgnlExpressionCompiler}
 130  
      * returned from
 131  
      * {@link org.apache.commons.ognl.OgnlRuntime#getCompiler(OgnlContext)}.
 132  
      * 
 133  
      * @param context The context to use.
 134  
      * @param root The root object for the given expression.
 135  
      * @param expression The expression to compile.
 136  
      * @return The node with a compiled accessor set on {@link org.apache.commons.ognl.Node#getAccessor()} if
 137  
      * compilation was successfull.
 138  
      *         In instances where compilation wasn't possible because of a partially null expression the
 139  
      *         {@link ExpressionAccessor} instance may be null and the compilation of this expression still possible at
 140  
      *         some as yet indertermined point in the future.
 141  
      * @throws Exception If a compilation error occurs.
 142  
      */
 143  
     public static Node compileExpression( OgnlContext context, Object root, String expression )
 144  
         throws Exception
 145  
     {
 146  562
         Node expr = (Node) Ognl.parseExpression( expression );
 147  
 
 148  562
         OgnlRuntime.compileExpression( context, expr, root );
 149  
 
 150  561
         return expr;
 151  
     }
 152  
 
 153  
     /**
 154  
      * Creates and returns a new standard naming context for evaluating an OGNL expression.
 155  
      * 
 156  
      * @param root the root of the object graph
 157  
      * @return a new Map with the keys <code>root</code> and <code>context</code> set appropriately
 158  
      */
 159  
     public static Map<String, Object> createDefaultContext( Object root )
 160  
     {
 161  722
         return addDefaultContext( root, null, null, null, new OgnlContext() );
 162  
     }
 163  
 
 164  
     /**
 165  
      * Creates and returns a new standard naming context for evaluating an OGNL expression.
 166  
      * 
 167  
      * @param root The root of the object graph.
 168  
      * @param classResolver The resolver used to instantiate {@link Class} instances referenced in the expression.
 169  
      * @return a new OgnlContext with the keys <code>root</code> and <code>context</code> set appropriately
 170  
      */
 171  
     public static Map<String, Object> createDefaultContext( Object root, ClassResolver classResolver )
 172  
     {
 173  0
         return addDefaultContext( root, classResolver, null, null, new OgnlContext() );
 174  
     }
 175  
 
 176  
     /**
 177  
      * Creates and returns a new standard naming context for evaluating an OGNL expression.
 178  
      * 
 179  
      * @param root The root of the object graph.
 180  
      * @param classResolver The resolver used to instantiate {@link Class} instances referenced in the expression.
 181  
      * @param converter Converter used to convert return types of an expression in to their desired types.
 182  
      * @return a new Map with the keys <code>root</code> and <code>context</code> set appropriately
 183  
      */
 184  
     public static Map<String, Object> createDefaultContext( Object root, ClassResolver classResolver,
 185  
                                                             TypeConverter converter )
 186  
     {
 187  0
         return addDefaultContext( root, classResolver, converter, null, new OgnlContext() );
 188  
     }
 189  
 
 190  
     /**
 191  
      * Creates and returns a new standard naming context for evaluating an OGNL expression.
 192  
      * 
 193  
      * @param root The root of the object graph.
 194  
      * @param classResolver The resolver used to instantiate {@link Class} instances referenced in the expression.
 195  
      * @param converter Converter used to convert return types of an expression in to their desired types.
 196  
      * @param memberAccess Java security handling object to determine semantics for accessing normally private/protected
 197  
      *            methods / fields.
 198  
      * @return a new Map with the keys <code>root</code> and <code>context</code> set appropriately
 199  
      */
 200  
     public static Map<String, Object> createDefaultContext( Object root, ClassResolver classResolver,
 201  
                                                             TypeConverter converter, MemberAccess memberAccess )
 202  
     {
 203  0
         return addDefaultContext( root, classResolver, converter, memberAccess, new OgnlContext() );
 204  
     }
 205  
 
 206  
     /**
 207  
      * Appends the standard naming context for evaluating an OGNL expression into the context given so that cached maps
 208  
      * can be used as a context.
 209  
      * 
 210  
      * @param root the root of the object graph
 211  
      * @param context the context to which OGNL context will be added.
 212  
      * @return Context Map with the keys <code>root</code> and <code>context</code> set appropriately
 213  
      */
 214  
     public static Map<String, Object> addDefaultContext( Object root, Map<String, Object> context )
 215  
     {
 216  690
         return addDefaultContext( root, null, null, null, context );
 217  
     }
 218  
 
 219  
     /**
 220  
      * Appends the standard naming context for evaluating an OGNL expression into the context given so that cached maps
 221  
      * can be used as a context.
 222  
      * 
 223  
      * @param root The root of the object graph.
 224  
      * @param classResolver The resolver used to instantiate {@link Class} instances referenced in the expression.
 225  
      * @param context The context to which OGNL context will be added.
 226  
      * @return Context Map with the keys <code>root</code> and <code>context</code> set appropriately
 227  
      */
 228  
     public static Map<String, Object> addDefaultContext( Object root, ClassResolver classResolver,
 229  
                                                          Map<String, Object> context )
 230  
     {
 231  0
         return addDefaultContext( root, classResolver, null, null, context );
 232  
     }
 233  
 
 234  
     /**
 235  
      * Appends the standard naming context for evaluating an OGNL expression into the context given so that cached maps
 236  
      * can be used as a context.
 237  
      * 
 238  
      * @param root The root of the object graph.
 239  
      * @param classResolver The resolver used to instantiate {@link Class} instances referenced in the expression.
 240  
      * @param converter Converter used to convert return types of an expression in to their desired types.
 241  
      * @param context The context to which OGNL context will be added.
 242  
      * @return Context Map with the keys <code>root</code> and <code>context</code> set appropriately
 243  
      */
 244  
     public static Map<String, Object> addDefaultContext( Object root, ClassResolver classResolver,
 245  
                                                          TypeConverter converter, Map<String, Object> context )
 246  
     {
 247  0
         return addDefaultContext( root, classResolver, converter, null, context );
 248  
     }
 249  
 
 250  
     /**
 251  
      * Appends the standard naming context for evaluating an OGNL expression into the context given so that cached maps
 252  
      * can be used as a context.
 253  
      * 
 254  
      * @param root the root of the object graph
 255  
      * @param classResolver The class loading resolver that should be used to resolve class references.
 256  
      * @param converter The type converter to be used by default.
 257  
      * @param memberAccess Definition for handling private/protected access.
 258  
      * @param context Default context to use, if not an {@link OgnlContext} will be dumped into a new
 259  
      *            {@link OgnlContext} object.
 260  
      * @return Context Map with the keys <code>root</code> and <code>context</code> set appropriately
 261  
      */
 262  
     public static Map<String, Object> addDefaultContext( Object root, ClassResolver classResolver,
 263  
                                                          TypeConverter converter, MemberAccess memberAccess,
 264  
                                                          Map<String, Object> context )
 265  
     {
 266  
         OgnlContext result;
 267  
 
 268  1412
         if ( !( context instanceof OgnlContext ) )
 269  
         {
 270  0
             result = new OgnlContext();
 271  0
             result.setValues( context );
 272  
         }
 273  
         else
 274  
         {
 275  1412
             result = (OgnlContext) context;
 276  
         }
 277  1412
         if ( classResolver != null )
 278  
         {
 279  0
             result.setClassResolver( classResolver );
 280  
         }
 281  1412
         if ( converter != null )
 282  
         {
 283  0
             result.setTypeConverter( converter );
 284  
         }
 285  1412
         if ( memberAccess != null )
 286  
         {
 287  0
             result.setMemberAccess( memberAccess );
 288  
         }
 289  
 
 290  1412
         result.setRoot( root );
 291  1412
         return result;
 292  
     }
 293  
 
 294  
     /**
 295  
      * Configures the {@link ClassResolver} to use for the given context. Will be used during expression parsing /
 296  
      * execution to resolve class names.
 297  
      * 
 298  
      * @param context The context to place the resolver.
 299  
      * @param classResolver The resolver to use to resolve classes.
 300  
      */
 301  
     public static void setClassResolver( Map<String, Object> context, ClassResolver classResolver )
 302  
     {
 303  0
         context.put( OgnlContext.CLASS_RESOLVER_CONTEXT_KEY, classResolver );
 304  0
     }
 305  
 
 306  
     /**
 307  
      * Gets the previously stored {@link ClassResolver} for the given context - if any.
 308  
      * 
 309  
      * @param context The context to get the configured resolver from.
 310  
      * @return The resolver instance, or null if none found.
 311  
      */
 312  
     public static ClassResolver getClassResolver( Map<String, Object> context )
 313  
     {
 314  0
         return (ClassResolver) context.get( OgnlContext.CLASS_RESOLVER_CONTEXT_KEY );
 315  
     }
 316  
 
 317  
     /**
 318  
      * Configures the type converter to use for a given context. This will be used to convert into / out of various java
 319  
      * class types.
 320  
      * 
 321  
      * @param context The context to configure it for.
 322  
      * @param converter The converter to use.
 323  
      */
 324  
     public static void setTypeConverter( Map<String, Object> context, TypeConverter converter )
 325  
     {
 326  0
         context.put( OgnlContext.TYPE_CONVERTER_CONTEXT_KEY, converter );
 327  0
     }
 328  
 
 329  
     /**
 330  
      * Gets the currently configured {@link TypeConverter} for the given context - if any.
 331  
      * 
 332  
      * @param context The context to get the converter from.
 333  
      * @return The converter - or null if none found.
 334  
      */
 335  
     public static TypeConverter getTypeConverter( Map<String, Object> context )
 336  
     {
 337  0
         return (TypeConverter) context.get( OgnlContext.TYPE_CONVERTER_CONTEXT_KEY );
 338  
     }
 339  
 
 340  
     /**
 341  
      * Configures the specified context with a {@link MemberAccess} instance for handling field/method protection
 342  
      * levels.
 343  
      * 
 344  
      * @param context The context to configure.
 345  
      * @param memberAccess The access resolver to configure the context with.
 346  
      */
 347  
     public static void setMemberAccess( Map<String, Object> context, MemberAccess memberAccess )
 348  
     {
 349  0
         context.put( OgnlContext.MEMBER_ACCESS_CONTEXT_KEY, memberAccess );
 350  0
     }
 351  
 
 352  
     /**
 353  
      * Gets the currently stored {@link MemberAccess} object for the given context - if any.
 354  
      * 
 355  
      * @param context The context to get the object from.
 356  
      * @return The configured {@link MemberAccess} instance in the specified context - or null if none found.
 357  
      */
 358  
     public static MemberAccess getMemberAccess( Map<String, Object> context )
 359  
     {
 360  0
         return (MemberAccess) context.get( OgnlContext.MEMBER_ACCESS_CONTEXT_KEY );
 361  
     }
 362  
 
 363  
     /**
 364  
      * Sets the root object to use for all expressions in the given context - doesn't necessarily replace root object
 365  
      * instances explicitly passed in to other expression resolving methods on this class.
 366  
      * 
 367  
      * @param context The context to store the root object in.
 368  
      * @param root The root object.
 369  
      */
 370  
     public static void setRoot( Map<String, Object> context, Object root )
 371  
     {
 372  0
         context.put( OgnlContext.ROOT_CONTEXT_KEY, root );
 373  0
     }
 374  
 
 375  
     /**
 376  
      * Gets the stored root object for the given context - if any.
 377  
      * 
 378  
      * @param context The context to get the root object from.
 379  
      * @return The root object - or null if none found.
 380  
      */
 381  
     public static Object getRoot( Map<String, Object> context )
 382  
     {
 383  0
         return context.get( OgnlContext.ROOT_CONTEXT_KEY );
 384  
     }
 385  
 
 386  
     /**
 387  
      * Gets the last {@link Evaluation} executed on the given context.
 388  
      * 
 389  
      * @param context The context to get the evaluation from.
 390  
      * @return The {@link Evaluation} - or null if none was found.
 391  
      */
 392  
     public static Evaluation getLastEvaluation( Map<String, Object> context )
 393  
     {
 394  0
         return (Evaluation) context.get( OgnlContext.LAST_EVALUATION_CONTEXT_KEY );
 395  
     }
 396  
 
 397  
     /**
 398  
      * Evaluates the given OGNL expression tree to extract a value from the given root object. The default context is
 399  
      * set for the given context and root via <code>addDefaultContext()</code>.
 400  
      * 
 401  
      * @param tree the OGNL expression tree to evaluate, as returned by parseExpression()
 402  
      * @param context the naming context for the evaluation
 403  
      * @param root the root object for the OGNL expression
 404  
      * @return the result of evaluating the expression
 405  
      * @throws MethodFailedException if the expression called a method which failed
 406  
      * @throws NoSuchPropertyException if the expression referred to a nonexistent property
 407  
      * @throws InappropriateExpressionException if the expression can't be used in this context
 408  
      * @throws OgnlException if there is a pathological environmental problem
 409  
      */
 410  
     public static <T> T getValue( Object tree, Map<String, Object> context, Object root )
 411  
         throws OgnlException
 412  
     {
 413  589
         return Ognl.<T> getValue( tree, context, root, null );
 414  
     }
 415  
 
 416  
     /**
 417  
      * Evaluates the given OGNL expression tree to extract a value from the given root object. The default context is
 418  
      * set for the given context and root via <code>addDefaultContext()</code>.
 419  
      * 
 420  
      * @param tree the OGNL expression tree to evaluate, as returned by parseExpression()
 421  
      * @param context the naming context for the evaluation
 422  
      * @param root the root object for the OGNL expression
 423  
      * @param resultType the converted type of the resultant object, using the context's type converter
 424  
      * @return the result of evaluating the expression
 425  
      * @throws MethodFailedException if the expression called a method which failed
 426  
      * @throws NoSuchPropertyException if the expression referred to a nonexistent property
 427  
      * @throws InappropriateExpressionException if the expression can't be used in this context
 428  
      * @throws OgnlException if there is a pathological environmental problem
 429  
      */
 430  
     @SuppressWarnings( "unchecked" ) // will cause CCE if types are not compatible
 431  
     public static <T> T getValue( Object tree, Map<String, Object> context, Object root, Class<T> resultType )
 432  
         throws OgnlException
 433  
     {
 434  
         T result;
 435  595
         OgnlContext ognlContext = (OgnlContext) addDefaultContext( root, context );
 436  
 
 437  595
         Node node = (Node) tree;
 438  
 
 439  595
         if ( node.getAccessor() != null )
 440  
         {
 441  562
             result = (T) node.getAccessor().get( ognlContext, root );
 442  
         }
 443  
         else
 444  
         {
 445  33
             result = (T) node.getValue( ognlContext, root );
 446  
         }
 447  
 
 448  581
         if ( resultType != null )
 449  
         {
 450  0
             result = getTypeConverter( context ).convertValue( context, root, null, null, result, resultType );
 451  
         }
 452  581
         return result;
 453  
     }
 454  
 
 455  
     /**
 456  
      * Gets the value represented by the given pre-compiled expression on the specified root object.
 457  
      * 
 458  
      * @param expression The pre-compiled expression, as found in {@link Node#getAccessor()}.
 459  
      * @param context The ognl context.
 460  
      * @param root The object to retrieve the expression value from.
 461  
      * @return The value.
 462  
      */
 463  
     @SuppressWarnings( "unchecked" ) // will cause CCE if types are not compatible
 464  
     public static <T> T getValue( ExpressionAccessor expression, OgnlContext context, Object root )
 465  
     {
 466  0
         return (T) expression.get( context, root );
 467  
     }
 468  
 
 469  
     /**
 470  
      * Gets the value represented by the given pre-compiled expression on the specified root object.
 471  
      * 
 472  
      * @param expression The pre-compiled expression, as found in {@link Node#getAccessor()}.
 473  
      * @param context The ognl context.
 474  
      * @param root The object to retrieve the expression value from.
 475  
      * @param resultType The desired object type that the return value should be converted to using the
 476  
      *            {@link #getTypeConverter(java.util.Map)} .
 477  
      * @return The value.
 478  
      */
 479  
     public static <T> T getValue( ExpressionAccessor expression, OgnlContext context, Object root, Class<T> resultType )
 480  
         throws OgnlException
 481  
     {
 482  0
         return getTypeConverter( context ).convertValue( context, root, null, null, expression.get( context, root ),
 483  
                                                          resultType );
 484  
     }
 485  
 
 486  
     /**
 487  
      * Evaluates the given OGNL expression to extract a value from the given root object in a given context
 488  
      * 
 489  
      * @see #parseExpression(String)
 490  
      * @see #getValue(Object,Object)
 491  
      * @param expression the OGNL expression to be parsed
 492  
      * @param context the naming context for the evaluation
 493  
      * @param root the root object for the OGNL expression
 494  
      * @return the result of evaluating the expression
 495  
      * @throws MethodFailedException if the expression called a method which failed
 496  
      * @throws NoSuchPropertyException if the expression referred to a nonexistent property
 497  
      * @throws InappropriateExpressionException if the expression can't be used in this context
 498  
      * @throws OgnlException if there is a pathological environmental problem
 499  
      */
 500  
     public static <T> T getValue( String expression, Map<String, Object> context, Object root )
 501  
         throws OgnlException
 502  
     {
 503  5
         return Ognl.<T> getValue( expression, context, root, null );
 504  
     }
 505  
 
 506  
     /**
 507  
      * Evaluates the given OGNL expression to extract a value from the given root object in a given context
 508  
      * 
 509  
      * @see #parseExpression(String)
 510  
      * @see #getValue(Object,Object)
 511  
      * @param expression the OGNL expression to be parsed
 512  
      * @param context the naming context for the evaluation
 513  
      * @param root the root object for the OGNL expression
 514  
      * @param resultType the converted type of the resultant object, using the context's type converter
 515  
      * @return the result of evaluating the expression
 516  
      * @throws MethodFailedException if the expression called a method which failed
 517  
      * @throws NoSuchPropertyException if the expression referred to a nonexistent property
 518  
      * @throws InappropriateExpressionException if the expression can't be used in this context
 519  
      * @throws OgnlException if there is a pathological environmental problem
 520  
      */
 521  
     public static <T> T getValue( String expression, Map<String, Object> context, Object root, Class<T> resultType )
 522  
         throws OgnlException
 523  
     {
 524  5
         return Ognl.<T> getValue( parseExpression( expression ), context, root, resultType );
 525  
     }
 526  
 
 527  
     /**
 528  
      * Evaluates the given OGNL expression tree to extract a value from the given root object.
 529  
      * 
 530  
      * @param tree the OGNL expression tree to evaluate, as returned by parseExpression()
 531  
      * @param root the root object for the OGNL expression
 532  
      * @return the result of evaluating the expression
 533  
      * @throws MethodFailedException if the expression called a method which failed
 534  
      * @throws NoSuchPropertyException if the expression referred to a nonexistent property
 535  
      * @throws InappropriateExpressionException if the expression can't be used in this context
 536  
      * @throws OgnlException if there is a pathological environmental problem
 537  
      */
 538  
     public static <T> T getValue( Object tree, Object root )
 539  
         throws OgnlException
 540  
     {
 541  0
         return Ognl.<T> getValue( tree, root, null );
 542  
     }
 543  
 
 544  
     /**
 545  
      * Evaluates the given OGNL expression tree to extract a value from the given root object.
 546  
      * 
 547  
      * @param tree the OGNL expression tree to evaluate, as returned by parseExpression()
 548  
      * @param root the root object for the OGNL expression
 549  
      * @param resultType the converted type of the resultant object, using the context's type converter
 550  
      * @return the result of evaluating the expression
 551  
      * @throws MethodFailedException if the expression called a method which failed
 552  
      * @throws NoSuchPropertyException if the expression referred to a nonexistent property
 553  
      * @throws InappropriateExpressionException if the expression can't be used in this context
 554  
      * @throws OgnlException if there is a pathological environmental problem
 555  
      */
 556  
     public static <T> T getValue( Object tree, Object root, Class<T> resultType )
 557  
         throws OgnlException
 558  
     {
 559  1
         return Ognl.<T> getValue( tree, createDefaultContext( root ), root, resultType );
 560  
     }
 561  
 
 562  
     /**
 563  
      * Convenience method that combines calls to <code> parseExpression </code> and <code> getValue</code>.
 564  
      * 
 565  
      * @see #parseExpression(String)
 566  
      * @see #getValue(Object,Object)
 567  
      * @param expression the OGNL expression to be parsed
 568  
      * @param root the root object for the OGNL expression
 569  
      * @return the result of evaluating the expression
 570  
      * @throws ExpressionSyntaxException if the expression is malformed
 571  
      * @throws MethodFailedException if the expression called a method which failed
 572  
      * @throws NoSuchPropertyException if the expression referred to a nonexistent property
 573  
      * @throws InappropriateExpressionException if the expression can't be used in this context
 574  
      * @throws OgnlException if there is a pathological environmental problem
 575  
      */
 576  
     public static <T> T getValue( String expression, Object root )
 577  
         throws OgnlException
 578  
     {
 579  1
         return Ognl.<T> getValue( expression, root, null );
 580  
     }
 581  
 
 582  
     /**
 583  
      * Convenience method that combines calls to <code> parseExpression </code> and <code> getValue</code>.
 584  
      * 
 585  
      * @see #parseExpression(String)
 586  
      * @see #getValue(Object,Object)
 587  
      * @param expression the OGNL expression to be parsed
 588  
      * @param root the root object for the OGNL expression
 589  
      * @param resultType the converted type of the resultant object, using the context's type converter
 590  
      * @return the result of evaluating the expression
 591  
      * @throws ExpressionSyntaxException if the expression is malformed
 592  
      * @throws MethodFailedException if the expression called a method which failed
 593  
      * @throws NoSuchPropertyException if the expression referred to a nonexistent property
 594  
      * @throws InappropriateExpressionException if the expression can't be used in this context
 595  
      * @throws OgnlException if there is a pathological environmental problem
 596  
      */
 597  
     public static <T> T getValue( String expression, Object root, Class<T> resultType )
 598  
         throws OgnlException
 599  
     {
 600  1
         return Ognl.<T> getValue( parseExpression( expression ), root, resultType );
 601  
     }
 602  
 
 603  
     /**
 604  
      * Evaluates the given OGNL expression tree to insert a value into the object graph rooted at the given root object.
 605  
      * The default context is set for the given context and root via <code>addDefaultContext()</code>.
 606  
      * 
 607  
      * @param tree the OGNL expression tree to evaluate, as returned by parseExpression()
 608  
      * @param context the naming context for the evaluation
 609  
      * @param root the root object for the OGNL expression
 610  
      * @param value the value to insert into the object graph
 611  
      * @throws MethodFailedException if the expression called a method which failed
 612  
      * @throws NoSuchPropertyException if the expression referred to a nonexistent property
 613  
      * @throws InappropriateExpressionException if the expression can't be used in this context
 614  
      * @throws OgnlException if there is a pathological environmental problem
 615  
      */
 616  
     public static void setValue( Object tree, Map<String, Object> context, Object root, Object value )
 617  
         throws OgnlException
 618  
     {
 619  63
         OgnlContext ognlContext = (OgnlContext) addDefaultContext( root, context );
 620  63
         Node n = (Node) tree;
 621  
 
 622  63
         if ( n.getAccessor() != null )
 623  
         {
 624  57
             n.getAccessor().set( ognlContext, root, value );
 625  47
             return;
 626  
         }
 627  
 
 628  6
         n.setValue( ognlContext, root, value );
 629  6
     }
 630  
 
 631  
     /**
 632  
      * Sets the value given using the pre-compiled expression on the specified root object.
 633  
      * 
 634  
      * @param expression The pre-compiled expression, as found in {@link Node#getAccessor()}.
 635  
      * @param context The ognl context.
 636  
      * @param root The object to set the expression value on.
 637  
      * @param value The value to set.
 638  
      */
 639  
     public static void setValue( ExpressionAccessor expression, OgnlContext context, Object root, Object value )
 640  
     {
 641  0
         expression.set( context, root, value );
 642  0
     }
 643  
 
 644  
     /**
 645  
      * Evaluates the given OGNL expression to insert a value into the object graph rooted at the given root object given
 646  
      * the context.
 647  
      * 
 648  
      * @param expression the OGNL expression to be parsed
 649  
      * @param root the root object for the OGNL expression
 650  
      * @param context the naming context for the evaluation
 651  
      * @param value the value to insert into the object graph
 652  
      * @throws MethodFailedException if the expression called a method which failed
 653  
      * @throws NoSuchPropertyException if the expression referred to a nonexistent property
 654  
      * @throws InappropriateExpressionException if the expression can't be used in this context
 655  
      * @throws OgnlException if there is a pathological environmental problem
 656  
      */
 657  
     public static void setValue( String expression, Map<String, Object> context, Object root, Object value )
 658  
         throws OgnlException
 659  
     {
 660  2
         setValue( parseExpression( expression ), context, root, value );
 661  2
     }
 662  
 
 663  
     /**
 664  
      * Evaluates the given OGNL expression tree to insert a value into the object graph rooted at the given root object.
 665  
      * 
 666  
      * @param tree the OGNL expression tree to evaluate, as returned by parseExpression()
 667  
      * @param root the root object for the OGNL expression
 668  
      * @param value the value to insert into the object graph
 669  
      * @throws MethodFailedException if the expression called a method which failed
 670  
      * @throws NoSuchPropertyException if the expression referred to a nonexistent property
 671  
      * @throws InappropriateExpressionException if the expression can't be used in this context
 672  
      * @throws OgnlException if there is a pathological environmental problem
 673  
      */
 674  
     public static void setValue( Object tree, Object root, Object value )
 675  
         throws OgnlException
 676  
     {
 677  0
         setValue( tree, createDefaultContext( root ), root, value );
 678  0
     }
 679  
 
 680  
     /**
 681  
      * Convenience method that combines calls to <code> parseExpression </code> and <code> setValue</code>.
 682  
      * 
 683  
      * @see #parseExpression(String)
 684  
      * @see #setValue(Object,Object,Object)
 685  
      * @param expression the OGNL expression to be parsed
 686  
      * @param root the root object for the OGNL expression
 687  
      * @param value the value to insert into the object graph
 688  
      * @throws ExpressionSyntaxException if the expression is malformed
 689  
      * @throws MethodFailedException if the expression called a method which failed
 690  
      * @throws NoSuchPropertyException if the expression referred to a nonexistent property
 691  
      * @throws InappropriateExpressionException if the expression can't be used in this context
 692  
      * @throws OgnlException if there is a pathological environmental problem
 693  
      */
 694  
     public static void setValue( String expression, Object root, Object value )
 695  
         throws OgnlException
 696  
     {
 697  0
         setValue( parseExpression( expression ), root, value );
 698  0
     }
 699  
 
 700  
     /**
 701  
      * Checks if the specified {@link Node} instance represents a constant expression.
 702  
      * 
 703  
      * @param tree The {@link Node} to check.
 704  
      * @param context The context to use.
 705  
      * @return True if the node is a constant - false otherwise.
 706  
      * @throws OgnlException If an error occurs checking the expression.
 707  
      */
 708  
     public static boolean isConstant( Object tree, Map<String, Object> context )
 709  
         throws OgnlException
 710  
     {
 711  12
         return ( (SimpleNode) tree ).isConstant( (OgnlContext) addDefaultContext( null, context ) );
 712  
     }
 713  
 
 714  
     /**
 715  
      * Checks if the specified expression represents a constant expression.
 716  
      * 
 717  
      * @param expression The expression to check.
 718  
      * @param context The context to use.
 719  
      * @return True if the node is a constant - false otherwise.
 720  
      * @throws OgnlException If an error occurs checking the expression.
 721  
      */
 722  
     public static boolean isConstant( String expression, Map<String, Object> context )
 723  
         throws OgnlException
 724  
     {
 725  0
         return isConstant( parseExpression( expression ), context );
 726  
     }
 727  
 
 728  
     /**
 729  
      * Same as {@link #isConstant(Object, java.util.Map)} - only the {@link Map} context is created for you.
 730  
      * 
 731  
      * @param tree The {@link Node} to check.
 732  
      * @return True if the node represents a constant expression - false otherwise.
 733  
      * @throws OgnlException If an exception occurs.
 734  
      */
 735  
     public static boolean isConstant( Object tree )
 736  
         throws OgnlException
 737  
     {
 738  0
         return isConstant( tree, createDefaultContext( null ) );
 739  
     }
 740  
 
 741  
     /**
 742  
      * Same as {@link #isConstant(String, java.util.Map)} - only the {@link Map} instance is created for you.
 743  
      * 
 744  
      * @param expression The expression to check.
 745  
      * @return True if the expression represents a constant - false otherwise.
 746  
      * @throws OgnlException If an exception occurs.
 747  
      */
 748  
     public static boolean isConstant( String expression )
 749  
         throws OgnlException
 750  
     {
 751  0
         return isConstant( parseExpression( expression ), createDefaultContext( null ) );
 752  
     }
 753  
 
 754  
     public static boolean isSimpleProperty( Object tree, Map<String, Object> context )
 755  
         throws OgnlException
 756  
     {
 757  16
         return ( (SimpleNode) tree ).isSimpleProperty( (OgnlContext) addDefaultContext( null, context ) );
 758  
     }
 759  
 
 760  
     public static boolean isSimpleProperty( String expression, Map<String, Object> context )
 761  
         throws OgnlException
 762  
     {
 763  0
         return isSimpleProperty( parseExpression( expression ), context );
 764  
     }
 765  
 
 766  
     public static boolean isSimpleProperty( Object tree )
 767  
         throws OgnlException
 768  
     {
 769  0
         return isSimpleProperty( tree, createDefaultContext( null ) );
 770  
     }
 771  
 
 772  
     public static boolean isSimpleProperty( String expression )
 773  
         throws OgnlException
 774  
     {
 775  0
         return isSimpleProperty( parseExpression( expression ), createDefaultContext( null ) );
 776  
     }
 777  
 
 778  
     public static boolean isSimpleNavigationChain( Object tree, Map<String, Object> context )
 779  
         throws OgnlException
 780  
     {
 781  4
         return ( (SimpleNode) tree ).isSimpleNavigationChain( (OgnlContext) addDefaultContext( null, context ) );
 782  
     }
 783  
 
 784  
     public static boolean isSimpleNavigationChain( String expression, Map<String, Object> context )
 785  
         throws OgnlException
 786  
     {
 787  0
         return isSimpleNavigationChain( parseExpression( expression ), context );
 788  
     }
 789  
 
 790  
     public static boolean isSimpleNavigationChain( Object tree )
 791  
         throws OgnlException
 792  
     {
 793  0
         return isSimpleNavigationChain( tree, createDefaultContext( null ) );
 794  
     }
 795  
 
 796  
     public static boolean isSimpleNavigationChain( String expression )
 797  
         throws OgnlException
 798  
     {
 799  0
         return isSimpleNavigationChain( parseExpression( expression ), createDefaultContext( null ) );
 800  
     }
 801  
 
 802  
     /** You can't make one of these. */
 803  
     private Ognl()
 804  0
     {
 805  0
     }
 806  
 }