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.velocity.app.event.EventHandlerUtil;
26  import org.apache.velocity.context.InternalContextAdapter;
27  import org.apache.velocity.exception.MethodInvocationException;
28  import org.apache.velocity.exception.TemplateInitException;
29  import org.apache.velocity.runtime.RuntimeConstants;
30  import org.apache.velocity.runtime.log.Log;
31  import org.apache.velocity.runtime.parser.Parser;
32  import org.apache.velocity.util.introspection.Info;
33  
34  /**
35   * Node for the #set directive
36   *
37   * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
38   * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
39   * @version $Id: ASTSetDirective.java 753450 2009-03-13 22:17:31Z nbubna $
40   */
41  public class ASTSetDirective extends SimpleNode
42  {
43      private String leftReference = "";
44      private Node right = null;
45      private ASTReference left = null;
46      private boolean isInitialized;
47  
48      /**
49       *  This is really immutable after the init, so keep one for this node
50       */
51      protected Info uberInfo;
52  
53      /**
54       * Indicates if we are running in strict reference mode.
55       */
56      protected boolean strictRef = false;
57  
58      /**
59       * @param id
60       */
61      public ASTSetDirective(int id)
62      {
63          super(id);
64      }
65  
66      /**
67       * @param p
68       * @param id
69       */
70      public ASTSetDirective(Parser p, int id)
71      {
72          super(p, id);
73      }
74  
75      /**
76       * @see org.apache.velocity.runtime.parser.node.SimpleNode#jjtAccept(org.apache.velocity.runtime.parser.node.ParserVisitor, java.lang.Object)
77       */
78      public Object jjtAccept(ParserVisitor visitor, Object data)
79      {
80          return visitor.visit(this, data);
81      }
82  
83      /**
84       *  simple init.  We can get the RHS and LHS as the the tree structure is static
85       * @param context
86       * @param data
87       * @return Init result.
88       * @throws TemplateInitException
89       */
90      public synchronized Object init(InternalContextAdapter context, Object data)
91      throws TemplateInitException
92      {
93          /** This method is synchronized to prevent double initialization or initialization while rendering **/
94  
95          if (!isInitialized)
96          {
97              /*
98               *  init the tree correctly
99               */
100     
101             super.init( context, data );
102     
103             uberInfo = new Info(getTemplateName(),
104                     getLine(), getColumn());
105     
106             right = getRightHandSide();
107             left = getLeftHandSide();
108     
109             strictRef = rsvc.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT, false);
110             
111             /*
112              *  grab this now.  No need to redo each time
113              */
114             leftReference = left.getFirstToken().image.substring(1);
115         
116             isInitialized = true;
117         }
118             
119         return data;
120     }
121 
122     /**
123      *   puts the value of the RHS into the context under the key of the LHS
124      * @param context
125      * @param writer
126      * @return True if rendering was sucessful.
127      * @throws IOException
128      * @throws MethodInvocationException
129      */
130     public boolean render( InternalContextAdapter context, Writer writer)
131         throws IOException, MethodInvocationException
132     {
133         /*
134          *  get the RHS node, and its value
135          */
136 
137         Object value = right.value(context);
138 
139         if ( value == null && !strictRef)
140         {
141             String rightReference = null;
142             if (right instanceof ASTExpression)
143             {
144                 rightReference = ((ASTExpression) right).getLastToken().image;
145             }
146             EventHandlerUtil.invalidSetMethod(rsvc, context, leftReference, rightReference, uberInfo);
147         }
148         
149         return left.setValue(context, value);
150     }
151     
152     
153     /**
154      *  returns the ASTReference that is the LHS of the set statememt
155      *  
156      *  @return left hand side of #set statement
157      */
158     private ASTReference getLeftHandSide()
159     {
160         return (ASTReference) jjtGetChild(0);
161     }
162 
163     /**
164      *  returns the RHS Node of the set statement
165      *  
166      *  @return right hand side of #set statement
167      */
168     private Node getRightHandSide()
169     {
170         return jjtGetChild(1);
171     }
172 }