2009/05/20 - Apache Shale has been retired.
For more information, please explore the Attic.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shale.test.el;
19
20 import java.util.ArrayList;
21 import java.util.List;
22 import javax.el.ELContext;
23 import javax.el.ELResolver;
24 import javax.el.ValueExpression;
25 import javax.faces.context.FacesContext;
26
27 /***
28 * <p>Mock implementation of <code>ValueExpression</code>.</p>
29 *
30 * <p>This implementation supports a limited subset of overall expression functionality:</p>
31 * <ul>
32 * <li>A literal string that contains no expression delimiters.</li>
33 * <li>An expression that starts with "#{" or "${", and ends with "}".</li>
34 * </ul>
35 */
36 public class MockValueExpression extends ValueExpression {
37
38
39
40
41
42 /***
43 * Serial version UID.
44 */
45 private static final long serialVersionUID = -8649071428507512623L;
46
47
48 /***
49 * <p>Construct a new expression for the specified expression string.</p>
50 *
51 * @param expression Expression string to be evaluated
52 * @param expectedType Expected type of the result
53 */
54 public MockValueExpression(String expression, Class expectedType) {
55
56 if (expression == null) {
57 throw new NullPointerException("Expression string cannot be null");
58 }
59 this.expression = expression;
60 this.expectedType = expectedType;
61 parse();
62
63 }
64
65
66
67
68
69 /***
70 * <p>The parsed elements of this expression.</p>
71 */
72 private String[] elements = null;
73
74
75 /***
76 * <p>The expected result type for <code>getValue()</code> calls.</p>
77 */
78 private Class expectedType = null;
79
80
81 /***
82 * <p>The original expression string used to create this expression.</p>
83 */
84 private String expression = null;
85
86
87
88
89
90 /***
91 * <p>Return <code>true</code> if this expression is equal to the
92 * specified expression.</p>
93 *
94 * @param obj Object to be compared
95 */
96 public boolean equals(Object obj) {
97
98 if ((obj != null) & (obj instanceof ValueExpression)) {
99 return expression.equals(((ValueExpression) obj).getExpressionString());
100 } else {
101 return false;
102 }
103
104 }
105
106
107 /***
108 * <p>Return the original String used to create this expression,
109 * unmodified.</p>
110 */
111 public String getExpressionString() {
112
113 return this.expression;
114
115 }
116
117
118 /***
119 * <p>Return the hash code for this expression.</p>
120 */
121 public int hashCode() {
122
123 return this.expression.hashCode();
124
125 }
126
127
128 /***
129 * <p>Return <code>true</code> if the expression string for this expression
130 * contains only literal text.</p>
131 */
132 public boolean isLiteralText() {
133
134 return (expression.indexOf("${") < 0) && (expression.indexOf("#{") < 0);
135
136 }
137
138
139
140
141
142 /***
143 * <p>Return the type that the result of this expression will
144 * be coerced to.</p>
145 */
146 public Class getExpectedType() {
147
148 return this.expectedType;
149
150 }
151
152
153 /***
154 * <p>Evaluate this expression relative to the specified context,
155 * and return the most general type that is acceptable for the
156 * value passed in a <code>setValue()</code> call.</p>
157 *
158 * @param context ELContext for this evaluation
159 */
160 public Class getType(ELContext context) {
161
162 if (context == null) {
163 throw new NullPointerException();
164 }
165 Object value = getValue(context);
166 if (value == null) {
167 return null;
168 } else {
169 return value.getClass();
170 }
171
172 }
173
174
175 /***
176 * <p>Evaluate this expression relative to the specified context,
177 * and return the result.</p>
178 *
179 * @param context ELContext for this evaluation
180 */
181 public Object getValue(ELContext context) {
182
183 if (context == null) {
184 throw new NullPointerException();
185 }
186 if (isLiteralText()) {
187 return expression;
188 }
189
190 FacesContext fcontext = (FacesContext) context.getContext(FacesContext.class);
191 ELResolver resolver = fcontext.getApplication().getELResolver();
192 Object base = null;
193 for (int i = 0; i < elements.length; i++) {
194 base = resolver.getValue(context, base, elements[i]);
195 }
196 return fcontext.getApplication().getExpressionFactory().coerceToType(base, getExpectedType());
197
198 }
199
200
201 /***
202 * <p>Evaluate this expression relative to the specified context,
203 * and return <code>true</code> if a call to <code>setValue()</code>
204 * will always fail.</p>
205 *
206 * @param context ELContext for this evaluation
207 */
208 public boolean isReadOnly(ELContext context) {
209
210 if (context == null) {
211 throw new NullPointerException();
212 }
213 if (isLiteralText()) {
214 return true;
215 }
216
217 FacesContext fcontext = (FacesContext) context.getContext(FacesContext.class);
218 ELResolver resolver = fcontext.getApplication().getELResolver();
219 Object base = null;
220 for (int i = 0; i < elements.length - 1; i++) {
221 base = resolver.getValue(context, base, elements[i]);
222 }
223 return resolver.isReadOnly(context, base, elements[elements.length - 1]);
224
225 }
226
227
228
229 /***
230 * <p>Evaluate this expression relative to the specified context,
231 * and set the result to the specified value.</p>
232 *
233 * @param context ELContext for this evaluation
234 * @param value Value to which the result should be set
235 */
236 public void setValue(ELContext context, Object value) {
237
238 if (context == null) {
239 throw new NullPointerException();
240 }
241
242 FacesContext fcontext = (FacesContext) context.getContext(FacesContext.class);
243 ELResolver resolver = fcontext.getApplication().getELResolver();
244 Object base = null;
245 for (int i = 0; i < elements.length - 1; i++) {
246 base = resolver.getValue(context, base, elements[i]);
247 }
248 resolver.setValue(context, base, elements[elements.length - 1], value);
249
250 }
251
252
253
254
255
256 /***
257 * <p>Parse the expression string into its constituent elemetns.</p>
258 */
259 private void parse() {
260
261 if (isLiteralText()) {
262 elements = new String[0];
263 return;
264 }
265
266 if (expression.startsWith("${") || expression.startsWith("#{")) {
267 if (expression.endsWith("}")) {
268 List names = new ArrayList();
269 StringBuffer expr = new StringBuffer(expression.substring(2, expression.length() - 1).replaceAll(" ", ""));
270 boolean isBlockOn = false;
271 for (int i = expr.length() - 1; i > -1; i--) {
272 if (expr.charAt(i) == ' ') {
273 expr.deleteCharAt(i);
274 } else if (expr.charAt(i) == ']') {
275 expr.deleteCharAt(i);
276 } else if (expr.charAt(i) == '[') {
277 expr.deleteCharAt(i);
278 } else if (expr.charAt(i) == '\'') {
279 if (!isBlockOn) {
280 expr.deleteCharAt(i);
281 } else {
282 names.add(0, expr.substring(i + 1));
283 expr.delete(i, expr.length());
284 }
285 isBlockOn = !isBlockOn;
286 } else if (expr.charAt(i) == '.' && !isBlockOn) {
287 names.add(0, expr.substring(i + 1));
288 expr.delete(i, expr.length());
289 }
290 }
291 if (expr.length() > 0) {
292 names.add(0, expr.toString());
293 }
294
295 elements = (String[]) names.toArray(new String[names.size()]);
296 } else {
297 throw new IllegalArgumentException(expression);
298 }
299 } else {
300 throw new IllegalArgumentException(expression);
301 }
302
303 }
304
305
306 }