1 package org.apache.velocity.app;
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.BufferedReader;
23 import java.io.InputStream;
24 import java.io.InputStreamReader;
25 import java.io.Reader;
26 import java.io.UnsupportedEncodingException;
27 import java.io.Writer;
28 import java.util.Properties;
29
30 import org.apache.commons.collections.ExtendedProperties;
31 import org.apache.velocity.Template;
32 import org.apache.velocity.context.Context;
33 import org.apache.velocity.exception.MethodInvocationException;
34 import org.apache.velocity.exception.ParseErrorException;
35 import org.apache.velocity.exception.ResourceNotFoundException;
36 import org.apache.velocity.runtime.RuntimeConstants;
37 import org.apache.velocity.runtime.RuntimeSingleton;
38 import org.apache.velocity.runtime.log.Log;
39
40 /**
41 * This class provides services to the application
42 * developer, such as :
43 * <ul>
44 * <li> Simple Velocity Runtime engine initialization methods.
45 * <li> Functions to apply the template engine to streams and strings
46 * to allow embedding and dynamic template generation.
47 * <li> Methods to access Velocimacros directly.
48 * </ul>
49 *
50 * <br><br>
51 * While the most common way to use Velocity is via templates, as
52 * Velocity is a general-purpose template engine, there are other
53 * uses that Velocity is well suited for, such as processing dynamically
54 * created templates, or processing content streams.
55 *
56 * <br><br>
57 * The methods herein were developed to allow easy access to the Velocity
58 * facilities without direct spelunking of the internals. If there is
59 * something you feel is necessary to add here, please, send a patch.
60 *
61 * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
62 * @author <a href="mailto:Christoph.Reck@dlr.de">Christoph Reck</a>
63 * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
64 * @version $Id: Velocity.java 898050 2010-01-11 20:15:31Z nbubna $
65 */
66 public class Velocity implements RuntimeConstants
67 {
68 /**
69 * initialize the Velocity runtime engine, using the default
70 * properties of the Velocity distribution
71 */
72 public static void init()
73 {
74 RuntimeSingleton.init();
75 }
76
77 /**
78 * initialize the Velocity runtime engine, using default properties
79 * plus the properties in the properties file passed in as the arg
80 *
81 * @param propsFilename file containing properties to use to initialize
82 * the Velocity runtime
83 */
84 public static void init( String propsFilename )
85 {
86 RuntimeSingleton.init(propsFilename);
87 }
88
89 /**
90 * initialize the Velocity runtime engine, using default properties
91 * plus the properties in the passed in java.util.Properties object
92 *
93 * @param p Properties object containing initialization properties
94 */
95 public static void init( Properties p )
96 {
97 RuntimeSingleton.init( p );
98 }
99
100 /**
101 * Set a Velocity Runtime property.
102 *
103 * @param key The property key.
104 * @param value The property value.
105 */
106 public static void setProperty(String key, Object value)
107 {
108 RuntimeSingleton.setProperty(key,value);
109 }
110
111 /**
112 * Add a Velocity Runtime property.
113 *
114 * @param key The property key.
115 * @param value The property value.
116 */
117 public static void addProperty(String key, Object value)
118 {
119 RuntimeSingleton.addProperty(key,value);
120 }
121
122 /**
123 * Clear a Velocity Runtime property.
124 *
125 * @param key of property to clear
126 */
127 public static void clearProperty(String key)
128 {
129 RuntimeSingleton.clearProperty(key);
130 }
131
132 /**
133 * Set an entire configuration at once. This is
134 * useful in cases where the parent application uses
135 * the ExtendedProperties class and the velocity configuration
136 * is a subset of the parent application's configuration.
137 *
138 * @param configuration A configuration object.
139 *
140 */
141 public static void setExtendedProperties( ExtendedProperties configuration)
142 {
143 RuntimeSingleton.setConfiguration( configuration );
144 }
145
146 /**
147 * Get a Velocity Runtime property.
148 *
149 * @param key property to retrieve
150 * @return property value or null if the property
151 * not currently set
152 */
153 public static Object getProperty( String key )
154 {
155 return RuntimeSingleton.getProperty( key );
156 }
157
158 /**
159 * renders the input string using the context into the output writer.
160 * To be used when a template is dynamically constructed, or want to use
161 * Velocity as a token replacer.
162 *
163 * @param context context to use in rendering input string
164 * @param out Writer in which to render the output
165 * @param logTag string to be used as the template name for log
166 * messages in case of error
167 * @param instring input string containing the VTL to be rendered
168 *
169 * @return true if successful, false otherwise. If false, see
170 * Velocity runtime log
171 * @throws ParseErrorException The template could not be parsed.
172 * @throws MethodInvocationException A method on a context object could not be invoked.
173 * @throws ResourceNotFoundException A referenced resource could not be loaded.
174 */
175 public static boolean evaluate( Context context, Writer out,
176 String logTag, String instring )
177 throws ParseErrorException, MethodInvocationException,
178 ResourceNotFoundException
179 {
180 return RuntimeSingleton.getRuntimeServices()
181 .evaluate(context, out, logTag, instring);
182 }
183
184 /**
185 * Renders the input stream using the context into the output writer.
186 * To be used when a template is dynamically constructed, or want to
187 * use Velocity as a token replacer.
188 *
189 * @param context context to use in rendering input string
190 * @param writer Writer in which to render the output
191 * @param logTag string to be used as the template name for log messages
192 * in case of error
193 * @param instream input stream containing the VTL to be rendered
194 *
195 * @return true if successful, false otherwise. If false, see
196 * Velocity runtime log
197 * @deprecated Use
198 * {@link #evaluate( Context context, Writer writer,
199 * String logTag, Reader reader ) }
200 * @throws ParseErrorException The template could not be parsed.
201 * @throws MethodInvocationException A method on a context object could not be invoked.
202 * @throws ResourceNotFoundException A referenced resource could not be loaded.
203 * @throws IOException While loading a reference, an I/O problem occured.
204 */
205 public static boolean evaluate( Context context, Writer writer,
206 String logTag, InputStream instream )
207 throws ParseErrorException, MethodInvocationException,
208 ResourceNotFoundException
209 {
210 /*
211 * first, parse - convert ParseException if thrown
212 */
213 BufferedReader br = null;
214 String encoding = null;
215
216 try
217 {
218 encoding = RuntimeSingleton.getString(INPUT_ENCODING,ENCODING_DEFAULT);
219 br = new BufferedReader( new InputStreamReader( instream, encoding));
220 }
221 catch( UnsupportedEncodingException uce )
222 {
223 String msg = "Unsupported input encoding : " + encoding
224 + " for template " + logTag;
225 throw new ParseErrorException( msg );
226 }
227
228 return evaluate( context, writer, logTag, br );
229 }
230
231 /**
232 * Renders the input reader using the context into the output writer.
233 * To be used when a template is dynamically constructed, or want to
234 * use Velocity as a token replacer.
235 *
236 * @param context context to use in rendering input string
237 * @param writer Writer in which to render the output
238 * @param logTag string to be used as the template name for log messages
239 * in case of error
240 * @param reader Reader containing the VTL to be rendered
241 *
242 * @return true if successful, false otherwise. If false, see
243 * Velocity runtime log
244 * @throws ParseErrorException The template could not be parsed.
245 * @throws MethodInvocationException A method on a context object could not be invoked.
246 * @throws ResourceNotFoundException A referenced resource could not be loaded.
247 * @since Velocity v1.1
248 */
249 public static boolean evaluate( Context context, Writer writer,
250 String logTag, Reader reader )
251 throws ParseErrorException, MethodInvocationException,
252 ResourceNotFoundException
253 {
254 return RuntimeSingleton.getRuntimeServices().evaluate(context, writer,
255 logTag, reader);
256 }
257
258 /**
259 * Invokes a currently registered Velocimacro with the params provided
260 * and places the rendered stream into the writer.
261 * <br>
262 * Note : currently only accepts args to the VM if they are in the context.
263 *
264 * @param vmName name of Velocimacro to call
265 * @param logTag string to be used for template name in case of error. if null,
266 * the vmName will be used
267 * @param params keys for args used to invoke Velocimacro, in java format
268 * rather than VTL (eg "foo" or "bar" rather than "$foo" or "$bar")
269 * @param context Context object containing data/objects used for rendering.
270 * @param writer Writer for output stream
271 * @return true if Velocimacro exists and successfully invoked, false otherwise.
272 */
273 public static boolean invokeVelocimacro( String vmName, String logTag,
274 String params[], Context context,
275 Writer writer )
276 {
277 return RuntimeSingleton.getRuntimeServices()
278 .invokeVelocimacro(vmName, logTag, params, context, writer);
279 }
280
281 /**
282 * Merges a template and puts the rendered stream into the writer.
283 * The default encoding that Velocity uses to read template files is defined in
284 * the property input.encoding and defaults to ISO-8859-1.
285 *
286 * @param templateName name of template to be used in merge
287 * @param context filled context to be used in merge
288 * @param writer writer to write template into
289 *
290 * @return true if successful, false otherwise. Errors
291 * logged to velocity log.
292 * @deprecated Use
293 * {@link #mergeTemplate( String templateName, String encoding,
294 * Context context, Writer writer )}
295 * @throws ParseErrorException The template could not be parsed.
296 * @throws MethodInvocationException A method on a context object could not be invoked.
297 * @throws ResourceNotFoundException A referenced resource could not be loaded.
298 */
299 public static boolean mergeTemplate( String templateName,
300 Context context, Writer writer )
301 throws ResourceNotFoundException, ParseErrorException, MethodInvocationException
302 {
303 return mergeTemplate( templateName, RuntimeSingleton.getString(INPUT_ENCODING,ENCODING_DEFAULT),
304 context, writer );
305 }
306
307 /**
308 * merges a template and puts the rendered stream into the writer
309 *
310 * @param templateName name of template to be used in merge
311 * @param encoding encoding used in template
312 * @param context filled context to be used in merge
313 * @param writer writer to write template into
314 *
315 * @return true if successful, false otherwise. Errors
316 * logged to velocity log
317 *
318 * @throws ParseErrorException The template could not be parsed.
319 * @throws MethodInvocationException A method on a context object could not be invoked.
320 * @throws ResourceNotFoundException A referenced resource could not be loaded.
321 *
322 * @since Velocity v1.1
323 */
324 public static boolean mergeTemplate( String templateName, String encoding,
325 Context context, Writer writer )
326 throws ResourceNotFoundException, ParseErrorException, MethodInvocationException
327 {
328 Template template = RuntimeSingleton.getTemplate(templateName, encoding);
329
330 if ( template == null )
331 {
332 String msg = "Velocity.mergeTemplate() was unable to load template '"
333 + templateName + "'";
334 getLog().error(msg);
335 throw new ResourceNotFoundException(msg);
336 }
337 else
338 {
339 template.merge(context, writer);
340 return true;
341 }
342 }
343
344 /**
345 * Returns a <code>Template</code> from the Velocity
346 * resource management system.
347 *
348 * @param name The file name of the desired template.
349 * @return The template.
350 * @throws ResourceNotFoundException if template not found
351 * from any available source.
352 * @throws ParseErrorException if template cannot be parsed due
353 * to syntax (or other) error.
354 */
355 public static Template getTemplate(String name)
356 throws ResourceNotFoundException, ParseErrorException
357 {
358 return RuntimeSingleton.getTemplate( name );
359 }
360
361 /**
362 * Returns a <code>Template</code> from the Velocity
363 * resource management system.
364 *
365 * @param name The file name of the desired template.
366 * @param encoding The character encoding to use for the template.
367 * @return The template.
368 * @throws ResourceNotFoundException if template not found
369 * from any available source.
370 * @throws ParseErrorException if template cannot be parsed due
371 * to syntax (or other) error.
372 *
373 * @since Velocity v1.1
374 */
375 public static Template getTemplate(String name, String encoding)
376 throws ResourceNotFoundException, ParseErrorException
377 {
378 return RuntimeSingleton.getTemplate( name, encoding );
379 }
380
381 /**
382 * <p>Determines whether a resource is accessable via the
383 * currently configured resource loaders. {@link
384 * org.apache.velocity.runtime.resource.Resource} is the generic
385 * description of templates, static content, etc.</p>
386 *
387 * <p>Note that the current implementation will <b>not</b> change
388 * the state of the system in any real way - so this cannot be
389 * used to pre-load the resource cache, as the previous
390 * implementation did as a side-effect.</p>
391 *
392 * @param resourceName The name of the resource to search for.
393 * @return Whether the resource was located.
394 */
395 public static boolean resourceExists(String resourceName)
396 {
397 return (RuntimeSingleton.getLoaderNameForResource(resourceName) != null);
398 }
399
400 /**
401 * Returns a convenient Log instance that wraps the current LogChute.
402 * Use this to log error messages. It has the usual methods.
403 *
404 * @return A convenience Log instance that wraps the current LogChute.
405 * @since 1.5
406 */
407 public static Log getLog()
408 {
409 return RuntimeSingleton.getLog();
410 }
411
412 /**
413 * @deprecated Use getLog() and call warn() on it.
414 * @see Log#warn(Object)
415 * @param message The message to log.
416 */
417 public static void warn(Object message)
418 {
419 getLog().warn( message );
420 }
421
422 /**
423 * @deprecated Use getLog() and call info() on it.
424 * @see Log#info(Object)
425 * @param message The message to log.
426 */
427 public static void info(Object message)
428 {
429 getLog().info( message );
430 }
431
432 /**
433 * @deprecated Use getLog() and call error() on it.
434 * @see Log#error(Object)
435 * @param message The message to log.
436 */
437 public static void error(Object message)
438 {
439 getLog().error( message );
440 }
441
442 /**
443 * @deprecated Use getLog() and call debug() on it.
444 * @see Log#debug(Object)
445 * @param message The message to log.
446 */
447 public static void debug(Object message)
448 {
449 getLog().debug( message );
450 }
451
452 /**
453 * <p>
454 * Set the an ApplicationAttribue, which is an Object
455 * set by the application which is accessable from
456 * any component of the system that gets a RuntimeServices.
457 * This allows communication between the application
458 * environment and custom pluggable components of the
459 * Velocity engine, such as loaders and loggers.
460 * </p>
461 *
462 * <p>
463 * Note that there is no enfocement or rules for the key
464 * used - it is up to the application developer. However, to
465 * help make the intermixing of components possible, using
466 * the target Class name (e.g. com.foo.bar ) as the key
467 * might help avoid collision.
468 * </p>
469 *
470 * @param key object 'name' under which the object is stored
471 * @param value object to store under this key
472 */
473 public static void setApplicationAttribute( Object key, Object value )
474 {
475 RuntimeSingleton.getRuntimeInstance().setApplicationAttribute( key, value);
476 }
477
478 /**
479 * @param resourceName Name of the Template to check.
480 * @return True if the template exists.
481 * @see #resourceExists(String)
482 * @deprecated Use resourceExists(String) instead.
483 */
484 public static boolean templateExists(String resourceName)
485 {
486 return resourceExists(resourceName);
487 }
488
489 /**
490 * Remove a directive.
491 *
492 * @param name name of the directive.
493 */
494 public void removeDirective(String name)
495 {
496 RuntimeSingleton.removeDirective(name);
497 }
498
499 /**
500 * Instantiates and loads the directive with some basic checks.
501 *
502 * @param directiveClass classname of directive to load
503 */
504 public void loadDirective(String directiveClass)
505 {
506 RuntimeSingleton.loadDirective(directiveClass);
507 }
508 }