1 package org.apache.velocity.runtime.directive; 2 3 18 19 import java.io.StringWriter ; 20 import java.io.StringReader ; 21 import java.io.BufferedReader ; 22 23 import org.apache.velocity.context.InternalContextAdapter; 24 import org.apache.velocity.context.InternalContextAdapterImpl; 25 import org.apache.velocity.runtime.RuntimeServices; 26 import org.apache.velocity.runtime.parser.node.ASTReference; 27 import org.apache.velocity.runtime.parser.ParserTreeConstants; 28 import org.apache.velocity.runtime.parser.node.SimpleNode; 29 import org.apache.velocity.util.StringUtils; 30 31 import org.apache.velocity.exception.MethodInvocationException; 32 import org.apache.velocity.VelocityContext; 33 34 78 public class VMProxyArg 79 { 80 81 private int type = 0; 82 83 84 private SimpleNode nodeTree = null; 85 86 87 private Object staticObject = null; 88 89 90 private InternalContextAdapter usercontext = null; 91 92 93 private int numTreeChildren = 0; 94 95 96 private String contextReference = null; 97 98 99 private String callerReference = null; 100 101 102 private String singleLevelRef = null; 103 104 105 private boolean constant = false; 106 107 108 private final int GENERALSTATIC = -1; 109 110 private RuntimeServices rsvc = null; 111 112 122 public VMProxyArg( RuntimeServices rs, String contextRef, String callerRef, int t ) 123 { 124 rsvc = rs; 125 126 contextReference = contextRef; 127 callerReference = callerRef; 128 type = t; 129 130 133 setup(); 134 135 139 if( nodeTree != null) 140 numTreeChildren = nodeTree.jjtGetNumChildren(); 141 142 147 if ( type == ParserTreeConstants.JJTREFERENCE ) 148 { 149 if ( numTreeChildren == 0) 150 { 151 154 singleLevelRef = ((ASTReference) nodeTree).getRootString(); 155 } 156 } 157 } 158 159 165 public boolean isConstant() 166 { 167 return constant; 168 } 169 170 177 public Object setObject( InternalContextAdapter context, Object o ) 178 { 179 182 183 if( type == ParserTreeConstants.JJTREFERENCE ) 184 { 185 if( numTreeChildren > 0) 186 { 187 191 192 try 193 { 194 ( (ASTReference) nodeTree).setValue( context, o ); 195 } 196 catch( MethodInvocationException mie ) 197 { 198 rsvc.error("VMProxyArg.getObject() : method invocation error setting value : " + mie ); 199 } 200 } 201 else 202 { 203 207 208 context.put( singleLevelRef, o); 209 210 } 212 } 213 else 214 { 215 221 222 type = GENERALSTATIC; 223 staticObject = o; 224 225 rsvc.error("VMProxyArg.setObject() : Programmer error : I am a constant! No setting! : " 226 + contextReference + " / " + callerReference); 227 } 228 229 return null; 230 } 231 232 233 242 public Object getObject( InternalContextAdapter context ) 243 { 244 try 245 { 246 247 250 251 Object retObject = null; 252 253 if ( type == ParserTreeConstants.JJTREFERENCE ) 254 { 255 258 259 if ( numTreeChildren == 0) 260 { 261 264 265 retObject = context.get( singleLevelRef ); 266 } 267 else 268 { 269 272 273 retObject = nodeTree.execute( null, context); 274 } 275 } 276 else if( type == ParserTreeConstants.JJTOBJECTARRAY ) 277 { 278 retObject = nodeTree.value( context ); 279 } 280 else if ( type == ParserTreeConstants.JJTINTEGERRANGE) 281 { 282 retObject = nodeTree.value( context ); 283 } 284 else if( type == ParserTreeConstants.JJTTRUE ) 285 { 286 retObject = staticObject; 287 } 288 else if ( type == ParserTreeConstants.JJTFALSE ) 289 { 290 retObject = staticObject; 291 } 292 else if ( type == ParserTreeConstants.JJTSTRINGLITERAL ) 293 { 294 retObject = nodeTree.value( context ); 295 } 296 else if ( type == ParserTreeConstants.JJTNUMBERLITERAL ) 297 { 298 retObject = staticObject; 299 } 300 else if ( type == ParserTreeConstants.JJTTEXT ) 301 { 302 305 306 try 307 { 308 StringWriter writer =new StringWriter (); 309 nodeTree.render( context, writer ); 310 311 retObject = writer; 312 } 313 catch (Exception e ) 314 { 315 rsvc.error("VMProxyArg.getObject() : error rendering reference : " + e ); 316 } 317 } 318 else if( type == GENERALSTATIC ) 319 { 320 retObject = staticObject; 321 } 322 else 323 { 324 rsvc.error("Unsupported VM arg type : VM arg = " + callerReference +" type = " + type + "( VMProxyArg.getObject() )"); 325 } 326 327 return retObject; 328 } 329 catch( MethodInvocationException mie ) 330 { 331 337 338 rsvc.error("VMProxyArg.getObject() : method invocation error getting value : " + mie ); 339 340 return null; 341 } 342 } 343 344 349 private void setup() 350 { 351 switch( type ) { 352 353 case ParserTreeConstants.JJTINTEGERRANGE : 354 case ParserTreeConstants.JJTREFERENCE : 355 case ParserTreeConstants.JJTOBJECTARRAY : 356 case ParserTreeConstants.JJTSTRINGLITERAL : 357 case ParserTreeConstants.JJTTEXT : 358 { 359 362 363 constant = false; 364 365 try 366 { 367 373 374 String buff ="#include(" + callerReference + " ) "; 375 376 378 BufferedReader br = new BufferedReader ( new StringReader ( buff ) ); 379 380 nodeTree = rsvc.parse(br, "VMProxyArg:" + callerReference, true); 381 382 385 386 nodeTree = (SimpleNode) nodeTree.jjtGetChild(0).jjtGetChild(0); 387 388 391 392 if ( nodeTree != null && nodeTree.getType() != type ) 393 { 394 rsvc.error( "VMProxyArg.setup() : programmer error : type doesn't match node type."); 395 } 396 397 400 401 InternalContextAdapter ica 402 = new InternalContextAdapterImpl(new VelocityContext()); 403 404 ica.pushCurrentTemplateName("VMProxyArg : " 405 + ParserTreeConstants.jjtNodeName[type]); 406 407 nodeTree.init(ica, rsvc); 408 } 409 catch ( Exception e ) 410 { 411 rsvc.error("VMProxyArg.setup() : exception " + callerReference + 412 " : " + StringUtils.stackTrace(e)); 413 } 414 415 break; 416 } 417 418 case ParserTreeConstants.JJTTRUE : 419 { 420 constant = true; 421 staticObject = new Boolean (true); 422 break; 423 } 424 425 case ParserTreeConstants.JJTFALSE : 426 { 427 constant = true; 428 staticObject = new Boolean (false); 429 break; 430 } 431 432 case ParserTreeConstants.JJTNUMBERLITERAL : 433 { 434 constant = true; 435 staticObject = new Integer (callerReference); 436 break; 437 } 438 439 case ParserTreeConstants.JJTWORD : 440 { 441 444 445 rsvc.error("Unsupported arg type : " + callerReference 446 + " You most likely intended to call a VM with a string literal, so enclose with ' or \" characters. (VMProxyArg.setup())"); 447 constant = true; 448 staticObject = new String ( callerReference ); 449 450 break; 451 } 452 453 default : 454 { 455 rsvc.error(" VMProxyArg.setup() : unsupported type : " 456 + callerReference ); 457 } 458 } 459 } 460 461 464 465 474 public VMProxyArg( VMProxyArg model, InternalContextAdapter c ) 475 { 476 usercontext = c; 477 contextReference = model.getContextReference(); 478 callerReference = model.getCallerReference(); 479 nodeTree = model.getNodeTree(); 480 staticObject = model.getStaticObject(); 481 type = model.getType(); 482 483 if( nodeTree != null) 484 numTreeChildren = nodeTree.jjtGetNumChildren(); 485 486 if ( type == ParserTreeConstants.JJTREFERENCE ) 487 { 488 if ( numTreeChildren == 0) 489 { 490 493 singleLevelRef = ((ASTReference) nodeTree).getRootString(); 494 } 495 } 496 } 497 498 public String getCallerReference() 499 { 500 return callerReference; 501 } 502 503 public String getContextReference() 504 { 505 return contextReference; 506 } 507 508 public SimpleNode getNodeTree() 509 { 510 return nodeTree; 511 } 512 513 public Object getStaticObject() 514 { 515 return staticObject; 516 } 517 518 public int getType() 519 { 520 return type; 521 } 522 } 523 | Popular Tags |