1 package org.apache.velocity.runtime.directive; 2 3 18 19 import java.io.Writer ; 20 import java.io.IOException ; 21 import java.io.BufferedReader ; 22 import java.io.StringReader ; 23 24 import java.util.HashMap ; 25 26 import org.apache.velocity.context.InternalContextAdapter; 27 import org.apache.velocity.context.VMContext; 28 29 import org.apache.velocity.runtime.visitor.VMReferenceMungeVisitor; 30 import org.apache.velocity.runtime.RuntimeServices; 31 import org.apache.velocity.runtime.parser.node.Node; 32 import org.apache.velocity.runtime.parser.Token; 33 import org.apache.velocity.runtime.parser.ParserTreeConstants; 34 import org.apache.velocity.runtime.parser.node.SimpleNode; 35 import org.apache.velocity.util.StringUtils; 36 37 import org.apache.velocity.exception.MethodInvocationException; 38 39 47 public class VelocimacroProxy extends Directive 48 { 49 private String macroName = ""; 50 private String macroBody = ""; 51 private String [] argArray = null; 52 private SimpleNode nodeTree = null; 53 private int numMacroArgs = 0; 54 private String namespace = ""; 55 56 private boolean init = false; 57 private String [] callingArgs; 58 private int[] callingArgTypes; 59 private HashMap proxyArgHash = new HashMap (); 60 61 62 65 public String getName() 66 { 67 return macroName; 68 } 69 70 74 public int getType() 75 { 76 return LINE; 77 } 78 79 82 public void setName( String name ) 83 { 84 macroName = name; 85 } 86 87 90 public void setArgArray( String [] arr ) 91 { 92 argArray = arr; 93 94 98 99 numMacroArgs = argArray.length - 1; 100 } 101 102 public void setNodeTree( SimpleNode tree ) 103 { 104 nodeTree = tree; 105 } 106 107 110 public int getNumArgs() 111 { 112 return numMacroArgs; 113 } 114 115 120 public void setMacrobody( String mb ) 121 { 122 macroBody = mb; 123 } 124 125 public void setNamespace( String ns ) 126 { 127 this.namespace = ns; 128 } 129 130 133 public boolean render( InternalContextAdapter context, Writer writer, Node node) 134 throws IOException , MethodInvocationException 135 { 136 try 137 { 138 142 143 if (nodeTree != null) 144 { 145 if ( !init ) 146 { 147 nodeTree.init( context, rsvc); 148 init = true; 149 } 150 151 154 155 VMContext vmc = new VMContext( context, rsvc ); 156 157 for( int i = 1; i < argArray.length; i++) 158 { 159 163 164 VMProxyArg arg = (VMProxyArg) proxyArgHash.get( argArray[i] ); 165 vmc.addVMProxyArg( arg ); 166 } 167 168 171 172 nodeTree.render( vmc, writer ); 173 } 174 else 175 { 176 rsvc.error( "VM error : " + macroName + ". Null AST"); 177 } 178 } 179 catch ( Exception e ) 180 { 181 184 185 if ( e instanceof MethodInvocationException) 186 { 187 throw (MethodInvocationException) e; 188 } 189 190 rsvc.error("VelocimacroProxy.render() : exception VM = #" + macroName + 191 "() : " + StringUtils.stackTrace(e)); 192 } 193 194 return true; 195 } 196 197 202 public void init( RuntimeServices rs, InternalContextAdapter context, Node node) 203 throws Exception 204 { 205 super.init( rs, context, node ); 206 207 210 211 int i = node.jjtGetNumChildren(); 212 213 216 217 if ( getNumArgs() != i ) 218 { 219 rsvc.error("VM #" + macroName + ": error : too " 220 + ( (getNumArgs() > i) ? "few" : "many") + " arguments to macro. Wanted " 221 + getNumArgs() + " got " + i ); 222 223 return; 224 } 225 226 229 230 callingArgs = getArgArray( node ); 231 232 235 236 setupMacro( callingArgs, callingArgTypes ); 237 return; 238 } 239 240 244 public boolean setupMacro( String [] callArgs, int[] callArgTypes ) 245 { 246 setupProxyArgs( callArgs, callArgTypes ); 247 parseTree( callArgs ); 248 249 return true; 250 } 251 252 256 private void parseTree( String [] callArgs ) 257 { 258 try 259 { 260 BufferedReader br = new BufferedReader ( new StringReader ( macroBody ) ); 261 262 265 266 nodeTree = rsvc.parse( br, namespace, false ); 267 268 276 277 HashMap hm = new HashMap (); 278 279 for( int i = 1; i < argArray.length; i++) 280 { 281 String arg = callArgs[i-1]; 282 283 288 289 if (arg.charAt(0) == '$') 290 { 291 hm.put( argArray[i], arg ); 292 } 293 } 294 295 299 300 VMReferenceMungeVisitor v = new VMReferenceMungeVisitor( hm ); 301 nodeTree.jjtAccept( v, null ); 302 } 303 catch ( Exception e ) 304 { 305 rsvc.error("VelocimacroManager.parseTree() : exception " + macroName + 306 " : " + StringUtils.stackTrace(e)); 307 } 308 } 309 310 private void setupProxyArgs( String [] callArgs, int [] callArgTypes ) 311 { 312 315 316 for( int i = 1; i < argArray.length; i++) 317 { 318 VMProxyArg arg = new VMProxyArg( rsvc, argArray[i], callArgs[i-1], callArgTypes[i-1] ); 319 proxyArgHash.put( argArray[i], arg ); 320 } 321 } 322 323 326 private String [] getArgArray( Node node ) 327 { 328 int numArgs = node.jjtGetNumChildren(); 329 330 String args[] = new String [ numArgs ]; 331 callingArgTypes = new int[numArgs]; 332 333 336 int i = 0; 337 Token t = null; 338 Token tLast = null; 339 340 while( i < numArgs ) 341 { 342 args[i] = ""; 343 347 348 callingArgTypes[i] = node.jjtGetChild(i).getType(); 349 350 351 if (false && node.jjtGetChild(i).getType() == ParserTreeConstants.JJTSTRINGLITERAL ) 352 { 353 args[i] += node.jjtGetChild(i).getFirstToken().image.substring(1, node.jjtGetChild(i).getFirstToken().image.length() - 1); 354 } 355 else 356 { 357 360 t = node.jjtGetChild(i).getFirstToken(); 361 tLast = node.jjtGetChild(i).getLastToken(); 362 363 while( t != tLast ) 364 { 365 args[i] += t.image; 366 t = t.next; 367 } 368 369 372 args[i] += t.image; 373 } 374 i++; 375 } 376 return args; 377 } 378 } 379 380 381 382 383 384 385 386 387 388 389 | Popular Tags |