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.IOException; 23 import java.io.Reader; 24 import java.io.Writer; 25 import java.util.Properties; 26 27 import org.apache.commons.collections.ExtendedProperties; 28 import org.apache.velocity.Template; 29 import org.apache.velocity.app.event.EventCartridge; 30 import org.apache.velocity.context.Context; 31 import org.apache.velocity.exception.MethodInvocationException; 32 import org.apache.velocity.exception.ParseErrorException; 33 import org.apache.velocity.exception.ResourceNotFoundException; 34 import org.apache.velocity.runtime.directive.Directive; 35 import org.apache.velocity.runtime.log.Log; 36 import org.apache.velocity.runtime.parser.ParseException; 37 import org.apache.velocity.runtime.parser.Parser; 38 import org.apache.velocity.runtime.parser.node.Node; 39 import org.apache.velocity.runtime.parser.node.SimpleNode; 40 import org.apache.velocity.runtime.resource.ContentResource; 41 import org.apache.velocity.util.introspection.Introspector; 42 import org.apache.velocity.util.introspection.Uberspect; 43 44 45 /** 46 * Interface for internal runtime services that are needed by the 47 * various components w/in Velocity. This was taken from the old 48 * Runtime singleton, and anything not necessary was removed. 49 * 50 * Currently implemented by RuntimeInstance. 51 * 52 * @author <a href="mailto:geirm@optonline.net">Geir Magusson Jr.</a> 53 * @version $Id: RuntimeServices.java 685724 2008-08-13 23:12:12Z nbubna $ 54 */ 55 public interface RuntimeServices extends RuntimeLogger 56 { 57 58 /** 59 * This is the primary initialization method in the Velocity 60 * Runtime. The systems that are setup/initialized here are 61 * as follows: 62 * 63 * <ul> 64 * <li>Logging System</li> 65 * <li>ResourceManager</li> 66 * <li>Parser Pool</li> 67 * <li>Global Cache</li> 68 * <li>Static Content Include System</li> 69 * <li>Velocimacro System</li> 70 * </ul> 71 * @throws Exception 72 */ 73 public void init() throws Exception; 74 75 /** 76 * Allows an external system to set a property in 77 * the Velocity Runtime. 78 * 79 * @param key property key 80 * @param value property value 81 */ 82 public void setProperty(String key, Object value); 83 84 /** 85 * Allow an external system to set an ExtendedProperties 86 * object to use. This is useful where the external 87 * system also uses the ExtendedProperties class and 88 * the velocity configuration is a subset of 89 * parent application's configuration. This is 90 * the case with Turbine. 91 * 92 * @param configuration 93 */ 94 public void setConfiguration( ExtendedProperties configuration); 95 96 /** 97 * Add a property to the configuration. If it already 98 * exists then the value stated here will be added 99 * to the configuration entry. For example, if 100 * 101 * resource.loader = file 102 * 103 * is already present in the configuration and you 104 * 105 * addProperty("resource.loader", "classpath") 106 * 107 * Then you will end up with a Vector like the 108 * following: 109 * 110 * ["file", "classpath"] 111 * 112 * @param key 113 * @param value 114 */ 115 public void addProperty(String key, Object value); 116 117 /** 118 * Clear the values pertaining to a particular 119 * property. 120 * 121 * @param key of property to clear 122 */ 123 public void clearProperty(String key); 124 125 /** 126 * Allows an external caller to get a property. The calling 127 * routine is required to know the type, as this routine 128 * will return an Object, as that is what properties can be. 129 * 130 * @param key property to return 131 * @return The value. 132 */ 133 public Object getProperty( String key ); 134 135 /** 136 * Initialize the Velocity Runtime with a Properties 137 * object. 138 * 139 * @param p 140 * @throws Exception 141 */ 142 public void init(Properties p) throws Exception; 143 144 /** 145 * Initialize the Velocity Runtime with the name of 146 * ExtendedProperties object. 147 * 148 * @param configurationFile 149 * @throws Exception 150 */ 151 public void init(String configurationFile) throws Exception; 152 153 /** 154 * Wraps the String in a StringReader and passes it off to 155 * {@link #parse(Reader,String)}. 156 * @since 1.6 157 */ 158 public SimpleNode parse(String string, String templateName) 159 throws ParseException; 160 161 /** 162 * Parse the input and return the root of 163 * AST node structure. 164 * <br><br> 165 * In the event that it runs out of parsers in the 166 * pool, it will create and let them be GC'd 167 * dynamically, logging that it has to do that. This 168 * is considered an exceptional condition. It is 169 * expected that the user will set the 170 * PARSER_POOL_SIZE property appropriately for their 171 * application. We will revisit this. 172 * 173 * @param reader inputstream retrieved by a resource loader 174 * @param templateName name of the template being parsed 175 * @return The AST representing the template. 176 * @throws ParseException 177 */ 178 public SimpleNode parse( Reader reader, String templateName ) 179 throws ParseException; 180 181 /** 182 * Parse the input and return the root of the AST node structure. 183 * 184 * @param reader inputstream retrieved by a resource loader 185 * @param templateName name of the template being parsed 186 * @param dumpNamespace flag to dump the Velocimacro namespace for this template 187 * @return The AST representing the template. 188 * @throws ParseException 189 */ 190 public SimpleNode parse( Reader reader, String templateName, boolean dumpNamespace ) 191 throws ParseException; 192 193 /** 194 * Renders the input string using the context into the output writer. 195 * To be used when a template is dynamically constructed, or want to use 196 * Velocity as a token replacer. 197 * 198 * @param context context to use in rendering input string 199 * @param out Writer in which to render the output 200 * @param logTag string to be used as the template name for log 201 * messages in case of error 202 * @param instring input string containing the VTL to be rendered 203 * 204 * @return true if successful, false otherwise. If false, see 205 * Velocity runtime log 206 * @throws ParseErrorException The template could not be parsed. 207 * @throws MethodInvocationException A method on a context object could not be invoked. 208 * @throws ResourceNotFoundException A referenced resource could not be loaded. 209 * @throws IOException While rendering to the writer, an I/O problem occured. 210 * @since Velocity 1.6 211 */ 212 public boolean evaluate(Context context, Writer out, 213 String logTag, String instring) throws IOException; 214 215 /** 216 * Renders the input reader using the context into the output writer. 217 * To be used when a template is dynamically constructed, or want to 218 * use Velocity as a token replacer. 219 * 220 * @param context context to use in rendering input string 221 * @param writer Writer in which to render the output 222 * @param logTag string to be used as the template name for log messages 223 * in case of error 224 * @param reader Reader containing the VTL to be rendered 225 * 226 * @return true if successful, false otherwise. If false, see 227 * Velocity runtime log 228 * @throws ParseErrorException The template could not be parsed. 229 * @throws MethodInvocationException A method on a context object could not be invoked. 230 * @throws ResourceNotFoundException A referenced resource could not be loaded. 231 * @throws IOException While reading from the reader or rendering to the writer, 232 * an I/O problem occured. 233 * @since Velocity 1.6 234 */ 235 public boolean evaluate(Context context, Writer writer, 236 String logTag, Reader reader) throws IOException; 237 238 /** 239 * Invokes a currently registered Velocimacro with the params provided 240 * and places the rendered stream into the writer. 241 * <br> 242 * Note : currently only accepts args to the VM if they are in the context. 243 * 244 * @param vmName name of Velocimacro to call 245 * @param logTag string to be used for template name in case of error. if null, 246 * the vmName will be used 247 * @param params keys for args used to invoke Velocimacro, in java format 248 * rather than VTL (eg "foo" or "bar" rather than "$foo" or "$bar") 249 * @param context Context object containing data/objects used for rendering. 250 * @param writer Writer for output stream 251 * @return true if Velocimacro exists and successfully invoked, false otherwise. 252 * @throws IOException While rendering to the writer, an I/O problem occured. 253 * @since 1.6 254 */ 255 public boolean invokeVelocimacro(final String vmName, String logTag, 256 String[] params, final Context context, 257 final Writer writer) throws IOException; 258 259 /** 260 * Returns a <code>Template</code> from the resource manager. 261 * This method assumes that the character encoding of the 262 * template is set by the <code>input.encoding</code> 263 * property. The default is "ISO-8859-1" 264 * 265 * @param name The file name of the desired template. 266 * @return The template. 267 * @throws ResourceNotFoundException if template not found 268 * from any available source. 269 * @throws ParseErrorException if template cannot be parsed due 270 * to syntax (or other) error. 271 * @throws Exception if an error occurs in template initialization 272 */ 273 public Template getTemplate(String name) 274 throws ResourceNotFoundException, ParseErrorException, Exception; 275 276 /** 277 * Returns a <code>Template</code> from the resource manager 278 * 279 * @param name The name of the desired template. 280 * @param encoding Character encoding of the template 281 * @return The template. 282 * @throws ResourceNotFoundException if template not found 283 * from any available source. 284 * @throws ParseErrorException if template cannot be parsed due 285 * to syntax (or other) error. 286 * @throws Exception if an error occurs in template initialization 287 */ 288 public Template getTemplate(String name, String encoding) 289 throws ResourceNotFoundException, ParseErrorException, Exception; 290 291 /** 292 * Returns a static content resource from the 293 * resource manager. Uses the current value 294 * if INPUT_ENCODING as the character encoding. 295 * 296 * @param name Name of content resource to get 297 * @return parsed ContentResource object ready for use 298 * @throws ResourceNotFoundException if template not found 299 * from any available source. 300 * @throws ParseErrorException 301 * @throws Exception 302 */ 303 public ContentResource getContent(String name) 304 throws ResourceNotFoundException, ParseErrorException, Exception; 305 306 /** 307 * Returns a static content resource from the 308 * resource manager. 309 * 310 * @param name Name of content resource to get 311 * @param encoding Character encoding to use 312 * @return parsed ContentResource object ready for use 313 * @throws ResourceNotFoundException if template not found 314 * from any available source. 315 * @throws ParseErrorException 316 * @throws Exception 317 */ 318 public ContentResource getContent( String name, String encoding ) 319 throws ResourceNotFoundException, ParseErrorException, Exception; 320 321 /** 322 * Determines is a template exists, and returns name of the loader that 323 * provides it. This is a slightly less hokey way to support 324 * the Velocity.templateExists() utility method, which was broken 325 * when per-template encoding was introduced. We can revisit this. 326 * 327 * @param resourceName Name of template or content resource 328 * @return class name of loader than can provide it 329 */ 330 public String getLoaderNameForResource( String resourceName ); 331 332 /** 333 * String property accessor method with default to hide the 334 * configuration implementation. 335 * 336 * @param key property key 337 * @param defaultValue default value to return if key not 338 * found in resource manager. 339 * @return String value of key or default 340 */ 341 public String getString( String key, String defaultValue); 342 343 /** 344 * Returns the appropriate VelocimacroProxy object if strVMname 345 * is a valid current Velocimacro. 346 * 347 * @param vmName Name of velocimacro requested 348 * @param templateName Name of the namespace. 349 * @return VelocimacroProxy 350 */ 351 public Directive getVelocimacro( String vmName, String templateName ); 352 353 /** 354 * Returns the appropriate VelocimacroProxy object if strVMname 355 * is a valid current Velocimacro. 356 * 357 * @param vmName Name of velocimacro requested 358 * @param templateName Name of the namespace. 359 * @param renderingTemplate Name of the template we are currently rendering. This 360 * information is needed when VM_PERM_ALLOW_INLINE_REPLACE_GLOBAL setting is true 361 * and template contains a macro with the same name as the global macro library. 362 * 363 * @since Velocity 1.6 364 * 365 * @return VelocimacroProxy 366 */ 367 public Directive getVelocimacro( String vmName, String templateName, String renderingTemplate ); 368 369 /** 370 * Adds a new Velocimacro. Usually called by Macro only while parsing. 371 * 372 * @param name Name of velocimacro 373 * @param macro String form of macro body 374 * @param argArray Array of strings, containing the 375 * #macro() arguments. the 0th is the name. 376 * @param sourceTemplate 377 * 378 * @deprecated Use addVelocimacro(String, Node, String[], String) instead 379 * 380 * @return boolean True if added, false if rejected for some 381 * reason (either parameters or permission settings) 382 */ 383 public boolean addVelocimacro( String name, 384 String macro, 385 String argArray[], 386 String sourceTemplate ); 387 388 /** 389 * Adds a new Velocimacro. Usually called by Macro only while parsing. 390 * 391 * @param name Name of velocimacro 392 * @param macro root AST node of the parsed macro 393 * @param argArray Array of strings, containing the 394 * #macro() arguments. the 0th is the name. 395 * @param sourceTemplate 396 * 397 * @since Velocity 1.6 398 * 399 * @return boolean True if added, false if rejected for some 400 * reason (either parameters or permission settings) 401 */ 402 public boolean addVelocimacro( String name, 403 Node macro, 404 String argArray[], 405 String sourceTemplate ); 406 407 408 /** 409 * Checks to see if a VM exists 410 * 411 * @param vmName Name of velocimacro 412 * @param templateName 413 * @return boolean True if VM by that name exists, false if not 414 */ 415 public boolean isVelocimacro( String vmName, String templateName ); 416 417 /** 418 * tells the vmFactory to dump the specified namespace. This is to support 419 * clearing the VM list when in inline-VM-local-scope mode 420 * @param namespace 421 * @return True if the Namespace was dumped. 422 */ 423 public boolean dumpVMNamespace( String namespace ); 424 425 /** 426 * String property accessor method to hide the configuration implementation 427 * @param key property key 428 * @return value of key or null 429 */ 430 public String getString(String key); 431 432 /** 433 * Int property accessor method to hide the configuration implementation. 434 * 435 * @param key property key 436 * @return int value 437 */ 438 public int getInt( String key ); 439 440 /** 441 * Int property accessor method to hide the configuration implementation. 442 * 443 * @param key property key 444 * @param defaultValue default value 445 * @return int value 446 */ 447 public int getInt( String key, int defaultValue ); 448 449 /** 450 * Boolean property accessor method to hide the configuration implementation. 451 * 452 * @param key property key 453 * @param def default default value if property not found 454 * @return boolean value of key or default value 455 */ 456 public boolean getBoolean( String key, boolean def ); 457 458 /** 459 * Return the velocity runtime configuration object. 460 * 461 * @return ExtendedProperties configuration object which houses 462 * the velocity runtime properties. 463 */ 464 public ExtendedProperties getConfiguration(); 465 466 /** 467 * Return the specified application attribute. 468 * 469 * @param key The name of the attribute to retrieve. 470 * @return The value of the attribute. 471 */ 472 public Object getApplicationAttribute( Object key ); 473 474 /** 475 * Set the specified application attribute. 476 * 477 * @param key The name of the attribute to set. 478 * @param value The attribute value to set. 479 * @return the displaced attribute value 480 */ 481 public Object setApplicationAttribute( Object key, Object value ); 482 483 /** 484 * Returns the configured class introspection/reflection 485 * implementation. 486 * @return The current Uberspect object. 487 */ 488 public Uberspect getUberspect(); 489 490 /** 491 * Returns a convenient Log instance that wraps the current LogChute. 492 * @return A log object. 493 */ 494 public Log getLog(); 495 496 /** 497 * Returns the event handlers for the application. 498 * @return The event handlers for the application. 499 */ 500 public EventCartridge getApplicationEventCartridge(); 501 502 503 /** 504 * Returns the configured method introspection/reflection 505 * implementation. 506 * @return The configured method introspection/reflection 507 * implementation. 508 */ 509 public Introspector getIntrospector(); 510 511 /** 512 * Returns true if the RuntimeInstance has been successfully initialized. 513 * @return True if the RuntimeInstance has been successfully initialized. 514 */ 515 public boolean isInitialized(); 516 517 /** 518 * Create a new parser instance. 519 * @return A new parser instance. 520 */ 521 public Parser createNewParser(); 522 523 /** 524 * Retrieve a previously instantiated directive. 525 * @param name name of the directive 526 * @return the directive with that name, if any 527 * @since 1.6 528 */ 529 public Directive getDirective(String name); 530 531 }