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 }