View Javadoc

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