View Javadoc

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