1 package org.apache.velocity.runtime.directive; 2 3 18 19 import java.io.Writer ; 20 import java.io.IOException ; 21 22 import java.util.List ; 23 import java.util.ArrayList ; 24 25 import org.apache.velocity.context.InternalContextAdapter; 26 27 import org.apache.velocity.runtime.parser.node.Node; 28 import org.apache.velocity.runtime.parser.node.NodeUtils; 29 import org.apache.velocity.runtime.parser.Token; 30 import org.apache.velocity.runtime.parser.ParseException; 31 import org.apache.velocity.runtime.parser.ParserTreeConstants; 32 import org.apache.velocity.runtime.RuntimeServices; 33 34 53 public class Macro extends Directive 54 { 55 private static boolean debugMode = false; 56 57 60 public String getName() 61 { 62 return "macro"; 63 } 64 65 68 public int getType() 69 { 70 return BLOCK; 71 } 72 73 77 public boolean render(InternalContextAdapter context, 78 Writer writer, Node node) 79 throws IOException 80 { 81 84 85 return true; 86 } 87 88 public void init(RuntimeServices rs, InternalContextAdapter context, 89 Node node) 90 throws Exception 91 { 92 super.init(rs, context, node); 93 94 99 100 return; 101 } 102 103 111 public static void processAndRegister(RuntimeServices rs, Node node, 112 String sourceTemplate) 113 throws IOException , ParseException 114 { 115 120 121 int numArgs = node.jjtGetNumChildren(); 122 123 127 128 if (numArgs < 2) 129 { 130 131 135 136 rs.error("#macro error : Velocimacro must have name as 1st " + 137 "argument to #macro(). #args = " + numArgs); 138 139 throw new MacroParseException("First argument to #macro() must be " + 140 " macro name."); 141 } 142 143 146 147 int firstType = node.jjtGetChild(0).getType(); 148 149 if(firstType != ParserTreeConstants.JJTWORD) 150 { 151 Token t = node.jjtGetChild(0).getFirstToken(); 152 153 throw new MacroParseException("First argument to #macro() must be a" 154 + " token without surrounding \' or \", which specifies" 155 + " the macro name. Currently it is a " 156 + ParserTreeConstants.jjtNodeName[firstType]); 157 158 } 159 160 163 164 String argArray[] = getArgArray(node); 165 166 169 170 List macroArray = 171 getASTAsStringArray(node.jjtGetChild(numArgs - 1)); 172 173 176 177 StringBuffer temp = new StringBuffer (); 178 179 for (int i=0; i < macroArray.size(); i++) 180 { 181 temp.append(macroArray.get(i)); 182 } 183 184 String macroBody = temp.toString(); 185 186 190 191 boolean bRet = rs.addVelocimacro(argArray[0], macroBody, 192 argArray, sourceTemplate); 193 194 return; 195 } 196 197 198 202 private static String [] getArgArray(Node node) 203 { 204 207 208 int numArgs = node.jjtGetNumChildren(); 209 210 numArgs--; 212 String argArray[] = new String [numArgs]; 213 214 int i = 0; 215 216 219 220 while (i < numArgs) 221 { 222 argArray[i] = node.jjtGetChild(i).getFirstToken().image; 223 224 228 229 if (i > 0) 230 { 231 if (argArray[i].startsWith("$")) 232 { 233 argArray[i] = argArray[i] 234 .substring(1, argArray[i].length()); 235 } 236 } 237 238 i++; 239 } 240 241 if (debugMode) 242 { 243 System.out.println("Macro.getArgArray() : #args = " + numArgs); 244 System.out.print(argArray[0] + "("); 245 246 for (i = 1; i < numArgs; i++) 247 { 248 System.out.print(" " + argArray[i]); 249 } 250 251 System.out.println(" )"); 252 } 253 254 return argArray; 255 } 256 257 260 private static List getASTAsStringArray(Node rootNode) 261 { 262 266 267 Token t = rootNode.getFirstToken(); 268 Token tLast = rootNode.getLastToken(); 269 270 274 275 ArrayList list = new ArrayList (); 276 277 t = rootNode.getFirstToken(); 278 279 while (t != tLast) 280 { 281 list.add(NodeUtils.tokenLiteral(t)); 282 t = t.next; 283 } 284 285 288 289 list.add(NodeUtils.tokenLiteral(t)); 290 291 return list; 292 } 293 } 294 | Popular Tags |