1 /*
2 * Copyright (c) 2003
3 * Information Desire GmbH
4 * All rights reserved.
5 */
6 package com.infodesire.infobit.render.velocity;
7
8 import java.io.IOException;
9 import java.io.Writer;
10
11 import org.apache.velocity.runtime.directive.InputBase;
12
13 import org.apache.velocity.context.InternalContextAdapter;
14 import org.apache.velocity.context.Context;
15
16 import org.apache.velocity.Template;
17 import org.apache.velocity.runtime.RuntimeConstants;
18 import org.apache.velocity.runtime.parser.node.Node;
19 import org.apache.velocity.runtime.parser.node.SimpleNode;
20 import org.apache.velocity.runtime.resource.Resource;
21 import org.apache.velocity.exception.MethodInvocationException;
22 import org.apache.velocity.exception.ResourceNotFoundException;
23 import org.apache.velocity.exception.ParseErrorException;
24 import org.apache.velocity.app.event.EventCartridge;
25
26 import com.infodesire.infobit.InfobitManager;
27 import com.infodesire.infobit.data.Infobit;
28 import com.infodesire.infobit.InfobitException;
29
30 import org.apache.velocity.util.introspection.IntrospectionCacheData;
31
32 import java.util.HashMap;
33 import java.util.Map;
34 import java.util.Set;
35 import java.util.Iterator;
36
37 /***
38 * pluggable directive to handle custom #infobit tag. supply infobit name to it.
39 *
40 * @author konstantin
41 * @created August 22, 2003
42 * @version $Revision: 1.3 $
43 */
44 public class InfobitDirective extends InputBase {
45 /***
46 * Return name of this directive.
47 *
48 * @return The Name value
49 */
50 public String getName() {
51 return "infobit";
52 }
53
54
55 /***
56 * Return type of this directive.
57 *
58 * @return The Type value
59 */
60 public int getType() {
61 return LINE;
62 }
63
64
65 /***
66 * renders infobit in appropriate way
67 *
68 * @param context Description of Parameter
69 * @param writer Description of Parameter
70 * @param node Description of Parameter
71 * @return Description of the Returned Value
72 * @exception IOException Description of Exception
73 * @exception ResourceNotFoundException Description of Exception
74 * @exception ParseErrorException Description of Exception
75 * @exception MethodInvocationException Description of Exception
76 */
77 public boolean render(InternalContextAdapter context,
78 Writer writer, Node node)
79 throws IOException, ResourceNotFoundException, ParseErrorException,
80 MethodInvocationException {
81
82 VelocityRenderer renderer = (VelocityRenderer) rsvc.getApplicationAttribute(VelocityRenderer.class.getName());
83 /*
84 * did we get an argument?
85 */
86 if (node.jjtGetChild(0) == null) {
87 rsvc.error("#infobit() error : null argument");
88 return false;
89 }
90
91 /*
92 * does it have a value? If you have a null reference, then no.
93 */
94 Object value = node.jjtGetChild(0).value(context);
95
96 if (value == null) {
97 rsvc.error("#infobit() error : null argument");
98 return false;
99 }
100
101 /*
102 * get the path
103 */
104 String arg = value.toString();
105
106 Object[] templateStack = context.getTemplateNameStack();
107
108 if (templateStack.length >=
109 rsvc.getInt(RuntimeConstants.PARSE_DIRECTIVE_MAXDEPTH, 20)) {
110 StringBuffer path = new StringBuffer();
111
112 for (int i = 0; i < templateStack.length; ++i) {
113 path.append(" > " + templateStack[i]);
114 }
115
116 rsvc.error("Max recursion depth reached (" +
117 templateStack.length + ")" + " File stack:" + path);
118 return false;
119 }
120 Template t = null;
121
122 try {
123 t = rsvc.getTemplate(arg, getInputEncoding(context));
124 } catch (ResourceNotFoundException rnfe) {
125 /*
126 * the arg wasn't found. Note it and throw
127 */
128 rsvc.error("#infobit(): cannot find template '" + arg +
129 "', called from template " +
130 context.getCurrentTemplateName() + " at (" +
131 getLine() + ", " + getColumn() + ")");
132 throw rnfe;
133 } catch (ParseErrorException pee) {
134 /*
135 * the arg was found, but didn't parse - syntax error
136 * note it and throw
137 */
138 rsvc.error("#infobit(): syntax error in #infobit()-ed template '" +
139 arg + "', called from template " +
140 context.getCurrentTemplateName() + " at (" +
141 getLine() + ", " + getColumn() + ")");
142
143 throw pee;
144 } catch (Exception e) {
145 rsvc.error("#infobit() : arg = " + arg + ". Exception : " + e);
146 return false;
147 }
148
149 /*
150 * and render it
151 */
152 try {
153 context.pushCurrentTemplateName(arg);
154
155 // we wrap context into new one
156 WrappedInternalContextAdapter wrapped = new WrappedInternalContextAdapter(context);
157 renderer.setupContext(wrapped, arg);
158 ((SimpleNode) t.getData()).render(wrapped, writer);
159
160 } catch (Exception e) {
161 /*
162 * if it's a MIE, it came from the render.... throw it...
163 */
164 if (e instanceof MethodInvocationException) {
165 throw (MethodInvocationException) e;
166 }
167
168 rsvc.error("Exception rendering #parse( " + arg + " ) : " + e);
169 return false;
170 } finally {
171 context.popCurrentTemplateName();
172 }
173
174 return true;
175 }
176
177
178 /***
179 * context wrapper for infobit context to prevent bleeding of context
180 * variables and effectively manage links etc.
181 *
182 * @author konstantin
183 * @created August 25, 2003
184 * @version $Revision: 1.3 $
185 */
186 class WrappedInternalContextAdapter implements InternalContextAdapter {
187 private HashMap params = new HashMap();
188 private InternalContextAdapter contextAdapter;
189
190
191 /***
192 * Constructor for the WrappedInternalContextAdapter object
193 *
194 * @param contextAdapter Description of Parameter
195 */
196 public WrappedInternalContextAdapter(InternalContextAdapter contextAdapter) {
197 this.contextAdapter = contextAdapter;
198 }
199
200
201 /***
202 * Gets the BaseContext attribute of the WrappedInternalContextAdapter
203 * object
204 *
205 * @return The BaseContext value
206 */
207 public InternalContextAdapter getBaseContext() {
208 return contextAdapter.getBaseContext();
209 }
210
211
212 /***
213 * Gets the CurrentResource attribute of the
214 * WrappedInternalContextAdapter object
215 *
216 * @return The CurrentResource value
217 */
218 public Resource getCurrentResource() {
219 return contextAdapter.getCurrentResource();
220 }
221
222
223 /***
224 * Gets the CurrentTemplateName attribute of the
225 * WrappedInternalContextAdapter object
226 *
227 * @return The CurrentTemplateName value
228 */
229 public String getCurrentTemplateName() {
230 return contextAdapter.getCurrentTemplateName();
231 }
232
233
234 /***
235 * Gets the EventCartridge attribute of the
236 * WrappedInternalContextAdapter object
237 *
238 * @return The EventCartridge value
239 */
240 public EventCartridge getEventCartridge() {
241 return contextAdapter.getEventCartridge();
242 }
243
244
245 /***
246 * Gets the InternalUserContext attribute of the
247 * WrappedInternalContextAdapter object
248 *
249 * @return The InternalUserContext value
250 */
251 public Context getInternalUserContext() {
252 return contextAdapter.getInternalUserContext();
253 }
254
255
256 /***
257 * Gets the Keys attribute of the WrappedInternalContextAdapter object
258 *
259 * @return The Keys value
260 */
261 public Object[] getKeys() {
262 Set keySet = params.keySet();
263
264 if (keySet == null) {
265 return contextAdapter.getKeys();
266 }
267
268 Object[] objects = new Object[keySet.size()];
269 keySet.toArray(objects);
270
271 return objects;
272 }
273
274
275 /***
276 * Gets the TemplateNameStack attribute of the
277 * WrappedInternalContextAdapter object
278 *
279 * @return The TemplateNameStack value
280 */
281 public Object[] getTemplateNameStack() {
282 return contextAdapter.getTemplateNameStack();
283 }
284
285
286 /***
287 * DOCUMENT METHOD
288 *
289 * @param s Description of Parameter
290 * @return Description of the Returned Value
291 */
292 public Object get(String s) {
293 Object obj = params.get(s);
294
295 if (obj == null) {
296 obj = contextAdapter.get(s);
297 }
298
299 return obj;
300 }
301
302
303 /***
304 * Sets the CurrentResource attribute of the
305 * WrappedInternalContextAdapter object
306 *
307 * @param resource The new CurrentResource value
308 */
309 public void setCurrentResource(Resource resource) {
310 contextAdapter.setCurrentResource(resource);
311 }
312
313
314 /***
315 * DOCUMENT METHOD
316 *
317 * @param eventCartridge Description of Parameter
318 * @return Description of the Returned Value
319 */
320 public EventCartridge attachEventCartridge(EventCartridge eventCartridge) {
321 return contextAdapter.attachEventCartridge(eventCartridge);
322 }
323
324
325 /***
326 * DOCUMENT METHOD
327 *
328 * @param o Description of Parameter
329 * @return Description of the Returned Value
330 */
331 public boolean containsKey(Object o) {
332 if (params.containsKey(o)) {
333 return true;
334 }
335
336 return contextAdapter.containsKey(o);
337 }
338
339
340 /***
341 * DOCUMENT METHOD
342 *
343 * @param o Description of Parameter
344 * @return Description of the Returned Value
345 */
346 public IntrospectionCacheData icacheGet(Object o) {
347 return contextAdapter.icacheGet(o);
348 }
349
350
351 /***
352 * DOCUMENT METHOD
353 *
354 * @param o Description of Parameter
355 * @param introspectionCacheData Description of Parameter
356 */
357 public void icachePut(Object o, IntrospectionCacheData introspectionCacheData) {
358 contextAdapter.icachePut(o, introspectionCacheData);
359 }
360
361
362 /***
363 * DOCUMENT METHOD
364 */
365 public void popCurrentTemplateName() {
366 contextAdapter.popCurrentTemplateName();
367 }
368
369
370 /***
371 * DOCUMENT METHOD
372 *
373 * @param s Description of Parameter
374 */
375 public void pushCurrentTemplateName(String s) {
376 contextAdapter.pushCurrentTemplateName(s);
377 }
378
379
380 /***
381 * DOCUMENT METHOD
382 *
383 * @param s Description of Parameter
384 * @param o Description of Parameter
385 * @return Description of the Returned Value
386 */
387 public Object put(String s, Object o) {
388 return params.put(s, o);
389 }
390
391
392 /***
393 * DOCUMENT METHOD
394 *
395 * @param o Description of Parameter
396 * @return Description of the Returned Value
397 */
398 public Object remove(Object o) {
399 Object obj = params.remove(o);
400
401 if (obj == null) {
402 obj = contextAdapter.remove(o);
403 }
404
405 return obj;
406 }
407 }
408 }
This page was automatically generated by Maven