1 package org.apache.commons.ognl;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.commons.ognl.enhance.ExpressionAccessor;
23
24 import java.io.PrintWriter;
25 import java.io.Serializable;
26
27
28
29
30
31 public abstract class SimpleNode
32 implements Node, Serializable
33 {
34
35 private static final long serialVersionUID = 8305393337889433901L;
36
37 protected Node parent;
38
39 protected Node[] children;
40
41 protected int id;
42
43 protected OgnlParser parser;
44
45 private boolean constantValueCalculated;
46
47 private volatile boolean hasConstantValue;
48
49 private Object constantValue;
50
51 private ExpressionAccessor accessor;
52
53 public SimpleNode( int i )
54 {
55 id = i;
56 }
57
58 public SimpleNode( OgnlParser p, int i )
59 {
60 this( i );
61 parser = p;
62 }
63
64 public void jjtOpen()
65 {
66 }
67
68 public void jjtClose()
69 {
70 }
71
72 public void jjtSetParent( Node n )
73 {
74 parent = n;
75 }
76
77 public Node jjtGetParent()
78 {
79 return parent;
80 }
81
82 public void jjtAddChild( Node n, int i )
83 {
84 if ( children == null )
85 {
86 children = new Node[i + 1];
87 }
88 else if ( i >= children.length )
89 {
90 Node c[] = new Node[i + 1];
91 System.arraycopy( children, 0, c, 0, children.length );
92 children = c;
93 }
94 children[i] = n;
95 }
96
97 public Node jjtGetChild( int i )
98 {
99 return children[i];
100 }
101
102 public int jjtGetNumChildren()
103 {
104 return ( children == null ) ? 0 : children.length;
105 }
106
107
108
109
110
111
112
113 @Override
114 public String toString()
115 {
116 final StringBuilder data = new StringBuilder();
117 try
118 {
119 accept( ToStringVisitor.INSTANCE, data );
120 }
121 catch ( OgnlException e )
122 {
123
124 }
125 return data.toString();
126 }
127
128
129
130 public String toString( String prefix )
131 {
132 return prefix + OgnlParserTreeConstants.jjtNodeName[id] + " " + toString();
133 }
134
135 public String toGetSourceString( OgnlContext context, Object target )
136 {
137 return toString();
138 }
139
140 public String toSetSourceString( OgnlContext context, Object target )
141 {
142 return toString();
143 }
144
145
146
147
148
149 public void dump( PrintWriter writer, String prefix )
150 {
151 writer.println( toString( prefix ) );
152
153 if ( children != null )
154 {
155 for ( int i = 0; i < children.length; ++i )
156 {
157 SimpleNode n = (SimpleNode) children[i];
158 if ( n != null )
159 {
160 n.dump( writer, prefix + " " );
161 }
162 }
163 }
164 }
165
166 public int getIndexInParent()
167 {
168 int result = -1;
169
170 if ( parent != null )
171 {
172 int icount = parent.jjtGetNumChildren();
173
174 for ( int i = 0; i < icount; i++ )
175 {
176 if ( parent.jjtGetChild( i ) == this )
177 {
178 result = i;
179 break;
180 }
181 }
182 }
183
184 return result;
185 }
186
187 public Node getNextSibling()
188 {
189 Node result = null;
190 int i = getIndexInParent();
191
192 if ( i >= 0 )
193 {
194 int icount = parent.jjtGetNumChildren();
195
196 if ( i < icount )
197 {
198 result = parent.jjtGetChild( i + 1 );
199 }
200 }
201 return result;
202 }
203
204 protected Object evaluateGetValueBody( OgnlContext context, Object source )
205 throws OgnlException
206 {
207 context.setCurrentObject( source );
208 context.setCurrentNode( this );
209
210 if ( !constantValueCalculated )
211 {
212 constantValueCalculated = true;
213 boolean constant = isConstant( context );
214
215 if ( constant )
216 {
217 constantValue = getValueBody( context, source );
218 }
219
220 hasConstantValue = constant;
221 }
222
223 return hasConstantValue ? constantValue : getValueBody( context, source );
224 }
225
226 protected void evaluateSetValueBody( OgnlContext context, Object target, Object value )
227 throws OgnlException
228 {
229 context.setCurrentObject( target );
230 context.setCurrentNode( this );
231 setValueBody( context, target, value );
232 }
233
234 public final Object getValue( OgnlContext context, Object source )
235 throws OgnlException
236 {
237 Object result = null;
238
239 if ( context.getTraceEvaluations() )
240 {
241
242 EvaluationPool pool = OgnlRuntime.getEvaluationPool();
243 Throwable evalException = null;
244 Evaluation evaluation = pool.create( this, source );
245
246 context.pushEvaluation( evaluation );
247 try
248 {
249 result = evaluateGetValueBody( context, source );
250 }
251 catch ( OgnlException ex )
252 {
253 evalException = ex;
254 throw ex;
255 }
256 catch ( RuntimeException ex )
257 {
258 evalException = ex;
259 throw ex;
260 }
261 finally
262 {
263 Evaluation eval = context.popEvaluation();
264
265 eval.setResult( result );
266 if ( evalException != null )
267 {
268 eval.setException( evalException );
269 }
270 if ( ( evalException == null ) && ( context.getRootEvaluation() == null )
271 && !context.getKeepLastEvaluation() )
272 {
273 pool.recycleAll( eval );
274 }
275 }
276 }
277 else
278 {
279 result = evaluateGetValueBody( context, source );
280 }
281
282 return result;
283 }
284
285
286
287
288
289 protected abstract Object getValueBody( OgnlContext context, Object source )
290 throws OgnlException;
291
292 public final void setValue( OgnlContext context, Object target, Object value )
293 throws OgnlException
294 {
295 if ( context.getTraceEvaluations() )
296 {
297 EvaluationPool pool = OgnlRuntime.getEvaluationPool();
298 Throwable evalException = null;
299 Evaluation evaluation = pool.create( this, target, true );
300
301 context.pushEvaluation( evaluation );
302 try
303 {
304 evaluateSetValueBody( context, target, value );
305 }
306 catch ( OgnlException ex )
307 {
308 evalException = ex;
309 ex.setEvaluation( evaluation );
310 throw ex;
311 }
312 catch ( RuntimeException ex )
313 {
314 evalException = ex;
315 throw ex;
316 }
317 finally
318 {
319 Evaluation eval = context.popEvaluation();
320
321 if ( evalException != null )
322 {
323 eval.setException( evalException );
324 }
325 if ( ( evalException == null ) && ( context.getRootEvaluation() == null )
326 && !context.getKeepLastEvaluation() )
327 {
328 pool.recycleAll( eval );
329 }
330 }
331 }
332 else
333 {
334 evaluateSetValueBody( context, target, value );
335 }
336 }
337
338
339
340
341
342
343 protected void setValueBody( OgnlContext context, Object target, Object value )
344 throws OgnlException
345 {
346 throw new InappropriateExpressionException( this );
347 }
348
349
350 public boolean isNodeConstant( OgnlContext context )
351 throws OgnlException
352 {
353 return false;
354 }
355
356 public boolean isConstant( OgnlContext context )
357 throws OgnlException
358 {
359 return isNodeConstant( context );
360 }
361
362 public boolean isNodeSimpleProperty( OgnlContext context )
363 throws OgnlException
364 {
365 return false;
366 }
367
368 public boolean isSimpleProperty( OgnlContext context )
369 throws OgnlException
370 {
371 return isNodeSimpleProperty( context );
372 }
373
374 public boolean isSimpleNavigationChain( OgnlContext context )
375 throws OgnlException
376 {
377 return isSimpleProperty( context );
378 }
379
380 public boolean isEvalChain( OgnlContext context )
381 throws OgnlException
382 {
383 if ( children == null )
384 {
385 return false;
386 }
387 for ( Node child : children )
388 {
389 if ( child instanceof SimpleNode )
390 {
391 if ( ( (SimpleNode) child ).isEvalChain( context ) )
392 {
393 return true;
394 }
395 }
396 }
397 return false;
398 }
399
400 protected boolean lastChild( OgnlContext context )
401 {
402 return parent == null || context.get( "_lastChild" ) != null;
403 }
404
405
406
407
408
409 protected void flattenTree()
410 {
411 boolean shouldFlatten = false;
412 int newSize = 0;
413
414 for ( Node aChildren : children )
415 {
416 if ( aChildren.getClass() == getClass() )
417 {
418 shouldFlatten = true;
419 newSize += aChildren.jjtGetNumChildren();
420 }
421 else
422 {
423 ++newSize;
424 }
425 }
426
427 if ( shouldFlatten )
428 {
429 Node[] newChildren = new Node[newSize];
430 int j = 0;
431
432 for ( Node c : children )
433 {
434 if ( c.getClass() == getClass() )
435 {
436 for ( int k = 0; k < c.jjtGetNumChildren(); ++k )
437 {
438 newChildren[j++] = c.jjtGetChild( k );
439 }
440
441 }
442 else
443 {
444 newChildren[j++] = c;
445 }
446 }
447
448 if ( j != newSize )
449 {
450 throw new Error( "Assertion error: " + j + " != " + newSize );
451 }
452
453 children = newChildren;
454 }
455 }
456
457 public ExpressionAccessor getAccessor()
458 {
459 return accessor;
460 }
461
462 public void setAccessor( ExpressionAccessor accessor )
463 {
464 this.accessor = accessor;
465 }
466 }