1 package org.apache.velocity.runtime;
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.Reader;
23 import java.util.Properties;
24
25 import org.apache.commons.collections.ExtendedProperties;
26 import org.apache.velocity.Template;
27 import org.apache.velocity.app.event.EventCartridge;
28 import org.apache.velocity.exception.ParseErrorException;
29 import org.apache.velocity.exception.ResourceNotFoundException;
30 import org.apache.velocity.runtime.directive.Directive;
31 import org.apache.velocity.runtime.log.Log;
32 import org.apache.velocity.runtime.parser.ParseException;
33 import org.apache.velocity.runtime.parser.node.Node;
34 import org.apache.velocity.runtime.parser.node.SimpleNode;
35 import org.apache.velocity.runtime.resource.ContentResource;
36 import org.apache.velocity.util.introspection.Introspector;
37 import org.apache.velocity.util.introspection.Uberspect;
38
39 /**
40 * This is the Runtime system for Velocity. It is the
41 * single access point for all functionality in Velocity.
42 * It adheres to the mediator pattern and is the only
43 * structure that developers need to be familiar with
44 * in order to get Velocity to perform.
45 *
46 * The Runtime will also cooperate with external
47 * systems like Turbine. Runtime properties can
48 * set and then the Runtime is initialized.
49 *
50 * Turbine for example knows where the templates
51 * are to be loaded from, and where the velocity
52 * log file should be placed.
53 *
54 * So in the case of Velocity cooperating with Turbine
55 * the code might look something like the following:
56 *
57 * <pre>
58 * RuntimeSingleton.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, templatePath);
59 * RuntimeSingleton.setProperty(RuntimeConstants.RUNTIME_LOG, pathToVelocityLog);
60 * RuntimeSingleton.init();
61 * </pre>
62 *
63 * <pre>
64 * -----------------------------------------------------------------------
65 * N O T E S O N R U N T I M E I N I T I A L I Z A T I O N
66 * -----------------------------------------------------------------------
67 * RuntimeSingleton.init()
68 *
69 * If Runtime.init() is called by itself the Runtime will
70 * initialize with a set of default values.
71 * -----------------------------------------------------------------------
72 * RuntimeSingleton.init(String/Properties)
73 *
74 * In this case the default velocity properties are layed down
75 * first to provide a solid base, then any properties provided
76 * in the given properties object will override the corresponding
77 * default property.
78 * -----------------------------------------------------------------------
79 * </pre>
80 *
81 * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
82 * @author <a href="mailto:jlb@houseofdistraction.com">Jeff Bowden</a>
83 * @author <a href="mailto:geirm@optonline.net">Geir Magusson Jr.</a>
84 * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
85 *
86 * @see org.apache.velocity.runtime.RuntimeInstance
87 *
88 * @version $Id: RuntimeSingleton.java 898050 2010-01-11 20:15:31Z nbubna $
89 */
90 public class RuntimeSingleton implements RuntimeConstants
91 {
92 private static RuntimeInstance ri = new RuntimeInstance();
93
94 /**
95 * This is the primary initialization method in the Velocity
96 * Runtime. The systems that are setup/initialized here are
97 * as follows:
98 *
99 * <ul>
100 * <li>Logging System</li>
101 * <li>ResourceManager</li>
102 * <li>Event Handlers</li>
103 * <li>Parser Pool</li>
104 * <li>Global Cache</li>
105 * <li>Static Content Include System</li>
106 * <li>Velocimacro System</li>
107 * </ul>
108 * @see RuntimeInstance#init()
109 */
110 public synchronized static void init()
111 {
112 ri.init();
113 }
114
115 /**
116 * Returns true if the RuntimeInstance has been successfully initialized.
117 * @return True if the RuntimeInstance has been successfully initialized.
118 * @see RuntimeInstance#isInitialized()
119 * @since 1.5
120 */
121 public static boolean isInitialized()
122 {
123 return ri.isInitialized();
124 }
125
126 /**
127 * Returns the RuntimeServices Instance used by this wrapper.
128 *
129 * @return The RuntimeServices Instance used by this wrapper.
130 */
131 public static RuntimeServices getRuntimeServices()
132 {
133 return ri;
134 }
135
136
137 /**
138 * Allows an external system to set a property in
139 * the Velocity Runtime.
140 *
141 * @param key property key
142 * @param value property value
143 * @see RuntimeInstance#setProperty(String, Object)
144 */
145 public static void setProperty(String key, Object value)
146 {
147 ri.setProperty( key, value );
148 }
149
150 /**
151 * Allow an external system to set an ExtendedProperties
152 * object to use. This is useful where the external
153 * system also uses the ExtendedProperties class and
154 * the velocity configuration is a subset of
155 * parent application's configuration. This is
156 * the case with Turbine.
157 *
158 * @param configuration
159 * @see RuntimeInstance#setConfiguration(ExtendedProperties)
160 */
161 public static void setConfiguration( ExtendedProperties configuration)
162 {
163 ri.setConfiguration( configuration );
164 }
165
166 /**
167 * Add a property to the configuration. If it already
168 * exists then the value stated here will be added
169 * to the configuration entry. For example, if
170 *
171 * resource.loader = file
172 *
173 * is already present in the configuration and you
174 *
175 * addProperty("resource.loader", "classpath")
176 *
177 * Then you will end up with a Vector like the
178 * following:
179 *
180 * ["file", "classpath"]
181 *
182 * @param key
183 * @param value
184 * @see RuntimeInstance#addProperty(String, Object)
185 */
186 public static void addProperty(String key, Object value)
187 {
188 ri.addProperty( key, value );
189 }
190
191 /**
192 * Clear the values pertaining to a particular
193 * property.
194 *
195 * @param key of property to clear
196 * @see RuntimeInstance#clearProperty(String)
197 */
198 public static void clearProperty(String key)
199 {
200 ri.clearProperty( key );
201 }
202
203 /**
204 * Allows an external caller to get a property. The calling
205 * routine is required to know the type, as this routine
206 * will return an Object, as that is what properties can be.
207 *
208 * @param key property to return
209 * @return Value of the property or null if it does not exist.
210 * @see RuntimeInstance#getProperty(String)
211 */
212 public static Object getProperty( String key )
213 {
214 return ri.getProperty( key );
215 }
216
217 /**
218 * Initialize the Velocity Runtime with a Properties
219 * object.
220 *
221 * @param p
222 * @see RuntimeInstance#init(Properties)
223 */
224 public static void init(Properties p)
225 {
226 ri.init(p);
227 }
228
229 /**
230 * Initialize the Velocity Runtime with the name of
231 * ExtendedProperties object.
232 *
233 * @param configurationFile
234 * @see RuntimeInstance#init(String)
235 */
236 public static void init(String configurationFile)
237 {
238 ri.init( configurationFile );
239 }
240
241 /**
242 * Parse the input and return the root of
243 * AST node structure.
244 * <br><br>
245 * In the event that it runs out of parsers in the
246 * pool, it will create and let them be GC'd
247 * dynamically, logging that it has to do that. This
248 * is considered an exceptional condition. It is
249 * expected that the user will set the
250 * PARSER_POOL_SIZE property appropriately for their
251 * application. We will revisit this.
252 *
253 * @param reader Reader retrieved by a resource loader
254 * @param templateName name of the template being parsed
255 * @return A root node representing the template as an AST tree.
256 * @throws ParseException When the template could not be parsed.
257 * @see RuntimeInstance#parse(Reader, String)
258 */
259 public static SimpleNode parse( Reader reader, String templateName )
260 throws ParseException
261 {
262 return ri.parse( reader, templateName );
263 }
264
265 /**
266 * Parse the input and return the root of the AST node structure.
267 *
268 * @param reader Reader retrieved by a resource loader
269 * @param templateName name of the template being parsed
270 * @param dumpNamespace flag to dump the Velocimacro namespace for this template
271 * @return A root node representing the template as an AST tree.
272 * @throws ParseException When the template could not be parsed.
273 * @see RuntimeInstance#parse(Reader, String, boolean)
274 */
275 public static SimpleNode parse( Reader reader, String templateName, boolean dumpNamespace )
276 throws ParseException
277 {
278 return ri.parse( reader, templateName, dumpNamespace );
279 }
280
281
282 /**
283 * Returns a <code>Template</code> from the resource manager.
284 * This method assumes that the character encoding of the
285 * template is set by the <code>input.encoding</code>
286 * property. The default is "ISO-8859-1"
287 *
288 * @param name The file name of the desired template.
289 * @return The template.
290 * @throws ResourceNotFoundException if template not found
291 * from any available source.
292 * @throws ParseErrorException if template cannot be parsed due
293 * to syntax (or other) error.
294 * @see RuntimeInstance#getTemplate(String)
295 */
296 public static Template getTemplate(String name)
297 throws ResourceNotFoundException, ParseErrorException
298 {
299 return ri.getTemplate( name );
300 }
301
302 /**
303 * Returns a <code>Template</code> from the resource manager
304 *
305 * @param name The name of the desired template.
306 * @param encoding Character encoding of the template
307 * @return The template.
308 * @throws ResourceNotFoundException if template not found
309 * from any available source.
310 * @throws ParseErrorException if template cannot be parsed due
311 * to syntax (or other) error.
312 * @see RuntimeInstance#getTemplate(String, String)
313 */
314 public static Template getTemplate(String name, String encoding)
315 throws ResourceNotFoundException, ParseErrorException
316 {
317 return ri.getTemplate( name, encoding );
318 }
319
320 /**
321 * Returns a static content resource from the
322 * resource manager. Uses the current value
323 * if INPUT_ENCODING as the character encoding.
324 *
325 * @param name Name of content resource to get
326 * @return parsed ContentResource object ready for use
327 * @throws ResourceNotFoundException if template not found
328 * from any available source.
329 * @throws ParseErrorException When the template could not be parsed.
330 * @see RuntimeInstance#getContent(String)
331 */
332 public static ContentResource getContent(String name)
333 throws ResourceNotFoundException, ParseErrorException
334 {
335 return ri.getContent( name );
336 }
337
338 /**
339 * Returns a static content resource from the
340 * resource manager.
341 *
342 * @param name Name of content resource to get
343 * @param encoding Character encoding to use
344 * @return parsed ContentResource object ready for use
345 * @throws ResourceNotFoundException if template not found
346 * from any available source.
347 * @throws ParseErrorException When the template could not be parsed.
348 * @see RuntimeInstance#getContent(String, String)
349 */
350 public static ContentResource getContent( String name, String encoding )
351 throws ResourceNotFoundException, ParseErrorException
352 {
353 return ri.getContent( name, encoding );
354 }
355
356
357 /**
358 * Determines is a template exists, and returns name of the loader that
359 * provides it. This is a slightly less hokey way to support
360 * the Velocity.templateExists() utility method, which was broken
361 * when per-template encoding was introduced. We can revisit this.
362 *
363 * @param resourceName Name of template or content resource
364 * @return class name of loader than can provide it
365 * @see RuntimeInstance#getLoaderNameForResource(String)
366 */
367 public static String getLoaderNameForResource( String resourceName )
368 {
369 return ri.getLoaderNameForResource( resourceName );
370 }
371
372
373 /**
374 * Returns a convenient Log instance that wraps the current LogChute.
375 *
376 * @return A convenience Log instance that wraps the current LogChute.
377 * @see RuntimeInstance#getLog()
378 * @since 1.5
379 */
380 public static Log getLog()
381 {
382 return ri.getLog();
383 }
384
385 /**
386 * @deprecated Use getLog() and call warn() on it.
387 * @see Log#warn(Object)
388 * @param message The message to log.
389 */
390 public static void warn(Object message)
391 {
392 getLog().warn(message);
393 }
394
395 /**
396 * @deprecated Use getLog() and call info() on it.
397 * @see Log#info(Object)
398 * @param message The message to log.
399 */
400 public static void info(Object message)
401 {
402 getLog().info(message);
403 }
404
405 /**
406 * @deprecated Use getLog() and call error() on it.
407 * @see Log#error(Object)
408 * @param message The message to log.
409 */
410 public static void error(Object message)
411 {
412 getLog().error(message);
413 }
414
415 /**
416 * @deprecated Use getLog() and call debug() on it.
417 * @see Log#debug(Object)
418 * @param message The message to log.
419 */
420 public static void debug(Object message)
421 {
422 getLog().debug(message);
423 }
424
425 /**
426 * String property accessor method with default to hide the
427 * configuration implementation.
428 *
429 * @param key property key
430 * @param defaultValue default value to return if key not
431 * found in resource manager.
432 * @return value of key or default
433 * @see RuntimeInstance#getString(String, String)
434 */
435 public static String getString( String key, String defaultValue)
436 {
437 return ri.getString( key, defaultValue );
438 }
439
440 /**
441 * Returns the appropriate VelocimacroProxy object if strVMname
442 * is a valid current Velocimacro.
443 *
444 * @param vmName Name of velocimacro requested
445 * @param templateName Name of the template that contains the velocimacro.
446 * @return The requested VelocimacroProxy.
447 * @see RuntimeInstance#getVelocimacro(String, String)
448 */
449 public static Directive getVelocimacro( String vmName, String templateName )
450 {
451 return ri.getVelocimacro( vmName, templateName );
452 }
453
454 /**
455 * Adds a new Velocimacro. Usually called by Macro only while parsing.
456 *
457 * @param name Name of a new velocimacro.
458 * @param macro root AST node of the parsed macro
459 * @param argArray Array of strings, containing the
460 * #macro() arguments. the 0th argument is the name.
461 * @param sourceTemplate The template from which the macro is requested.
462 * @return boolean True if added, false if rejected for some
463 * reason (either parameters or permission settings)
464 * @see RuntimeInstance#addVelocimacro(String, Node, String[], String)
465 * @since 1.6
466 */
467 public static boolean addVelocimacro(String name, Node macro,
468 String argArray[], String sourceTemplate)
469 {
470 return ri.addVelocimacro(name, macro, argArray, sourceTemplate);
471 }
472
473 /**
474 * Adds a new Velocimacro. Usually called by Macro only while parsing.
475 *
476 * @param name Name of velocimacro
477 * @param macro String form of macro body
478 * @param argArray Array of strings, containing the
479 * #macro() arguments. the 0th is the name.
480 * @param sourceTemplate Name of the template that contains the velocimacro.
481 * @return True if added, false if rejected for some
482 * reason (either parameters or permission settings)
483 *
484 * @deprecated Use addVelocimacro(String, Node, String[], String) instead
485 *
486 * @see RuntimeInstance#addVelocimacro(String, String, String[], String)
487 */
488 public static boolean addVelocimacro( String name,
489 String macro,
490 String argArray[],
491 String sourceTemplate )
492 {
493 return ri.addVelocimacro( name, macro, argArray, sourceTemplate );
494 }
495
496 /**
497 * Checks to see if a VM exists
498 *
499 * @param vmName Name of the Velocimacro.
500 * @param templateName Template on which to look for the Macro.
501 * @return True if VM by that name exists, false if not
502 * @see RuntimeInstance#isVelocimacro(String, String)
503 */
504 public static boolean isVelocimacro( String vmName, String templateName )
505 {
506 return ri.isVelocimacro( vmName, templateName );
507 }
508
509 /**
510 * tells the vmFactory to dump the specified namespace. This is to support
511 * clearing the VM list when in inline-VM-local-scope mode
512 * @param namespace Namespace to dump.
513 * @return True if namespace was dumped successfully.
514 * @see RuntimeInstance#dumpVMNamespace(String)
515 */
516 public static boolean dumpVMNamespace( String namespace )
517 {
518 return ri.dumpVMNamespace( namespace );
519 }
520
521 /* --------------------------------------------------------------------
522 * R U N T I M E A C C E S S O R M E T H O D S
523 * --------------------------------------------------------------------
524 * These are the getXXX() methods that are a simple wrapper
525 * around the configuration object. This is an attempt
526 * to make a the Velocity Runtime the single access point
527 * for all things Velocity, and allow the Runtime to
528 * adhere as closely as possible the the Mediator pattern
529 * which is the ultimate goal.
530 * --------------------------------------------------------------------
531 */
532
533 /**
534 * String property accessor method to hide the configuration implementation
535 * @param key property key
536 * @return value of key or null
537 * @see RuntimeInstance#getString(String)
538 */
539 public static String getString(String key)
540 {
541 return ri.getString( key );
542 }
543
544 /**
545 * Int property accessor method to hide the configuration implementation.
546 *
547 * @param key Property key
548 * @return value
549 * @see RuntimeInstance#getInt(String)
550 */
551 public static int getInt( String key )
552 {
553 return ri.getInt( key );
554 }
555
556 /**
557 * Int property accessor method to hide the configuration implementation.
558 *
559 * @param key property key
560 * @param defaultValue The default value.
561 * @return value
562 * @see RuntimeInstance#getInt(String, int)
563 */
564 public static int getInt( String key, int defaultValue )
565 {
566 return ri.getInt( key, defaultValue );
567 }
568
569 /**
570 * Boolean property accessor method to hide the configuration implementation.
571 *
572 * @param key property key
573 * @param def The default value if property not found.
574 * @return value of key or default value
575 * @see RuntimeInstance#getBoolean(String, boolean)
576 */
577 public static boolean getBoolean( String key, boolean def )
578 {
579 return ri.getBoolean( key, def );
580 }
581
582 /**
583 * Return the velocity runtime configuration object.
584 *
585 * @return ExtendedProperties configuration object which houses
586 * the velocity runtime properties.
587 * @see RuntimeInstance#getConfiguration()
588 */
589 public static ExtendedProperties getConfiguration()
590 {
591 return ri.getConfiguration();
592 }
593
594 /**
595 * Return the Introspector for this RuntimeInstance
596 *
597 * @return Introspector object for this runtime instance
598 * @see RuntimeInstance#getIntrospector()
599 */
600 public static Introspector getIntrospector()
601 {
602 return ri.getIntrospector();
603 }
604
605 /**
606 * Returns the event handlers for the application.
607 * @return The event handlers for the application.
608 * @see RuntimeInstance#getApplicationEventCartridge()
609 * @since 1.5
610 */
611 public EventCartridge getEventCartridge()
612 {
613 return ri.getApplicationEventCartridge();
614 }
615
616 /**
617 * Gets the application attribute for the given key
618 *
619 * @see org.apache.velocity.runtime.RuntimeServices#getApplicationAttribute(Object)
620 * @param key
621 * @return The application attribute for the given key.
622 * @see RuntimeInstance#getApplicationAttribute(Object)
623 */
624 public static Object getApplicationAttribute(Object key)
625 {
626 return ri.getApplicationAttribute(key);
627 }
628
629 /**
630 * Returns the Uberspect object for this Instance.
631 *
632 * @return The Uberspect object for this Instance.
633 * @see org.apache.velocity.runtime.RuntimeServices#getUberspect()
634 * @see RuntimeInstance#getUberspect()
635 */
636 public static Uberspect getUberspect()
637 {
638 return ri.getUberspect();
639 }
640
641 /**
642 * @deprecated Use getRuntimeServices() instead.
643 * @return The RuntimeInstance used by this Singleton.
644 */
645 public static RuntimeInstance getRuntimeInstance()
646 {
647 return ri;
648 }
649
650 /**
651 * Remove a directive.
652 *
653 * @param name name of the directive.
654 */
655 public static void removeDirective(String name)
656 {
657 ri.removeDirective(name);
658 }
659
660 /**
661 * Instantiates and loads the directive with some basic checks.
662 *
663 * @param directiveClass classname of directive to load
664 */
665 public static void loadDirective(String directiveClass)
666 {
667 ri.loadDirective(directiveClass);
668 }
669 }