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