View Javadoc

1   /*
2    * Copyright 2002,2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.apache.commons.jexl;
18  
19  import java.util.ArrayList;
20  import java.util.List;
21  
22  import org.apache.commons.jexl.parser.SimpleNode;
23  
24  /***
25   * Instances of ExpressionImpl are created by the {@link ExpressionFactory},
26   * and this is the default implementation of the {@link Expression} interface.
27   *
28   *  @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
29   *  @version $Id: ExpressionImpl.java,v 1.11 2004/08/23 14:00:11 dion Exp $
30   */
31  class ExpressionImpl implements Expression
32  {
33  
34      protected List preResolvers;
35      protected List postResolvers;
36  
37      /***
38       *  Original expression - this is just a 'snippet', not a valid
39       *  statement (i.e.  foo.bar() vs foo.bar();
40       */
41      protected String expression;
42  
43      /***
44       *  The resulting AST we can call value() on
45       */
46      protected SimpleNode node;
47  
48      /***
49       *  do not let this be generally instantiated with a 'new'
50       */
51      ExpressionImpl(String expr, SimpleNode ref)
52      {
53          expression = expr;
54          node = ref;
55      }
56  
57      /***
58       *  Evaluate the expression and return the value.
59       *
60       * Before JEXL evaluates the expression, any pre-resolvers will be called.
61       * If the pre-resolver provides a value, it is returned.
62       * If JEXL evaluates the expression as null, post-resolvers are called
63       * and any resulting value returned.
64       *
65       *  @param context Context containing objects/data used for evaluation
66       *  @return value of expression
67       */
68      public Object evaluate(JexlContext context)
69          throws Exception
70      {
71          Object val = null;
72  
73          /*
74           * if we have pre resolvers, give them a wack
75           */
76          if (preResolvers != null)
77          {
78              val = tryResolver(preResolvers, context);
79  
80              if (val != JexlExprResolver.NO_VALUE)
81              {
82                  return val;
83              }
84          }
85  
86          val = node.value(context);
87  
88          /*
89           * if null, call post resolvers
90           */
91          if (val == null && postResolvers != null)
92          {
93              val = tryResolver(postResolvers, context);
94  
95              if (val != JexlExprResolver.NO_VALUE)
96              {
97                  return val;
98              }
99          }
100 
101         return val;
102     }
103 
104     /***
105      *  Tries the resolvers in the given resolverlist against the context
106      *
107      *  @param resolverList list of JexlExprResolvers
108      *  @param context JexlContext to use for evauluation
109      *  @return value (including null) or JexlExprResolver.NO_VALUE
110      */
111     protected Object tryResolver(List resolverList, JexlContext context)
112     {
113         Object val = JexlExprResolver.NO_VALUE;
114         String expr = getExpression();
115 
116         for (int i = 0; i < resolverList.size(); i++)
117         {
118             JexlExprResolver jer = (JexlExprResolver) resolverList.get(i);
119 
120             val = jer.evaluate(context, expr);
121 
122             /*
123             * as long as it's not NO_VALUE, return it
124             */
125             if (val != JexlExprResolver.NO_VALUE)
126             {
127                return val;
128             }
129         }
130 
131         return val;
132     }
133 
134     /***
135      *  returns original expression string
136      */
137     public String getExpression()
138     {
139         return expression;
140     }
141 
142     public void addPreResolver(JexlExprResolver resolver)
143     {
144         if (preResolvers == null) 
145         {
146             preResolvers = new ArrayList();
147         }
148         preResolvers.add(resolver);
149     }
150 
151     /***
152      *  allows addition of a resolver to allow custom interdiction of
153      *  expression evaluation
154      *
155      *  @param resolver resolver to be called if Jexl expression evaluated to null
156      */
157     public void addPostResolver(JexlExprResolver resolver)
158     {
159         if (postResolvers == null) 
160         {
161             postResolvers = new ArrayList();
162         }
163         postResolvers.add(resolver);
164     }
165 
166 }