1 package org.apache.velocity.runtime.parser.node;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
36
37
38
39
40
41 public class ASTSetDirective extends SimpleNode
42 {
43 private String leftReference = "";
44 private Node right = null;
45 private ASTReference left = null;
46 boolean logOnNull = false;
47 private boolean allowNull = false;
48 private boolean isInitialized;
49
50
51
52
53 protected Info uberInfo;
54
55
56
57
58 protected boolean strictRef = false;
59
60
61
62
63 public ASTSetDirective(int id)
64 {
65 super(id);
66 }
67
68
69
70
71
72 public ASTSetDirective(Parser p, int id)
73 {
74 super(p, id);
75 }
76
77
78
79
80 public Object jjtAccept(ParserVisitor visitor, Object data)
81 {
82 return visitor.visit(this, data);
83 }
84
85
86
87
88
89
90
91
92 public synchronized Object init(InternalContextAdapter context, Object data)
93 throws TemplateInitException
94 {
95
96
97 if (!isInitialized)
98 {
99
100
101
102
103 super.init( context, data );
104
105 uberInfo = new Info(getTemplateName(),
106 getLine(), getColumn());
107
108 right = getRightHandSide();
109 left = getLeftHandSide();
110
111 logOnNull = rsvc.getBoolean(RuntimeConstants.RUNTIME_LOG_REFERENCE_LOG_INVALID, true);
112 allowNull = rsvc.getBoolean(RuntimeConstants.SET_NULL_ALLOWED, false);
113 strictRef = rsvc.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT, false);
114 if (strictRef) allowNull = true;
115
116
117
118
119 leftReference = left.getFirstToken().image.substring(1);
120
121 isInitialized = true;
122 }
123
124 return data;
125 }
126
127
128
129
130
131
132
133
134
135 public boolean render( InternalContextAdapter context, Writer writer)
136 throws IOException, MethodInvocationException
137 {
138
139
140
141
142 Object value = right.value(context);
143
144
145
146
147
148
149 if( !allowNull )
150 {
151 if ( value == null )
152 {
153
154
155
156 if(logOnNull)
157 {
158 boolean doit = EventHandlerUtil.shouldLogOnNullSet( rsvc, context, left.literal(), right.literal() );
159
160 if (doit && rsvc.getLog().isDebugEnabled())
161 {
162 rsvc.getLog().debug("RHS of #set statement is null. Context will not be modified. "
163 + Log.formatFileString(this));
164 }
165 }
166
167 String rightReference = null;
168 if (right instanceof ASTExpression)
169 {
170 rightReference = ((ASTExpression) right).getLastToken().image;
171 }
172 EventHandlerUtil.invalidSetMethod(rsvc, context, leftReference, rightReference, uberInfo);
173
174 return false;
175 }
176 }
177
178 if ( value == null && !strictRef)
179 {
180 String rightReference = null;
181 if (right instanceof ASTExpression)
182 {
183 rightReference = ((ASTExpression) right).getLastToken().image;
184 }
185 EventHandlerUtil.invalidSetMethod(rsvc, context, leftReference, rightReference, uberInfo);
186
187
188
189
190
191 if (left.jjtGetNumChildren() == 0)
192 {
193 context.remove( leftReference );
194 }
195 else
196 {
197 left.setValue(context, null);
198 }
199
200 return false;
201
202 }
203 else
204 {
205
206
207
208
209
210
211 if (left.jjtGetNumChildren() == 0)
212 {
213 context.put( leftReference, value);
214 }
215 else
216 {
217 left.setValue(context, value);
218 }
219 }
220
221 return true;
222 }
223
224
225
226
227
228
229 private ASTReference getLeftHandSide()
230 {
231 return (ASTReference) jjtGetChild(0);
232 }
233
234
235
236
237
238
239 private Node getRightHandSide()
240 {
241 return jjtGetChild(1);
242 }
243 }