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.lang.reflect.InvocationTargetException;
23
24 import org.apache.velocity.app.event.EventHandlerUtil;
25 import org.apache.velocity.context.InternalContextAdapter;
26 import org.apache.velocity.exception.MethodInvocationException;
27 import org.apache.velocity.exception.TemplateInitException;
28 import org.apache.velocity.exception.VelocityException;
29 import org.apache.velocity.runtime.RuntimeConstants;
30 import org.apache.velocity.runtime.parser.Parser;
31 import org.apache.velocity.util.introspection.Info;
32 import org.apache.velocity.util.introspection.IntrospectionCacheData;
33 import org.apache.velocity.util.introspection.VelPropertyGet;
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 public class ASTIdentifier extends SimpleNode
52 {
53 private String identifier = "";
54
55
56
57
58 protected Info uberInfo;
59
60
61
62
63 protected boolean strictRef = false;
64
65
66
67
68 public ASTIdentifier(int id)
69 {
70 super(id);
71 }
72
73
74
75
76
77 public ASTIdentifier(Parser p, int id)
78 {
79 super(p, id);
80 }
81
82
83
84
85
86 public Object jjtAccept(ParserVisitor visitor, Object data)
87 {
88 return visitor.visit(this, data);
89 }
90
91
92
93
94
95
96
97
98
99 public Object init(InternalContextAdapter context, Object data)
100 throws TemplateInitException
101 {
102 super.init(context, data);
103
104 identifier = getFirstToken().image;
105
106 uberInfo = new Info(getTemplateName(), getLine(), getColumn());
107
108 strictRef = rsvc.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT, false);
109
110 return data;
111 }
112
113
114
115
116 public Object execute(Object o, InternalContextAdapter context)
117 throws MethodInvocationException
118 {
119
120 VelPropertyGet vg = null;
121
122 try
123 {
124
125
126
127
128 IntrospectionCacheData icd = context.icacheGet(this);
129
130
131
132
133
134
135
136
137 if ( icd != null && (o != null) && (icd.contextData == o.getClass()) )
138 {
139 vg = (VelPropertyGet) icd.thingy;
140 }
141 else
142 {
143
144
145
146
147
148 vg = rsvc.getUberspect().getPropertyGet(o,identifier, uberInfo);
149
150 if (vg != null && vg.isCacheable() && (o != null))
151 {
152 icd = new IntrospectionCacheData();
153 icd.contextData = o.getClass();
154 icd.thingy = vg;
155 context.icachePut(this,icd);
156 }
157 }
158 }
159
160
161
162
163 catch( RuntimeException e )
164 {
165 throw e;
166 }
167 catch(Exception e)
168 {
169 String msg = "ASTIdentifier.execute() : identifier = "+identifier;
170 log.error(msg, e);
171 throw new VelocityException(msg, e);
172 }
173
174
175
176
177
178 if (vg == null)
179 {
180 if (strictRef)
181 {
182 throw new MethodInvocationException("Object '" + o.getClass().getName() +
183 "' does not contain property '" + identifier + "'", null, identifier,
184 uberInfo.getTemplateName(), uberInfo.getLine(), uberInfo.getColumn());
185 }
186 else
187 {
188 return null;
189 }
190 }
191
192
193
194
195
196 try
197 {
198 return vg.invoke(o);
199 }
200 catch(InvocationTargetException ite)
201 {
202
203
204
205
206
207 Throwable t = ite.getTargetException();
208 if (t instanceof Exception)
209 {
210 try
211 {
212 return EventHandlerUtil.methodException(rsvc, context, o.getClass(), vg.getMethodName(),
213 (Exception) t);
214 }
215
216
217
218
219
220
221 catch( Exception e )
222 {
223 throw new MethodInvocationException(
224 "Invocation of method '" + vg.getMethodName() + "'"
225 + " in " + o.getClass()
226 + " threw exception "
227 + ite.getTargetException().toString(),
228 ite.getTargetException(), vg.getMethodName(), getTemplateName(), this.getLine(), this.getColumn());
229 }
230 }
231 else
232 {
233
234
235
236
237 throw new MethodInvocationException(
238 "Invocation of method '" + vg.getMethodName() + "'"
239 + " in " + o.getClass()
240 + " threw exception "
241 + ite.getTargetException().toString(),
242 ite.getTargetException(), vg.getMethodName(), getTemplateName(), this.getLine(), this.getColumn());
243
244
245 }
246 }
247 catch(IllegalArgumentException iae)
248 {
249 return null;
250 }
251
252
253
254 catch( RuntimeException e )
255 {
256 throw e;
257 }
258 catch(Exception e)
259 {
260 String msg = "ASTIdentifier() : exception invoking method "
261 + "for identifier '" + identifier + "' in "
262 + o.getClass();
263 log.error(msg, e);
264 throw new VelocityException(msg, e);
265 }
266 }
267 }