001: package org.apache.velocity.runtime;
002:
003: /*
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021:
022: import java.io.Reader;
023: import java.util.Properties;
024:
025: import org.apache.commons.collections.ExtendedProperties;
026: import org.apache.velocity.Template;
027: import org.apache.velocity.app.event.EventCartridge;
028: import org.apache.velocity.exception.ParseErrorException;
029: import org.apache.velocity.exception.ResourceNotFoundException;
030: import org.apache.velocity.runtime.directive.Directive;
031: import org.apache.velocity.runtime.log.Log;
032: import org.apache.velocity.runtime.parser.ParseException;
033: import org.apache.velocity.runtime.parser.node.SimpleNode;
034: import org.apache.velocity.runtime.resource.ContentResource;
035: import org.apache.velocity.util.introspection.Introspector;
036: import org.apache.velocity.util.introspection.Uberspect;
037:
038: /**
039: * This is the Runtime system for Velocity. It is the
040: * single access point for all functionality in Velocity.
041: * It adheres to the mediator pattern and is the only
042: * structure that developers need to be familiar with
043: * in order to get Velocity to perform.
044: *
045: * The Runtime will also cooperate with external
046: * systems like Turbine. Runtime properties can
047: * set and then the Runtime is initialized.
048: *
049: * Turbine for example knows where the templates
050: * are to be loaded from, and where the velocity
051: * log file should be placed.
052: *
053: * So in the case of Velocity cooperating with Turbine
054: * the code might look something like the following:
055: *
056: * <pre>
057: * RuntimeSingleton.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, templatePath);
058: * RuntimeSingleton.setProperty(RuntimeConstants.RUNTIME_LOG, pathToVelocityLog);
059: * RuntimeSingleton.init();
060: * </pre>
061: *
062: * <pre>
063: * -----------------------------------------------------------------------
064: * 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
065: * -----------------------------------------------------------------------
066: * RuntimeSingleton.init()
067: *
068: * If Runtime.init() is called by itself the Runtime will
069: * initialize with a set of default values.
070: * -----------------------------------------------------------------------
071: * RuntimeSingleton.init(String/Properties)
072: *
073: * In this case the default velocity properties are layed down
074: * first to provide a solid base, then any properties provided
075: * in the given properties object will override the corresponding
076: * default property.
077: * -----------------------------------------------------------------------
078: * </pre>
079: *
080: * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
081: * @author <a href="mailto:jlb@houseofdistraction.com">Jeff Bowden</a>
082: * @author <a href="mailto:geirm@optonline.net">Geir Magusson Jr.</a>
083: * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
084: *
085: * @see org.apache.velocity.runtime.RuntimeInstance
086: *
087: * @version $Id: RuntimeSingleton.java 463298 2006-10-12 16:10:32Z henning $
088: */
089: public class RuntimeSingleton implements RuntimeConstants {
090: private static RuntimeInstance ri = new RuntimeInstance();
091:
092: /**
093: * This is the primary initialization method in the Velocity
094: * Runtime. The systems that are setup/initialized here are
095: * as follows:
096: *
097: * <ul>
098: * <li>Logging System</li>
099: * <li>ResourceManager</li>
100: * <li>Event Handlers</li>
101: * <li>Parser Pool</li>
102: * <li>Global Cache</li>
103: * <li>Static Content Include System</li>
104: * <li>Velocimacro System</li>
105: * </ul>
106: * @throws Exception When an error occured during initialization.
107: * @see RuntimeInstance#init()
108: */
109: public synchronized static void init() throws Exception {
110: ri.init();
111: }
112:
113: /**
114: * Returns true if the RuntimeInstance has been successfully initialized.
115: * @return True if the RuntimeInstance has been successfully initialized.
116: * @see RuntimeInstance#isInitialized()
117: */
118: public static boolean isInitialized() {
119: return ri.isInitialized();
120: }
121:
122: /**
123: * Returns the RuntimeServices Instance used by this wrapper.
124: *
125: * @return The RuntimeServices Instance used by this wrapper.
126: */
127: public static RuntimeServices getRuntimeServices() {
128: return ri;
129: }
130:
131: /**
132: * Allows an external system to set a property in
133: * the Velocity Runtime.
134: *
135: * @param key property key
136: * @param value property value
137: * @see RuntimeInstance#setProperty(String, Object)
138: */
139: public static void setProperty(String key, Object value) {
140: ri.setProperty(key, value);
141: }
142:
143: /**
144: * Allow an external system to set an ExtendedProperties
145: * object to use. This is useful where the external
146: * system also uses the ExtendedProperties class and
147: * the velocity configuration is a subset of
148: * parent application's configuration. This is
149: * the case with Turbine.
150: *
151: * @param configuration
152: * @see RuntimeInstance#setConfiguration(ExtendedProperties)
153: */
154: public static void setConfiguration(ExtendedProperties configuration) {
155: ri.setConfiguration(configuration);
156: }
157:
158: /**
159: * Add a property to the configuration. If it already
160: * exists then the value stated here will be added
161: * to the configuration entry. For example, if
162: *
163: * resource.loader = file
164: *
165: * is already present in the configuration and you
166: *
167: * addProperty("resource.loader", "classpath")
168: *
169: * Then you will end up with a Vector like the
170: * following:
171: *
172: * ["file", "classpath"]
173: *
174: * @param key
175: * @param value
176: * @see RuntimeInstance#addProperty(String, Object)
177: */
178: public static void addProperty(String key, Object value) {
179: ri.addProperty(key, value);
180: }
181:
182: /**
183: * Clear the values pertaining to a particular
184: * property.
185: *
186: * @param key of property to clear
187: * @see RuntimeInstance#clearProperty(String)
188: */
189: public static void clearProperty(String key) {
190: ri.clearProperty(key);
191: }
192:
193: /**
194: * Allows an external caller to get a property. The calling
195: * routine is required to know the type, as this routine
196: * will return an Object, as that is what properties can be.
197: *
198: * @param key property to return
199: * @return Value of the property or null if it does not exist.
200: * @see RuntimeInstance#getProperty(String)
201: */
202: public static Object getProperty(String key) {
203: return ri.getProperty(key);
204: }
205:
206: /**
207: * Initialize the Velocity Runtime with a Properties
208: * object.
209: *
210: * @param p
211: * @throws Exception When an error occurs during initialization.
212: * @see RuntimeInstance#init(Properties)
213: */
214: public static void init(Properties p) throws Exception {
215: ri.init(p);
216: }
217:
218: /**
219: * Initialize the Velocity Runtime with the name of
220: * ExtendedProperties object.
221: *
222: * @param configurationFile
223: * @throws Exception When an error occurs during initialization.
224: * @see RuntimeInstance#init(String)
225: */
226: public static void init(String configurationFile) throws Exception {
227: ri.init(configurationFile);
228: }
229:
230: /**
231: * Parse the input and return the root of
232: * AST node structure.
233: * <br><br>
234: * In the event that it runs out of parsers in the
235: * pool, it will create and let them be GC'd
236: * dynamically, logging that it has to do that. This
237: * is considered an exceptional condition. It is
238: * expected that the user will set the
239: * PARSER_POOL_SIZE property appropriately for their
240: * application. We will revisit this.
241: *
242: * @param reader Reader retrieved by a resource loader
243: * @param templateName name of the template being parsed
244: * @return A root node representing the template as an AST tree.
245: * @throws ParseException When the template could not be parsed.
246: * @see RuntimeInstance#parse(Reader, String)
247: */
248: public static SimpleNode parse(Reader reader, String templateName)
249: throws ParseException {
250: return ri.parse(reader, templateName);
251: }
252:
253: /**
254: * Parse the input and return the root of the AST node structure.
255: *
256: * @param reader Reader retrieved by a resource loader
257: * @param templateName name of the template being parsed
258: * @param dumpNamespace flag to dump the Velocimacro namespace for this template
259: * @return A root node representing the template as an AST tree.
260: * @throws ParseException When the template could not be parsed.
261: * @see RuntimeInstance#parse(Reader, String, boolean)
262: */
263: public static SimpleNode parse(Reader reader, String templateName,
264: boolean dumpNamespace) throws ParseException {
265: return ri.parse(reader, templateName, dumpNamespace);
266: }
267:
268: /**
269: * Returns a <code>Template</code> from the resource manager.
270: * This method assumes that the character encoding of the
271: * template is set by the <code>input.encoding</code>
272: * property. The default is "ISO-8859-1"
273: *
274: * @param name The file name of the desired template.
275: * @return The template.
276: * @throws ResourceNotFoundException if template not found
277: * from any available source.
278: * @throws ParseErrorException if template cannot be parsed due
279: * to syntax (or other) error.
280: * @throws Exception if an error occurs in template initialization
281: * @see RuntimeInstance#getTemplate(String)
282: */
283: public static Template getTemplate(String name)
284: throws ResourceNotFoundException, ParseErrorException,
285: Exception {
286: return ri.getTemplate(name);
287: }
288:
289: /**
290: * Returns a <code>Template</code> from the resource manager
291: *
292: * @param name The name of the desired template.
293: * @param encoding Character encoding of the 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: * @throws ParseErrorException When the template could not be parsed.
301: * @throws Exception Any other error.
302: * @see RuntimeInstance#getTemplate(String, String)
303: */
304: public static Template getTemplate(String name, String encoding)
305: throws ResourceNotFoundException, ParseErrorException,
306: Exception {
307: return ri.getTemplate(name, encoding);
308: }
309:
310: /**
311: * Returns a static content resource from the
312: * resource manager. Uses the current value
313: * if INPUT_ENCODING as the character encoding.
314: *
315: * @param name Name of content resource to get
316: * @return parsed ContentResource object ready for use
317: * @throws ResourceNotFoundException if template not found
318: * from any available source.
319: * @throws ParseErrorException When the template could not be parsed.
320: * @throws Exception Any other error.
321: * @see RuntimeInstance#getContent(String)
322: */
323: public static ContentResource getContent(String name)
324: throws ResourceNotFoundException, ParseErrorException,
325: Exception {
326: return ri.getContent(name);
327: }
328:
329: /**
330: * Returns a static content resource from the
331: * resource manager.
332: *
333: * @param name Name of content resource to get
334: * @param encoding Character encoding to use
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, String)
341: */
342: public static ContentResource getContent(String name,
343: String encoding) throws ResourceNotFoundException,
344: ParseErrorException, Exception {
345: return ri.getContent(name, encoding);
346: }
347:
348: /**
349: * Determines is a template exists, and returns name of the loader that
350: * provides it. This is a slightly less hokey way to support
351: * the Velocity.templateExists() utility method, which was broken
352: * when per-template encoding was introduced. We can revisit this.
353: *
354: * @param resourceName Name of template or content resource
355: * @return class name of loader than can provide it
356: * @see RuntimeInstance#getLoaderNameForResource(String)
357: */
358: public static String getLoaderNameForResource(String resourceName) {
359: return ri.getLoaderNameForResource(resourceName);
360: }
361:
362: /**
363: * Returns a convenient Log instance that wraps the current LogChute.
364: *
365: * @return A convenience Log instance that wraps the current LogChute.
366: * @see RuntimeInstance#getLog()
367: */
368: public static Log getLog() {
369: return ri.getLog();
370: }
371:
372: /**
373: * @deprecated Use getLog() and call warn() on it.
374: * @see Log#warn(Object)
375: * @param message The message to log.
376: */
377: public static void warn(Object message) {
378: getLog().warn(message);
379: }
380:
381: /**
382: * @deprecated Use getLog() and call info() on it.
383: * @see Log#info(Object)
384: * @param message The message to log.
385: */
386: public static void info(Object message) {
387: getLog().info(message);
388: }
389:
390: /**
391: * @deprecated Use getLog() and call error() on it.
392: * @see Log#error(Object)
393: * @param message The message to log.
394: */
395: public static void error(Object message) {
396: getLog().error(message);
397: }
398:
399: /**
400: * @deprecated Use getLog() and call debug() on it.
401: * @see Log#debug(Object)
402: * @param message The message to log.
403: */
404: public static void debug(Object message) {
405: getLog().debug(message);
406: }
407:
408: /**
409: * String property accessor method with default to hide the
410: * configuration implementation.
411: *
412: * @param key property key
413: * @param defaultValue default value to return if key not
414: * found in resource manager.
415: * @return value of key or default
416: * @see RuntimeInstance#getString(String, String)
417: */
418: public static String getString(String key, String defaultValue) {
419: return ri.getString(key, defaultValue);
420: }
421:
422: /**
423: * Returns the appropriate VelocimacroProxy object if strVMname
424: * is a valid current Velocimacro.
425: *
426: * @param vmName Name of velocimacro requested
427: * @param templateName Name of the template that contains the velocimacro.
428: * @return The requested VelocimacroProxy.
429: * @see RuntimeInstance#getVelocimacro(String, String)
430: */
431: public static Directive getVelocimacro(String vmName,
432: String templateName) {
433: return ri.getVelocimacro(vmName, templateName);
434: }
435:
436: /**
437: * Adds a new Velocimacro. Usually called by Macro only while parsing.
438: *
439: * @param name Name of velocimacro
440: * @param macro String form of macro body
441: * @param argArray Array of strings, containing the
442: * #macro() arguments. the 0th is the name.
443: * @param sourceTemplate Name of the template that contains the velocimacro.
444: * @return True if added, false if rejected for some
445: * reason (either parameters or permission settings)
446: * @see RuntimeInstance#addVelocimacro(String, String, String[], String)
447: */
448: public static boolean addVelocimacro(String name, String macro,
449: String argArray[], String sourceTemplate) {
450: return ri.addVelocimacro(name, macro, argArray, sourceTemplate);
451: }
452:
453: /**
454: * Checks to see if a VM exists
455: *
456: * @param vmName Name of the Velocimacro.
457: * @param templateName Template on which to look for the Macro.
458: * @return True if VM by that name exists, false if not
459: * @see RuntimeInstance#isVelocimacro(String, String)
460: */
461: public static boolean isVelocimacro(String vmName,
462: String templateName) {
463: return ri.isVelocimacro(vmName, templateName);
464: }
465:
466: /**
467: * tells the vmFactory to dump the specified namespace. This is to support
468: * clearing the VM list when in inline-VM-local-scope mode
469: * @param namespace Namespace to dump.
470: * @return True if namespace was dumped successfully.
471: * @see RuntimeInstance#dumpVMNamespace(String)
472: */
473: public static boolean dumpVMNamespace(String namespace) {
474: return ri.dumpVMNamespace(namespace);
475: }
476:
477: /* --------------------------------------------------------------------
478: * R U N T I M E A C C E S S O R M E T H O D S
479: * --------------------------------------------------------------------
480: * These are the getXXX() methods that are a simple wrapper
481: * around the configuration object. This is an attempt
482: * to make a the Velocity Runtime the single access point
483: * for all things Velocity, and allow the Runtime to
484: * adhere as closely as possible the the Mediator pattern
485: * which is the ultimate goal.
486: * --------------------------------------------------------------------
487: */
488:
489: /**
490: * String property accessor method to hide the configuration implementation
491: * @param key property key
492: * @return value of key or null
493: * @see RuntimeInstance#getString(String)
494: */
495: public static String getString(String key) {
496: return ri.getString(key);
497: }
498:
499: /**
500: * Int property accessor method to hide the configuration implementation.
501: *
502: * @param key Property key
503: * @return value
504: * @see RuntimeInstance#getInt(String)
505: */
506: public static int getInt(String key) {
507: return ri.getInt(key);
508: }
509:
510: /**
511: * Int property accessor method to hide the configuration implementation.
512: *
513: * @param key property key
514: * @param defaultValue The default value.
515: * @return value
516: * @see RuntimeInstance#getInt(String, int)
517: */
518: public static int getInt(String key, int defaultValue) {
519: return ri.getInt(key, defaultValue);
520: }
521:
522: /**
523: * Boolean property accessor method to hide the configuration implementation.
524: *
525: * @param key property key
526: * @param def The default value if property not found.
527: * @return value of key or default value
528: * @see RuntimeInstance#getBoolean(String, boolean)
529: */
530: public static boolean getBoolean(String key, boolean def) {
531: return ri.getBoolean(key, def);
532: }
533:
534: /**
535: * Return the velocity runtime configuration object.
536: *
537: * @return ExtendedProperties configuration object which houses
538: * the velocity runtime properties.
539: * @see RuntimeInstance#getConfiguration()
540: */
541: public static ExtendedProperties getConfiguration() {
542: return ri.getConfiguration();
543: }
544:
545: /**
546: * Return the Introspector for this RuntimeInstance
547: *
548: * @return Introspector object for this runtime instance
549: * @see RuntimeInstance#getIntrospector()
550: */
551: public static Introspector getIntrospector() {
552: return ri.getIntrospector();
553: }
554:
555: /**
556: * Returns the event handlers for the application.
557: * @return The event handlers for the application.
558: * @see RuntimeInstance#getApplicationEventCartridge()
559: */
560: public EventCartridge getEventCartridge() {
561: return ri.getApplicationEventCartridge();
562: }
563:
564: /**
565: * Gets the application attribute for the given key
566: *
567: * @see org.apache.velocity.runtime.RuntimeServices#getApplicationAttribute(Object)
568: * @param key
569: * @return The application attribute for the given key.
570: * @see RuntimeInstance#getApplicationAttribute(Object)
571: */
572: public static Object getApplicationAttribute(Object key) {
573: return ri.getApplicationAttribute(key);
574: }
575:
576: /**
577: * Returns the Uberspect object for this Instance.
578: *
579: * @return The Uberspect object for this Instance.
580: * @see org.apache.velocity.runtime.RuntimeServices#getUberspect()
581: * @see RuntimeInstance#getUberspect()
582: */
583: public static Uberspect getUberspect() {
584: return ri.getUberspect();
585: }
586:
587: /**
588: * @deprecated Use getRuntimeServices() instead.
589: * @return The RuntimeInstance used by this Singleton.
590: */
591: public static RuntimeInstance getRuntimeInstance() {
592: return ri;
593: }
594: }
|