%line | %branch | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
org.apache.turbine.services.velocity.TurbineVelocityService |
|
|
1 | package org.apache.turbine.services.velocity; |
|
2 | ||
3 | /* |
|
4 | * Copyright 2001-2005 The Apache Software Foundation. |
|
5 | * |
|
6 | * Licensed under the Apache License, Version 2.0 (the "License") |
|
7 | * you may not use this file except in compliance with the License. |
|
8 | * You may obtain a copy of the License at |
|
9 | * |
|
10 | * http://www.apache.org/licenses/LICENSE-2.0 |
|
11 | * |
|
12 | * Unless required by applicable law or agreed to in writing, software |
|
13 | * distributed under the License is distributed on an "AS IS" BASIS, |
|
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
15 | * See the License for the specific language governing permissions and |
|
16 | * limitations under the License. |
|
17 | */ |
|
18 | ||
19 | import java.io.ByteArrayOutputStream; |
|
20 | import java.io.IOException; |
|
21 | import java.io.OutputStream; |
|
22 | import java.io.OutputStreamWriter; |
|
23 | import java.io.Writer; |
|
24 | ||
25 | import java.util.Iterator; |
|
26 | import java.util.List; |
|
27 | import java.util.Vector; |
|
28 | ||
29 | import javax.servlet.ServletConfig; |
|
30 | ||
31 | import org.apache.commons.collections.ExtendedProperties; |
|
32 | import org.apache.commons.configuration.Configuration; |
|
33 | import org.apache.commons.lang.StringUtils; |
|
34 | import org.apache.commons.logging.Log; |
|
35 | import org.apache.commons.logging.LogFactory; |
|
36 | ||
37 | import org.apache.velocity.VelocityContext; |
|
38 | import org.apache.velocity.app.Velocity; |
|
39 | import org.apache.velocity.app.event.EventCartridge; |
|
40 | import org.apache.velocity.app.event.MethodExceptionEventHandler; |
|
41 | import org.apache.velocity.context.Context; |
|
42 | import org.apache.velocity.runtime.log.SimpleLog4JLogSystem; |
|
43 | ||
44 | import org.apache.turbine.Turbine; |
|
45 | import org.apache.turbine.services.InitializationException; |
|
46 | import org.apache.turbine.services.pull.PullService; |
|
47 | import org.apache.turbine.services.pull.TurbinePull; |
|
48 | import org.apache.turbine.services.template.BaseTemplateEngineService; |
|
49 | import org.apache.turbine.util.RunData; |
|
50 | import org.apache.turbine.util.TurbineException; |
|
51 | ||
52 | /** |
|
53 | * This is a Service that can process Velocity templates from within a |
|
54 | * Turbine Screen. It is used in conjunction with the templating service |
|
55 | * as a Templating Engine for templates ending in "vm". It registers |
|
56 | * itself as translation engine with the template service and gets |
|
57 | * accessed from there. After configuring it in your properties, it |
|
58 | * should never be necessary to call methods from this service directly. |
|
59 | * |
|
60 | * Here's an example of how you might use it from a |
|
61 | * screen:<br> |
|
62 | * |
|
63 | * <code> |
|
64 | * Context context = TurbineVelocity.getContext(data);<br> |
|
65 | * context.put("message", "Hello from Turbine!");<br> |
|
66 | * String results = TurbineVelocity.handleRequest(context,"helloWorld.vm");<br> |
|
67 | * data.getPage().getBody().addElement(results);<br> |
|
68 | * </code> |
|
69 | * |
|
70 | * @author <a href="mailto:mbryson@mont.mindspring.com">Dave Bryson</a> |
|
71 | * @author <a href="mailto:krzewski@e-point.pl">Rafal Krzewski</a> |
|
72 | * @author <a href="mailto:jvanzyl@periapt.com">Jason van Zyl</a> |
|
73 | * @author <a href="mailto:sean@informage.ent">Sean Legassick</a> |
|
74 | * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a> |
|
75 | * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a> |
|
76 | * @version $Id: TurbineVelocityService.java 264152 2005-08-29 14:50:22Z henning $ |
|
77 | */ |
|
78 | 100 | public class TurbineVelocityService |
79 | extends BaseTemplateEngineService |
|
80 | implements VelocityService, |
|
81 | MethodExceptionEventHandler |
|
82 | { |
|
83 | /** The generic resource loader path property in velocity.*/ |
|
84 | private static final String RESOURCE_LOADER_PATH = ".resource.loader.path"; |
|
85 | ||
86 | /** Default character set to use if not specified in the RunData object. */ |
|
87 | private static final String DEFAULT_CHAR_SET = "ISO-8859-1"; |
|
88 | ||
89 | /** The prefix used for URIs which are of type <code>jar</code>. */ |
|
90 | private static final String JAR_PREFIX = "jar:"; |
|
91 | ||
92 | /** The prefix used for URIs which are of type <code>absolute</code>. */ |
|
93 | private static final String ABSOLUTE_PREFIX = "file://"; |
|
94 | ||
95 | /** Logging */ |
|
96 | 80 | private static Log log = LogFactory.getLog(TurbineVelocityService.class); |
97 | ||
98 | /** Is the pullModelActive? */ |
|
99 | 40 | private boolean pullModelActive = false; |
100 | ||
101 | /** Shall we catch Velocity Errors and report them in the log file? */ |
|
102 | 40 | private boolean catchErrors = true; |
103 | ||
104 | /** Internal Reference to the pull Service */ |
|
105 | 40 | private PullService pullService = null; |
106 | ||
107 | ||
108 | /** |
|
109 | * Load all configured components and initialize them. This is |
|
110 | * a zero parameter variant which queries the Turbine Servlet |
|
111 | * for its config. |
|
112 | * |
|
113 | * @throws InitializationException Something went wrong in the init |
|
114 | * stage |
|
115 | */ |
|
116 | public void init() |
|
117 | throws InitializationException |
|
118 | { |
|
119 | try |
|
120 | { |
|
121 | 42 | initVelocity(); |
122 | ||
123 | // We can only load the Pull Model ToolBox |
|
124 | // if the Pull service has been listed in the TR.props |
|
125 | // and the service has successfully been initialized. |
|
126 | 42 | if (TurbinePull.isRegistered()) |
127 | { |
|
128 | 42 | pullModelActive = true; |
129 | ||
130 | 42 | pullService = TurbinePull.getService(); |
131 | ||
132 | 42 | log.debug("Activated Pull Tools"); |
133 | } |
|
134 | ||
135 | // Register with the template service. |
|
136 | 42 | registerConfiguration(VelocityService.VELOCITY_EXTENSION); |
137 | ||
138 | 42 | setInit(true); |
139 | 21 | } |
140 | 0 | catch (Exception e) |
141 | { |
|
142 | 0 | throw new InitializationException( |
143 | "Failed to initialize TurbineVelocityService", e); |
|
144 | 21 | } |
145 | 42 | } |
146 | ||
147 | ||
148 | /** |
|
149 | * Inits the service using servlet parameters to obtain path to the |
|
150 | * configuration file. |
|
151 | * |
|
152 | * @param config The ServletConfiguration from Turbine |
|
153 | * |
|
154 | * @throws InitializationException Something went wrong when starting up. |
|
155 | * @deprecated use init() instead. |
|
156 | */ |
|
157 | public void init(ServletConfig config) |
|
158 | throws InitializationException |
|
159 | { |
|
160 | 0 | init(); |
161 | 0 | } |
162 | ||
163 | ||
164 | /** |
|
165 | * Create a Context object that also contains the globalContext. |
|
166 | * |
|
167 | * @return A Context object. |
|
168 | */ |
|
169 | public Context getContext() |
|
170 | { |
|
171 | 0 | Context globalContext = |
172 | pullModelActive ? pullService.getGlobalContext() : null; |
|
173 | ||
174 | 0 | Context ctx = new VelocityContext(globalContext); |
175 | 0 | return ctx; |
176 | } |
|
177 | ||
178 | /** |
|
179 | * This method returns a new, empty Context object. |
|
180 | * |
|
181 | * @return A Context Object. |
|
182 | */ |
|
183 | public Context getNewContext() |
|
184 | { |
|
185 | 42 | Context ctx = new VelocityContext(); |
186 | ||
187 | // Attach an Event Cartridge to it, so we get exceptions |
|
188 | // while invoking methods from the Velocity Screens |
|
189 | 42 | EventCartridge ec = new EventCartridge(); |
190 | 42 | ec.addEventHandler(this); |
191 | 42 | ec.attachToContext(ctx); |
192 | 42 | return ctx; |
193 | } |
|
194 | ||
195 | /** |
|
196 | * MethodException Event Cartridge handler |
|
197 | * for Velocity. |
|
198 | * |
|
199 | * It logs an execption thrown by the velocity processing |
|
200 | * on error level into the log file |
|
201 | * |
|
202 | * @param clazz The class that threw the exception |
|
203 | * @param method The Method name that threw the exception |
|
204 | * @param e The exception that would've been thrown |
|
205 | * @return A valid value to be used as Return value |
|
206 | * @throws Exception We threw the exception further up |
|
207 | */ |
|
208 | public Object methodException(Class clazz, String method, Exception e) |
|
209 | throws Exception |
|
210 | { |
|
211 | 0 | log.error("Class " + clazz.getName() + "." + method + " threw Exception", e); |
212 | ||
213 | 0 | if (!catchErrors) |
214 | { |
|
215 | 0 | throw e; |
216 | } |
|
217 | ||
218 | 0 | return "[Turbine caught an Error here. Look into the turbine.log for further information]"; |
219 | } |
|
220 | ||
221 | /** |
|
222 | * Create a Context from the RunData object. Adds a pointer to |
|
223 | * the RunData object to the VelocityContext so that RunData |
|
224 | * is available in the templates. |
|
225 | * |
|
226 | * @param data The Turbine RunData object. |
|
227 | * @return A clone of the WebContext needed by Velocity. |
|
228 | */ |
|
229 | public Context getContext(RunData data) |
|
230 | { |
|
231 | // Attempt to get it from the data first. If it doesn't |
|
232 | // exist, create it and then stuff it into the data. |
|
233 | 0 | Context context = (Context) |
234 | data.getTemplateInfo().getTemplateContext(VelocityService.CONTEXT); |
|
235 | ||
236 | 0 | if (context == null) |
237 | { |
|
238 | 0 | context = getContext(); |
239 | 0 | context.put(VelocityService.RUNDATA_KEY, data); |
240 | ||
241 | 0 | if (pullModelActive) |
242 | { |
|
243 | // Populate the toolbox with request scope, session scope |
|
244 | // and persistent scope tools (global tools are already in |
|
245 | // the toolBoxContent which has been wrapped to construct |
|
246 | // this request-specific context). |
|
247 | 0 | pullService.populateContext(context, data); |
248 | } |
|
249 | ||
250 | 0 | data.getTemplateInfo().setTemplateContext( |
251 | VelocityService.CONTEXT, context); |
|
252 | } |
|
253 | 0 | return context; |
254 | } |
|
255 | ||
256 | /** |
|
257 | * Process the request and fill in the template with the values |
|
258 | * you set in the Context. |
|
259 | * |
|
260 | * @param context The populated context. |
|
261 | * @param filename The file name of the template. |
|
262 | * @return The process template as a String. |
|
263 | * |
|
264 | * @throws TurbineException Any exception trown while processing will be |
|
265 | * wrapped into a TurbineException and rethrown. |
|
266 | */ |
|
267 | public String handleRequest(Context context, String filename) |
|
268 | throws TurbineException |
|
269 | { |
|
270 | 0 | String results = null; |
271 | 0 | ByteArrayOutputStream bytes = null; |
272 | 0 | OutputStreamWriter writer = null; |
273 | 0 | String charset = getCharSet(context); |
274 | ||
275 | try |
|
276 | { |
|
277 | 0 | bytes = new ByteArrayOutputStream(); |
278 | ||
279 | 0 | writer = new OutputStreamWriter(bytes, charset); |
280 | ||
281 | 0 | executeRequest(context, filename, writer); |
282 | 0 | writer.flush(); |
283 | 0 | results = bytes.toString(charset); |
284 | 0 | } |
285 | 0 | catch (Exception e) |
286 | { |
|
287 | 0 | renderingError(filename, e); |
288 | 0 | } |
289 | finally |
|
290 | { |
|
291 | 0 | try |
292 | { |
|
293 | 0 | if (bytes != null) |
294 | { |
|
295 | 0 | bytes.close(); |
296 | } |
|
297 | } |
|
298 | 0 | catch (IOException ignored) |
299 | { |
|
300 | // do nothing. |
|
301 | 0 | } |
302 | 0 | } |
303 | 0 | return results; |
304 | } |
|
305 | ||
306 | /** |
|
307 | * Process the request and fill in the template with the values |
|
308 | * you set in the Context. |
|
309 | * |
|
310 | * @param context A Context. |
|
311 | * @param filename A String with the filename of the template. |
|
312 | * @param output A OutputStream where we will write the process template as |
|
313 | * a String. |
|
314 | * |
|
315 | * @throws TurbineException Any exception trown while processing will be |
|
316 | * wrapped into a TurbineException and rethrown. |
|
317 | */ |
|
318 | public void handleRequest(Context context, String filename, |
|
319 | OutputStream output) |
|
320 | throws TurbineException |
|
321 | { |
|
322 | 0 | String charset = getCharSet(context); |
323 | 0 | OutputStreamWriter writer = null; |
324 | ||
325 | try |
|
326 | { |
|
327 | 0 | writer = new OutputStreamWriter(output, charset); |
328 | 0 | executeRequest(context, filename, writer); |
329 | 0 | } |
330 | 0 | catch (Exception e) |
331 | { |
|
332 | 0 | renderingError(filename, e); |
333 | 0 | } |
334 | finally |
|
335 | { |
|
336 | 0 | try |
337 | { |
|
338 | 0 | if (writer != null) |
339 | { |
|
340 | 0 | writer.flush(); |
341 | } |
|
342 | } |
|
343 | 0 | catch (Exception ignored) |
344 | { |
|
345 | // do nothing. |
|
346 | 0 | } |
347 | 0 | } |
348 | 0 | } |
349 | ||
350 | ||
351 | /** |
|
352 | * Process the request and fill in the template with the values |
|
353 | * you set in the Context. |
|
354 | * |
|
355 | * @param context A Context. |
|
356 | * @param filename A String with the filename of the template. |
|
357 | * @param writer A Writer where we will write the process template as |
|
358 | * a String. |
|
359 | * |
|
360 | * @throws TurbineException Any exception trown while processing will be |
|
361 | * wrapped into a TurbineException and rethrown. |
|
362 | */ |
|
363 | public void handleRequest(Context context, String filename, Writer writer) |
|
364 | throws TurbineException |
|
365 | { |
|
366 | try |
|
367 | { |
|
368 | 0 | executeRequest(context, filename, writer); |
369 | 0 | } |
370 | 0 | catch (Exception e) |
371 | { |
|
372 | 0 | renderingError(filename, e); |
373 | 0 | } |
374 | finally |
|
375 | { |
|
376 | 0 | try |
377 | { |
|
378 | 0 | if (writer != null) |
379 | { |
|
380 | 0 | writer.flush(); |
381 | } |
|
382 | } |
|
383 | 0 | catch (Exception ignored) |
384 | { |
|
385 | // do nothing. |
|
386 | 0 | } |
387 | 0 | } |
388 | 0 | } |
389 | ||
390 | ||
391 | /** |
|
392 | * Process the request and fill in the template with the values |
|
393 | * you set in the Context. Apply the character and template |
|
394 | * encodings from RunData to the result. |
|
395 | * |
|
396 | * @param context A Context. |
|
397 | * @param filename A String with the filename of the template. |
|
398 | * @param writer A OutputStream where we will write the process template as |
|
399 | * a String. |
|
400 | * |
|
401 | * @throws Exception A problem occured. |
|
402 | */ |
|
403 | private void executeRequest(Context context, String filename, |
|
404 | Writer writer) |
|
405 | throws Exception |
|
406 | { |
|
407 | 0 | String encoding = getEncoding(context); |
408 | ||
409 | 0 | if (encoding != null) |
410 | { |
|
411 | 0 | Velocity.mergeTemplate(filename, encoding, context, writer); |
412 | } |
|
413 | else |
|
414 | { |
|
415 | 0 | Velocity.mergeTemplate(filename, context, writer); |
416 | } |
|
417 | 0 | } |
418 | ||
419 | /** |
|
420 | * Retrieve the required charset from the Turbine RunData in the context |
|
421 | * |
|
422 | * @param context A Context. |
|
423 | * @return The character set applied to the resulting String. |
|
424 | */ |
|
425 | private String getCharSet(Context context) |
|
426 | { |
|
427 | 0 | String charset = null; |
428 | ||
429 | 0 | Object data = context.get(VelocityService.RUNDATA_KEY); |
430 | 0 | if ((data != null) && (data instanceof RunData)) |
431 | { |
|
432 | 0 | charset = ((RunData) data).getCharSet(); |
433 | } |
|
434 | ||
435 | 0 | return (StringUtils.isEmpty(charset)) ? DEFAULT_CHAR_SET : charset; |
436 | } |
|
437 | ||
438 | /** |
|
439 | * Retrieve the required encoding from the Turbine RunData in the context |
|
440 | * |
|
441 | * @param context A Context. |
|
442 | * @return The encoding applied to the resulting String. |
|
443 | */ |
|
444 | private String getEncoding(Context context) |
|
445 | { |
|
446 | 0 | String encoding = null; |
447 | ||
448 | 0 | Object data = context.get(VelocityService.RUNDATA_KEY); |
449 | 0 | if ((data != null) && (data instanceof RunData)) |
450 | { |
|
451 | 0 | encoding = ((RunData) data).getTemplateEncoding(); |
452 | } |
|
453 | ||
454 | 0 | return encoding; |
455 | } |
|
456 | ||
457 | /** |
|
458 | * Macro to handle rendering errors. |
|
459 | * |
|
460 | * @param filename The file name of the unrenderable template. |
|
461 | * @param e The error. |
|
462 | * |
|
463 | * @exception TurbineException Thrown every time. Adds additional |
|
464 | * information to <code>e</code>. |
|
465 | */ |
|
466 | private static void renderingError(String filename, Exception e) |
|
467 | throws TurbineException |
|
468 | { |
|
469 | 0 | String err = "Error rendering Velocity template: " + filename; |
470 | 0 | log.error(err, e); |
471 | 0 | throw new TurbineException(err, e); |
472 | } |
|
473 | ||
474 | /** |
|
475 | * Setup the velocity runtime by using a subset of the |
|
476 | * Turbine configuration which relates to velocity. |
|
477 | * |
|
478 | * @exception Exception An Error occured. |
|
479 | */ |
|
480 | private synchronized void initVelocity() |
|
481 | throws Exception |
|
482 | { |
|
483 | // Get the configuration for this service. |
|
484 | 42 | Configuration conf = getConfiguration(); |
485 | ||
486 | 42 | catchErrors = conf.getBoolean(CATCH_ERRORS_KEY, CATCH_ERRORS_DEFAULT); |
487 | ||
488 | 42 | conf.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM_CLASS, |
489 | SimpleLog4JLogSystem.class.getName()); |
|
490 | 42 | conf.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM |
491 | + ".log4j.category", "velocity"); |
|
492 | ||
493 | 42 | Velocity.setExtendedProperties(createVelocityProperties(conf)); |
494 | 42 | Velocity.init(); |
495 | 42 | } |
496 | ||
497 | ||
498 | /** |
|
499 | * This method generates the Extended Properties object necessary |
|
500 | * for the initialization of Velocity. It also converts the various |
|
501 | * resource loader pathes into webapp relative pathes. It also |
|
502 | * |
|
503 | * @param conf The Velocity Service configuration |
|
504 | * |
|
505 | * @return An ExtendedProperties Object for Velocity |
|
506 | * |
|
507 | * @throws Exception If a problem occured while converting the properties. |
|
508 | */ |
|
509 | ||
510 | public ExtendedProperties createVelocityProperties(Configuration conf) |
|
511 | throws Exception |
|
512 | { |
|
513 | // This bugger is public, because we want to run some Unit tests |
|
514 | // on it. |
|
515 | ||
516 | 44 | ExtendedProperties veloConfig = new ExtendedProperties(); |
517 | ||
518 | // Fix up all the template resource loader pathes to be |
|
519 | // webapp relative. Copy all other keys verbatim into the |
|
520 | // veloConfiguration. |
|
521 | ||
522 | 568 | for (Iterator i = conf.getKeys(); i.hasNext();) |
523 | { |
|
524 | 1004 | String key = (String) i.next(); |
525 | 1004 | if (!key.endsWith(RESOURCE_LOADER_PATH)) |
526 | { |
|
527 | 816 | Object value = conf.getProperty(key); |
528 | ||
529 | // Since 1.0-pre-something, Commons Collections suddently |
|
530 | // no longer returns a vector for multiple value-keys but a |
|
531 | // List object. Velocity will choke if we add this object because |
|
532 | // org.apache.commons.collections.ExtendedProperties expect a |
|
533 | // Vector object. Ah, the joys of incompatible class changes, |
|
534 | // unwritten assumptions and general Java JAR Hell... =8-O |
|
535 | 816 | if (value instanceof List) |
536 | { |
|
537 | 26 | List srcValue = (List) value; |
538 | 26 | Vector targetValue = new Vector(srcValue.size()); |
539 | ||
540 | 65 | for (Iterator it = srcValue.iterator(); it.hasNext(); ) |
541 | { |
|
542 | 52 | targetValue.add(it.next()); |
543 | } |
|
544 | ||
545 | 26 | veloConfig.addProperty(key, targetValue); |
546 | } |
|
547 | else |
|
548 | { |
|
549 | 790 | veloConfig.addProperty(key, value); |
550 | } |
|
551 | ||
552 | 790 | continue; // for() |
553 | } |
|
554 | ||
555 | 188 | List paths = conf.getList(key, null); |
556 | 188 | if (paths == null) |
557 | { |
|
558 | // We don't copy this into VeloProperties, because |
|
559 | // null value is unhealthy for the ExtendedProperties object... |
|
560 | 0 | continue; // for() |
561 | } |
|
562 | ||
563 | 188 | Velocity.clearProperty(key); |
564 | ||
565 | // Translate the supplied pathes given here. |
|
566 | // the following three different kinds of |
|
567 | // pathes must be translated to be webapp-relative |
|
568 | // |
|
569 | // jar:file://path-component!/entry-component |
|
570 | // file://path-component |
|
571 | // path/component |
|
572 | ||
573 | 376 | for (Iterator j = paths.iterator(); j.hasNext();) |
574 | { |
|
575 | 188 | String path = (String) j.next(); |
576 | ||
577 | 188 | log.debug("Translating " + path); |
578 | ||
579 | 188 | if (path.startsWith(JAR_PREFIX)) |
580 | { |
|
581 | // skip jar: -> 4 chars |
|
582 | 72 | if (path.substring(4).startsWith(ABSOLUTE_PREFIX)) |
583 | { |
|
584 | // We must convert up to the jar path separator |
|
585 | 54 | int jarSepIndex = path.indexOf("!/"); |
586 | ||
587 | // jar:file:// -> skip 11 chars |
|
588 | 54 | path = (jarSepIndex < 0) |
589 | ? Turbine.getRealPath(path.substring(11)) |
|
590 | // Add the path after the jar path separator again to the new url. |
|
591 | : (Turbine.getRealPath(path.substring(11, jarSepIndex)) + path.substring(jarSepIndex)); |
|
592 | ||
593 | 54 | log.debug("Result (absolute jar path): " + path); |
594 | } |
|
595 | } |
|
596 | 116 | else if (path.startsWith(ABSOLUTE_PREFIX)) |
597 | { |
|
598 | // skip file:// -> 7 chars |
|
599 | 18 | path = Turbine.getRealPath(path.substring(7)); |
600 | ||
601 | 18 | log.debug("Result (absolute URL Path): " + path); |
602 | } |
|
603 | // Test if this might be some sort of URL that we haven't encountered yet. |
|
604 | 98 | else if (path.indexOf("://") < 0) |
605 | { |
|
606 | 80 | path = Turbine.getRealPath(path); |
607 | ||
608 | 80 | log.debug("Result (normal fs reference): " + path); |
609 | } |
|
610 | ||
611 | 188 | log.debug("Adding " + key + " -> " + path); |
612 | // Re-Add this property to the configuration object |
|
613 | 188 | veloConfig.addProperty(key, path); |
614 | } |
|
615 | } |
|
616 | 44 | return veloConfig; |
617 | } |
|
618 | ||
619 | /** |
|
620 | * Find out if a given template exists. Velocity |
|
621 | * will do its own searching to determine whether |
|
622 | * a template exists or not. |
|
623 | * |
|
624 | * @param template String template to search for |
|
625 | * @return True if the template can be loaded by Velocity |
|
626 | */ |
|
627 | public boolean templateExists(String template) |
|
628 | { |
|
629 | 46 | return Velocity.templateExists(template); |
630 | } |
|
631 | ||
632 | /** |
|
633 | * Performs post-request actions (releases context |
|
634 | * tools back to the object pool). |
|
635 | * |
|
636 | * @param context a Velocity Context |
|
637 | */ |
|
638 | public void requestFinished(Context context) |
|
639 | { |
|
640 | 0 | if (pullModelActive) |
641 | { |
|
642 | 0 | pullService.releaseTools(context); |
643 | } |
|
644 | 0 | } |
645 | } |
This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |