1 package org.apache.velocity.runtime.directive;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.BufferedReader;
23 import java.io.StringReader;
24 import java.io.StringWriter;
25
26 import org.apache.velocity.VelocityContext;
27 import org.apache.velocity.context.InternalContextAdapter;
28 import org.apache.velocity.context.InternalContextAdapterImpl;
29 import org.apache.velocity.exception.MethodInvocationException;
30 import org.apache.velocity.runtime.RuntimeServices;
31 import org.apache.velocity.runtime.log.Log;
32 import org.apache.velocity.runtime.parser.ParserTreeConstants;
33 import org.apache.velocity.runtime.parser.node.ASTReference;
34 import org.apache.velocity.runtime.parser.node.SimpleNode;
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81 public class VMProxyArg
82 {
83
84 private static final int GENERALSTATIC = -1;
85
86
87 private int type = 0;
88
89
90 private SimpleNode nodeTree = null;
91
92
93 private Object staticObject = null;
94
95
96 private int numTreeChildren = 0;
97
98
99 private String contextReference = null;
100
101
102 private String callerReference = null;
103
104
105 private String singleLevelRef = null;
106
107
108 private boolean constant = false;
109
110 private RuntimeServices rsvc = null;
111 private Log log = null;
112
113
114
115
116
117
118
119
120
121
122
123
124 public VMProxyArg( RuntimeServices rs, String contextRef, String callerRef, int t )
125 {
126 rsvc = rs;
127 log = rsvc.getLog();
128
129 contextReference = contextRef;
130 callerReference = callerRef;
131 type = t;
132
133
134
135
136 setup();
137
138
139
140
141
142 if( nodeTree != null)
143 {
144 numTreeChildren = nodeTree.jjtGetNumChildren();
145 }
146
147
148
149
150
151
152 if ( type == ParserTreeConstants.JJTREFERENCE )
153 {
154 if ( numTreeChildren == 0)
155 {
156
157
158
159 singleLevelRef = ((ASTReference) nodeTree).getRootString();
160 }
161 }
162 }
163
164
165
166
167
168
169
170 public boolean isConstant()
171 {
172 return constant;
173 }
174
175
176
177
178
179
180
181
182 public Object setObject( InternalContextAdapter context, Object o )
183 {
184
185
186
187
188 if( type == ParserTreeConstants.JJTREFERENCE )
189 {
190 if( numTreeChildren > 0)
191 {
192
193
194
195
196
197 try
198 {
199 ( (ASTReference) nodeTree).setValue( context, o );
200 }
201 catch( MethodInvocationException mie )
202 {
203 log.error("VMProxyArg.getObject() : method invocation error setting value", mie);
204 }
205 }
206 else
207 {
208
209
210
211
212
213 context.put( singleLevelRef, o);
214
215
216 }
217 }
218 else
219 {
220
221
222
223
224
225
226
227 type = GENERALSTATIC;
228 staticObject = o;
229
230 log.error("VMProxyArg.setObject() : Programmer error : I am a constant! No setting! : "
231 + contextReference + " / " + callerReference);
232 }
233
234 return null;
235 }
236
237
238
239
240
241
242
243
244
245
246
247 public Object getObject( InternalContextAdapter context ) throws MethodInvocationException
248 {
249 try
250 {
251
252
253
254
255
256 Object retObject = null;
257
258 if ( type == ParserTreeConstants.JJTREFERENCE )
259 {
260
261
262
263
264 if ( numTreeChildren == 0)
265 {
266
267
268
269
270 retObject = context.get( singleLevelRef );
271 }
272 else
273 {
274
275
276
277
278 retObject = nodeTree.execute( null, context);
279 }
280 }
281 else if (type == ParserTreeConstants.JJTMAP)
282 {
283 retObject = nodeTree.value(context);
284 }
285 else if( type == ParserTreeConstants.JJTOBJECTARRAY )
286 {
287 retObject = nodeTree.value( context );
288 }
289 else if ( type == ParserTreeConstants.JJTINTEGERRANGE)
290 {
291 retObject = nodeTree.value( context );
292 }
293 else if( type == ParserTreeConstants.JJTTRUE )
294 {
295 retObject = staticObject;
296 }
297 else if ( type == ParserTreeConstants.JJTFALSE )
298 {
299 retObject = staticObject;
300 }
301 else if ( type == ParserTreeConstants.JJTSTRINGLITERAL )
302 {
303 retObject = nodeTree.value( context );
304 }
305 else if ( type == ParserTreeConstants.JJTINTEGERLITERAL )
306 {
307 retObject = staticObject;
308 }
309 else if ( type == ParserTreeConstants.JJTFLOATINGPOINTLITERAL )
310 {
311 retObject = staticObject;
312 }
313 else if ( type == ParserTreeConstants.JJTTEXT )
314 {
315
316
317
318
319 try
320 {
321 StringWriter writer =new StringWriter();
322 nodeTree.render( context, writer );
323
324 retObject = writer;
325 }
326
327
328
329 catch( RuntimeException e )
330 {
331 throw e;
332 }
333 catch (Exception e )
334 {
335 log.error("VMProxyArg.getObject() : error rendering reference", e);
336 }
337 }
338 else if( type == GENERALSTATIC )
339 {
340 retObject = staticObject;
341 }
342 else
343 {
344 log.error("Unsupported VM arg type : VM arg = " +
345 callerReference +" type = " + type +
346 "( VMProxyArg.getObject() )");
347 }
348
349 return retObject;
350 }
351 catch( MethodInvocationException mie )
352 {
353
354
355
356
357
358
359
360 log.error("VMProxyArg.getObject() : method invocation error getting value", mie);
361 throw mie;
362 }
363 }
364
365
366
367
368
369
370 private void setup()
371 {
372 switch( type )
373 {
374
375 case ParserTreeConstants.JJTINTEGERRANGE :
376 case ParserTreeConstants.JJTREFERENCE :
377 case ParserTreeConstants.JJTOBJECTARRAY :
378 case ParserTreeConstants.JJTMAP :
379 case ParserTreeConstants.JJTSTRINGLITERAL :
380 case ParserTreeConstants.JJTTEXT :
381 {
382
383
384
385
386 constant = false;
387
388 try
389 {
390
391
392
393
394
395
396
397 String buff ="#include(" + callerReference + " ) ";
398
399
400
401 BufferedReader br = new BufferedReader( new StringReader( buff ) );
402
403 nodeTree = rsvc.parse(br, "VMProxyArg:" + callerReference, true);
404
405
406
407
408
409 nodeTree = (SimpleNode) nodeTree.jjtGetChild(0).jjtGetChild(0);
410
411
412
413
414 if ( nodeTree != null)
415 {
416 if(nodeTree.getType() != type)
417 {
418 log.error("VMProxyArg.setup() : programmer error : type doesn't match node type.");
419 }
420
421
422
423
424
425 InternalContextAdapter ica
426 = new InternalContextAdapterImpl(new VelocityContext());
427
428 ica.pushCurrentTemplateName("VMProxyArg : "
429 + ParserTreeConstants.jjtNodeName[type]);
430
431 nodeTree.init(ica, rsvc);
432 }
433 }
434
435
436
437 catch( RuntimeException e )
438 {
439 throw e;
440 }
441 catch ( Exception e )
442 {
443 log.error("VMProxyArg.setup() : exception " +
444 callerReference, e);
445 }
446
447 break;
448 }
449
450 case ParserTreeConstants.JJTTRUE :
451 {
452 constant = true;
453 staticObject = Boolean.TRUE;
454 break;
455 }
456
457 case ParserTreeConstants.JJTFALSE :
458 {
459 constant = true;
460 staticObject = Boolean.FALSE;
461 break;
462 }
463
464 case ParserTreeConstants.JJTINTEGERLITERAL :
465 {
466 constant = true;
467 staticObject = new Integer(callerReference);
468 break;
469 }
470
471 case ParserTreeConstants.JJTFLOATINGPOINTLITERAL :
472 {
473 constant = true;
474 staticObject = new Double(callerReference);
475 break;
476 }
477
478 case ParserTreeConstants.JJTWORD :
479 {
480
481
482
483
484 log.error("Unsupported arg type : " + callerReference +
485 " You most likely intended to call a VM with a string literal, so enclose with ' or \" characters. (VMProxyArg.setup())");
486 constant = true;
487 staticObject = callerReference;
488
489 break;
490 }
491
492 default :
493 {
494 log.error("VMProxyArg.setup() : unsupported type : "
495 + callerReference );
496 }
497 }
498 }
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515 public VMProxyArg( VMProxyArg model, InternalContextAdapter c )
516 {
517 contextReference = model.getContextReference();
518 callerReference = model.getCallerReference();
519 nodeTree = model.getNodeTree();
520 staticObject = model.getStaticObject();
521 type = model.getType();
522
523 if( nodeTree != null)
524 numTreeChildren = nodeTree.jjtGetNumChildren();
525
526 if ( type == ParserTreeConstants.JJTREFERENCE )
527 {
528 if ( numTreeChildren == 0)
529 {
530
531
532
533 singleLevelRef = ((ASTReference) nodeTree).getRootString();
534 }
535 }
536 }
537
538
539
540
541 public String getCallerReference()
542 {
543 return callerReference;
544 }
545
546
547
548
549 public String getContextReference()
550 {
551 return contextReference;
552 }
553
554
555
556
557 public SimpleNode getNodeTree()
558 {
559 return nodeTree;
560 }
561
562
563
564
565 public Object getStaticObject()
566 {
567 return staticObject;
568 }
569
570
571
572
573 public int getType()
574 {
575 return type;
576 }
577 }