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