View Javadoc

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             OgnlParser parser = new OgnlParser( new StringReader( expression ) );
116             return parser.topLevelExpression();
117         }
118         catch ( ParseException e )
119         {
120             throw new ExpressionSyntaxException( expression, e );
121         }
122         catch ( TokenMgrError e )
123         {
124             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         Node expr = (Node) Ognl.parseExpression( expression );
147 
148         OgnlRuntime.compileExpression( context, expr, root );
149 
150         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         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         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         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         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         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         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         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         if ( !( context instanceof OgnlContext ) )
269         {
270             result = new OgnlContext();
271             result.setValues( context );
272         }
273         else
274         {
275             result = (OgnlContext) context;
276         }
277         if ( classResolver != null )
278         {
279             result.setClassResolver( classResolver );
280         }
281         if ( converter != null )
282         {
283             result.setTypeConverter( converter );
284         }
285         if ( memberAccess != null )
286         {
287             result.setMemberAccess( memberAccess );
288         }
289 
290         result.setRoot( root );
291         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         context.put( OgnlContext.CLASS_RESOLVER_CONTEXT_KEY, classResolver );
304     }
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         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         context.put( OgnlContext.TYPE_CONVERTER_CONTEXT_KEY, converter );
327     }
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         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         context.put( OgnlContext.MEMBER_ACCESS_CONTEXT_KEY, memberAccess );
350     }
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         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         context.put( OgnlContext.ROOT_CONTEXT_KEY, root );
373     }
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         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         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         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         OgnlContext ognlContext = (OgnlContext) addDefaultContext( root, context );
436 
437         Node node = (Node) tree;
438 
439         if ( node.getAccessor() != null )
440         {
441             result = (T) node.getAccessor().get( ognlContext, root );
442         }
443         else
444         {
445             result = (T) node.getValue( ognlContext, root );
446         }
447 
448         if ( resultType != null )
449         {
450             result = getTypeConverter( context ).convertValue( context, root, null, null, result, resultType );
451         }
452         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         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         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         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         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         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         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         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         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         OgnlContext ognlContext = (OgnlContext) addDefaultContext( root, context );
620         Node n = (Node) tree;
621 
622         if ( n.getAccessor() != null )
623         {
624             n.getAccessor().set( ognlContext, root, value );
625             return;
626         }
627 
628         n.setValue( ognlContext, root, value );
629     }
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         expression.set( context, root, value );
642     }
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         setValue( parseExpression( expression ), context, root, value );
661     }
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         setValue( tree, createDefaultContext( root ), root, value );
678     }
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         setValue( parseExpression( expression ), root, value );
698     }
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         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         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         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         return isConstant( parseExpression( expression ), createDefaultContext( null ) );
752     }
753 
754     public static boolean isSimpleProperty( Object tree, Map<String, Object> context )
755         throws OgnlException
756     {
757         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         return isSimpleProperty( parseExpression( expression ), context );
764     }
765 
766     public static boolean isSimpleProperty( Object tree )
767         throws OgnlException
768     {
769         return isSimpleProperty( tree, createDefaultContext( null ) );
770     }
771 
772     public static boolean isSimpleProperty( String expression )
773         throws OgnlException
774     {
775         return isSimpleProperty( parseExpression( expression ), createDefaultContext( null ) );
776     }
777 
778     public static boolean isSimpleNavigationChain( Object tree, Map<String, Object> context )
779         throws OgnlException
780     {
781         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         return isSimpleNavigationChain( parseExpression( expression ), context );
788     }
789 
790     public static boolean isSimpleNavigationChain( Object tree )
791         throws OgnlException
792     {
793         return isSimpleNavigationChain( tree, createDefaultContext( null ) );
794     }
795 
796     public static boolean isSimpleNavigationChain( String expression )
797         throws OgnlException
798     {
799         return isSimpleNavigationChain( parseExpression( expression ), createDefaultContext( null ) );
800     }
801 
802     /** You can't make one of these. */
803     private Ognl()
804     {
805     }
806 }