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