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 * @param i
81 */
82 public SimpleNode(int i)
83 {
84 id = i;
85 }
86
87 /**
88 * @param p
89 * @param i
90 */
91 public SimpleNode(Parser p, int i)
92 {
93 this(i);
94 parser = p;
95 templateName = parser.currentTemplateName;
96 }
97
98 /**
99 * @see org.apache.velocity.runtime.parser.node.Node#jjtOpen()
100 */
101 public void jjtOpen()
102 {
103 first = parser.getToken(1); // added
104 }
105
106 /**
107 * @see org.apache.velocity.runtime.parser.node.Node#jjtClose()
108 */
109 public void jjtClose()
110 {
111 last = parser.getToken(0); // added
112 }
113
114 /**
115 * @param t
116 */
117 public void setFirstToken(Token t)
118 {
119 this.first = t;
120 }
121
122 /**
123 * @see org.apache.velocity.runtime.parser.node.Node#getFirstToken()
124 */
125 public Token getFirstToken()
126 {
127 return first;
128 }
129
130 /**
131 * @see org.apache.velocity.runtime.parser.node.Node#getLastToken()
132 */
133 public Token getLastToken()
134 {
135 return last;
136 }
137
138 /**
139 * @see org.apache.velocity.runtime.parser.node.Node#jjtSetParent(org.apache.velocity.runtime.parser.node.Node)
140 */
141 public void jjtSetParent(Node n)
142 {
143 parent = n;
144 }
145
146 /**
147 * @see org.apache.velocity.runtime.parser.node.Node#jjtGetParent()
148 */
149 public Node jjtGetParent()
150 {
151 return parent;
152 }
153
154 /**
155 * @see org.apache.velocity.runtime.parser.node.Node#jjtAddChild(org.apache.velocity.runtime.parser.node.Node, int)
156 */
157 public void jjtAddChild(Node n, int i)
158 {
159 if (children == null)
160 {
161 children = new Node[i + 1];
162 }
163 else if (i >= children.length)
164 {
165 Node c[] = new Node[i + 1];
166 System.arraycopy(children, 0, c, 0, children.length);
167 children = c;
168 }
169 children[i] = n;
170 }
171
172 /**
173 * @see org.apache.velocity.runtime.parser.node.Node#jjtGetChild(int)
174 */
175 public Node jjtGetChild(int i)
176 {
177 return children[i];
178 }
179
180 /**
181 * @see org.apache.velocity.runtime.parser.node.Node#jjtGetNumChildren()
182 */
183 public int jjtGetNumChildren()
184 {
185 return (children == null) ? 0 : children.length;
186 }
187
188
189 /**
190 * @see org.apache.velocity.runtime.parser.node.Node#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object)
191 */
192 public Object jjtAccept(ParserVisitor visitor, Object data)
193 {
194 return visitor.visit(this, data);
195 }
196
197
198 /**
199 * @see org.apache.velocity.runtime.parser.node.Node#childrenAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object)
200 */
201 public Object childrenAccept(ParserVisitor visitor, Object data)
202 {
203 if (children != null)
204 {
205 for (int i = 0; i < children.length; ++i)
206 {
207 children[i].jjtAccept(visitor, data);
208 }
209 }
210 return data;
211 }
212
213 /* You can override these two methods in subclasses of SimpleNode to
214 customize the way the node appears when the tree is dumped. If
215 your output uses more than one line you should override
216 toString(String), otherwise overriding toString() is probably all
217 you need to do. */
218
219 // public String toString()
220 // {
221 // return ParserTreeConstants.jjtNodeName[id];
222 // }
223 /**
224 * @param prefix
225 * @return String representation of this node.
226 */
227 public String toString(String prefix)
228 {
229 return prefix + toString();
230 }
231
232 /**
233 * Override this method if you want to customize how the node dumps
234 * out its children.
235 *
236 * @param prefix
237 */
238 public void dump(String prefix)
239 {
240 System.out.println(toString(prefix));
241 if (children != null)
242 {
243 for (int i = 0; i < children.length; ++i)
244 {
245 SimpleNode n = (SimpleNode) children[i];
246 if (n != null)
247 {
248 n.dump(prefix + " ");
249 }
250 }
251 }
252 }
253
254 /**
255 * Return a string that tells the current location of this node.
256 */
257 protected String getLocation(InternalContextAdapter context)
258 {
259 return Log.formatFileString(this);
260 }
261
262 // All additional methods
263
264 /**
265 * @see org.apache.velocity.runtime.parser.node.Node#literal()
266 */
267 public String literal()
268 {
269 // if we have only one string, just return it and avoid
270 // buffer allocation. VELOCITY-606
271 if (first == last)
272 {
273 return NodeUtils.tokenLiteral(first);
274 }
275
276 Token t = first;
277 StrBuilder sb = new StrBuilder(NodeUtils.tokenLiteral(t));
278 while (t != last)
279 {
280 t = t.next;
281 sb.append(NodeUtils.tokenLiteral(t));
282 }
283 return sb.toString();
284 }
285
286 /**
287 * @throws TemplateInitException
288 * @see org.apache.velocity.runtime.parser.node.Node#init(org.apache.velocity.context.InternalContextAdapter, java.lang.Object)
289 */
290 public Object init( InternalContextAdapter context, Object data) throws TemplateInitException
291 {
292 /*
293 * hold onto the RuntimeServices
294 */
295
296 rsvc = (RuntimeServices) data;
297 log = rsvc.getLog();
298
299 int i, k = jjtGetNumChildren();
300
301 for (i = 0; i < k; i++)
302 {
303 jjtGetChild(i).init( context, data);
304 }
305
306 return data;
307 }
308
309 /**
310 * @see org.apache.velocity.runtime.parser.node.Node#evaluate(org.apache.velocity.context.InternalContextAdapter)
311 */
312 public boolean evaluate( InternalContextAdapter context)
313 throws MethodInvocationException
314 {
315 return false;
316 }
317
318 /**
319 * @see org.apache.velocity.runtime.parser.node.Node#value(org.apache.velocity.context.InternalContextAdapter)
320 */
321 public Object value( InternalContextAdapter context)
322 throws MethodInvocationException
323 {
324 return null;
325 }
326
327 /**
328 * @see org.apache.velocity.runtime.parser.node.Node#render(org.apache.velocity.context.InternalContextAdapter, java.io.Writer)
329 */
330 public boolean render( InternalContextAdapter context, Writer writer)
331 throws IOException, MethodInvocationException, ParseErrorException, ResourceNotFoundException
332 {
333 int i, k = jjtGetNumChildren();
334
335 for (i = 0; i < k; i++)
336 jjtGetChild(i).render(context, writer);
337
338 return true;
339 }
340
341 /**
342 * @see org.apache.velocity.runtime.parser.node.Node#execute(java.lang.Object, org.apache.velocity.context.InternalContextAdapter)
343 */
344 public Object execute(Object o, InternalContextAdapter context)
345 throws MethodInvocationException
346 {
347 return null;
348 }
349
350 /**
351 * @see org.apache.velocity.runtime.parser.node.Node#getType()
352 */
353 public int getType()
354 {
355 return id;
356 }
357
358 /**
359 * @see org.apache.velocity.runtime.parser.node.Node#setInfo(int)
360 */
361 public void setInfo(int info)
362 {
363 this.info = info;
364 }
365
366 /**
367 * @see org.apache.velocity.runtime.parser.node.Node#getInfo()
368 */
369 public int getInfo()
370 {
371 return info;
372 }
373
374 /**
375 * @see org.apache.velocity.runtime.parser.node.Node#setInvalid()
376 */
377 public void setInvalid()
378 {
379 invalid = true;
380 }
381
382 /**
383 * @see org.apache.velocity.runtime.parser.node.Node#isInvalid()
384 */
385 public boolean isInvalid()
386 {
387 return invalid;
388 }
389
390 /**
391 * @see org.apache.velocity.runtime.parser.node.Node#getLine()
392 */
393 public int getLine()
394 {
395 return first.beginLine;
396 }
397
398 /**
399 * @see org.apache.velocity.runtime.parser.node.Node#getColumn()
400 */
401 public int getColumn()
402 {
403 return first.beginColumn;
404 }
405
406 /**
407 * @since 1.5
408 */
409 public String toString()
410 {
411 StrBuilder tokens = new StrBuilder();
412
413 for (Token t = getFirstToken(); t != null; )
414 {
415 tokens.append("[").append(t.image).append("]");
416 if (t.next != null)
417 {
418 if (t.equals(getLastToken()))
419 {
420 break;
421 }
422 else
423 {
424 tokens.append(", ");
425 }
426 }
427 t = t.next;
428 }
429
430 return new ToStringBuilder(this)
431 .append("id", getType())
432 .append("info", getInfo())
433 .append("invalid", isInvalid())
434 .append("children", jjtGetNumChildren())
435 .append("tokens", tokens)
436 .toString();
437 }
438
439 public String getTemplateName()
440 {
441 return templateName;
442 }
443 }
444