1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
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
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
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 }