1 package org.apache.velocity.runtime.parser.node;
2
3 /*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22 import java.io.IOException;
23 import java.io.Writer;
24
25 import org.apache.commons.lang.builder.ToStringBuilder;
26 import org.apache.commons.lang.text.StrBuilder;
27 import org.apache.velocity.context.InternalContextAdapter;
28 import org.apache.velocity.exception.MethodInvocationException;
29 import org.apache.velocity.exception.ParseErrorException;
30 import org.apache.velocity.exception.ResourceNotFoundException;
31 import org.apache.velocity.exception.TemplateInitException;
32 import org.apache.velocity.runtime.RuntimeServices;
33 import org.apache.velocity.runtime.log.Log;
34 import org.apache.velocity.runtime.parser.Parser;
35 import org.apache.velocity.runtime.parser.Token;
36
37 /**
38 *
39 */
40 public class SimpleNode implements Node
41 {
42 /** */
43 protected RuntimeServices rsvc = null;
44
45 /** */
46 protected Log log = null;
47
48 /** */
49 protected Node parent;
50
51 /** */
52 protected Node[] children;
53
54 /** */
55 protected int id;
56
57 /** */
58 // TODO - It seems that this field is only valid when parsing, and should not be kept around.
59 protected Parser parser;
60
61 /** */
62 protected int info; // added
63
64 /** */
65 public boolean state;
66
67 /** */
68 protected boolean invalid = false;
69
70 /** */
71 protected Token first;
72
73 /** */
74 protected Token last;
75
76
77 protected String templateName;
78
79
80 public RuntimeServices getRuntimeServices()
81 {
82 return rsvc;
83 }
84
85 /**
86 * @param i
87 */
88 public SimpleNode(int i)
89 {
90 id = i;
91 }
92
93 /**
94 * @param p
95 * @param i
96 */
97 public SimpleNode(Parser p, int i)
98 {
99 this(i);
100 parser = p;
101 templateName = parser.currentTemplateName;
102 }
103
104 /**
105 * @see org.apache.velocity.runtime.parser.node.Node#jjtOpen()
106 */
107 public void jjtOpen()
108 {
109 first = parser.getToken(1); // added
110 }
111
112 /**
113 * @see org.apache.velocity.runtime.parser.node.Node#jjtClose()
114 */
115 public void jjtClose()
116 {
117 last = parser.getToken(0); // added
118 }
119
120 /**
121 * @param t
122 */
123 public void setFirstToken(Token t)
124 {
125 this.first = t;
126 }
127
128 /**
129 * @see org.apache.velocity.runtime.parser.node.Node#getFirstToken()
130 */
131 public Token getFirstToken()
132 {
133 return first;
134 }
135
136 /**
137 * @see org.apache.velocity.runtime.parser.node.Node#getLastToken()
138 */
139 public Token getLastToken()
140 {
141 return last;
142 }
143
144 /**
145 * @see org.apache.velocity.runtime.parser.node.Node#jjtSetParent(org.apache.velocity.runtime.parser.node.Node)
146 */
147 public void jjtSetParent(Node n)
148 {
149 parent = n;
150 }
151
152 /**
153 * @see org.apache.velocity.runtime.parser.node.Node#jjtGetParent()
154 */
155 public Node jjtGetParent()
156 {
157 return parent;
158 }
159
160 /**
161 * @see org.apache.velocity.runtime.parser.node.Node#jjtAddChild(org.apache.velocity.runtime.parser.node.Node, int)
162 */
163 public void jjtAddChild(Node n, int i)
164 {
165 if (children == null)
166 {
167 children = new Node[i + 1];
168 }
169 else if (i >= children.length)
170 {
171 Node c[] = new Node[i + 1];
172 System.arraycopy(children, 0, c, 0, children.length);
173 children = c;
174 }
175 children[i] = n;
176 }
177
178 /**
179 * @see org.apache.velocity.runtime.parser.node.Node#jjtGetChild(int)
180 */
181 public Node jjtGetChild(int i)
182 {
183 return children[i];
184 }
185
186 /**
187 * @see org.apache.velocity.runtime.parser.node.Node#jjtGetNumChildren()
188 */
189 public int jjtGetNumChildren()
190 {
191 return (children == null) ? 0 : children.length;
192 }
193
194
195 /**
196 * @see org.apache.velocity.runtime.parser.node.Node#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object)
197 */
198 public Object jjtAccept(ParserVisitor visitor, Object data)
199 {
200 return visitor.visit(this, data);
201 }
202
203
204 /**
205 * @see org.apache.velocity.runtime.parser.node.Node#childrenAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object)
206 */
207 public Object childrenAccept(ParserVisitor visitor, Object data)
208 {
209 if (children != null)
210 {
211 for (int i = 0; i < children.length; ++i)
212 {
213 children[i].jjtAccept(visitor, data);
214 }
215 }
216 return data;
217 }
218
219 /* You can override these two methods in subclasses of SimpleNode to
220 customize the way the node appears when the tree is dumped. If
221 your output uses more than one line you should override
222 toString(String), otherwise overriding toString() is probably all
223 you need to do. */
224
225 // public String toString()
226 // {
227 // return ParserTreeConstants.jjtNodeName[id];
228 // }
229 /**
230 * @param prefix
231 * @return String representation of this node.
232 */
233 public String toString(String prefix)
234 {
235 return prefix + toString();
236 }
237
238 /**
239 * Override this method if you want to customize how the node dumps
240 * out its children.
241 *
242 * @param prefix
243 */
244 public void dump(String prefix)
245 {
246 System.out.println(toString(prefix));
247 if (children != null)
248 {
249 for (int i = 0; i < children.length; ++i)
250 {
251 SimpleNode n = (SimpleNode) children[i];
252 if (n != null)
253 {
254 n.dump(prefix + " ");
255 }
256 }
257 }
258 }
259
260 /**
261 * Return a string that tells the current location of this node.
262 */
263 protected String getLocation(InternalContextAdapter context)
264 {
265 return Log.formatFileString(this);
266 }
267
268 // All additional methods
269
270 /**
271 * @see org.apache.velocity.runtime.parser.node.Node#literal()
272 */
273 public String literal()
274 {
275 // if we have only one string, just return it and avoid
276 // buffer allocation. VELOCITY-606
277 if (first == last)
278 {
279 return NodeUtils.tokenLiteral(first);
280 }
281
282 Token t = first;
283 StrBuilder sb = new StrBuilder(NodeUtils.tokenLiteral(t));
284 while (t != last)
285 {
286 t = t.next;
287 sb.append(NodeUtils.tokenLiteral(t));
288 }
289 return sb.toString();
290 }
291
292 /**
293 * @throws TemplateInitException
294 * @see org.apache.velocity.runtime.parser.node.Node#init(org.apache.velocity.context.InternalContextAdapter, java.lang.Object)
295 */
296 public Object init( InternalContextAdapter context, Object data) throws TemplateInitException
297 {
298 /*
299 * hold onto the RuntimeServices
300 */
301
302 rsvc = (RuntimeServices) data;
303 log = rsvc.getLog();
304
305 int i, k = jjtGetNumChildren();
306
307 for (i = 0; i < k; i++)
308 {
309 jjtGetChild(i).init( context, data);
310 }
311
312 return data;
313 }
314
315 /**
316 * @see org.apache.velocity.runtime.parser.node.Node#evaluate(org.apache.velocity.context.InternalContextAdapter)
317 */
318 public boolean evaluate( InternalContextAdapter context)
319 throws MethodInvocationException
320 {
321 return false;
322 }
323
324 /**
325 * @see org.apache.velocity.runtime.parser.node.Node#value(org.apache.velocity.context.InternalContextAdapter)
326 */
327 public Object value( InternalContextAdapter context)
328 throws MethodInvocationException
329 {
330 return null;
331 }
332
333 /**
334 * @see org.apache.velocity.runtime.parser.node.Node#render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer)
335 */
336 public boolean render( InternalContextAdapter context, Writer writer)
337 throws IOException, MethodInvocationException, ParseErrorException, ResourceNotFoundException
338 {
339 int i, k = jjtGetNumChildren();
340
341 for (i = 0; i < k; i++)
342 jjtGetChild(i).render(context, writer);
343
344 return true;
345 }
346
347 /**
348 * @see org.apache.velocity.runtime.parser.node.Node#execute(java.lang.Object, org.apache.velocity.context.InternalContextAdapter)
349 */
350 public Object execute(Object o, InternalContextAdapter context)
351 throws MethodInvocationException
352 {
353 return null;
354 }
355
356 /**
357 * @see org.apache.velocity.runtime.parser.node.Node#getType()
358 */
359 public int getType()
360 {
361 return id;
362 }
363
364 /**
365 * @see org.apache.velocity.runtime.parser.node.Node#setInfo(int)
366 */
367 public void setInfo(int info)
368 {
369 this.info = info;
370 }
371
372 /**
373 * @see org.apache.velocity.runtime.parser.node.Node#getInfo()
374 */
375 public int getInfo()
376 {
377 return info;
378 }
379
380 /**
381 * @see org.apache.velocity.runtime.parser.node.Node#setInvalid()
382 */
383 public void setInvalid()
384 {
385 invalid = true;
386 }
387
388 /**
389 * @see org.apache.velocity.runtime.parser.node.Node#isInvalid()
390 */
391 public boolean isInvalid()
392 {
393 return invalid;
394 }
395
396 /**
397 * @see org.apache.velocity.runtime.parser.node.Node#getLine()
398 */
399 public int getLine()
400 {
401 return first.beginLine;
402 }
403
404 /**
405 * @see org.apache.velocity.runtime.parser.node.Node#getColumn()
406 */
407 public int getColumn()
408 {
409 return first.beginColumn;
410 }
411
412 /**
413 * @since 1.5
414 */
415 public String toString()
416 {
417 StrBuilder tokens = new StrBuilder();
418
419 for (Token t = getFirstToken(); t != null; )
420 {
421 tokens.append("[").append(t.image).append("]");
422 if (t.next != null)
423 {
424 if (t.equals(getLastToken()))
425 {
426 break;
427 }
428 else
429 {
430 tokens.append(", ");
431 }
432 }
433 t = t.next;
434 }
435
436 return new ToStringBuilder(this)
437 .append("id", getType())
438 .append("info", getInfo())
439 .append("invalid", isInvalid())
440 .append("children", jjtGetNumChildren())
441 .append("tokens", tokens)
442 .toString();
443 }
444
445 public String getTemplateName()
446 {
447 return templateName;
448 }
449 }
450