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      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