diff --git a/doc/reference/src/templating.xml b/doc/reference/src/templating.xml
index e426eaa5..b2ab0d8a 100644
--- a/doc/reference/src/templating.xml
+++ b/doc/reference/src/templating.xml
@@ -51,7 +51,7 @@
linkend="objects-factory-lifecycle-factoryobject" />. A custom namespace
parser is provided to simplify the configuration of a NVelocity template
engine. For more information on custom namespace parser see .
+ linkend="context-custom-parsers" />.
Simple file based template engine definition
@@ -67,7 +67,8 @@
</objects>
The velocity engine could then be used to load and merge a local
- template using a simple relative path:
+ template using a simple relative path (the default resource loader path
+ is the current execution directory):
StringWriter stringWriter = new StringWriter();
Hashtable modelTable = new Hashtable();
@@ -81,6 +82,86 @@ string mergedContent = stringWriter.ToString();
<engine/> to false.
+
+ Configuration Options
+
+ You can define several attributes on the <engine> element to
+ control how the factory is configured:
+
+
+ Engine Factory Configuration Options
+
+
+
+
+
+
+
+
+
+
+
+
+ Attribute
+
+ Description
+
+ Required
+
+ Default Value
+
+
+
+
+
+ config-file
+
+
+ A uri of a properties file defining the NVelocity
+ configuration. This value accepts all spring resource loader
+ uri (e.g., file://, http://). See
+
+
+ no
+
+ N/A
+
+
+
+ prefer-file-system-access
+
+
+ Instructs the NVelocity engine factory to attempt use
+ NVelocity's file loader. When set to false the provided
+ SpringResourceLoader will be used (and the ResourceLoaderPath
+ property must be set)
+
+
+ no
+
+ true
+
+
+
+ override-logging
+
+
+ Instructs the NVelocity engine factory to use the
+ provided spring commons logging based logging system. See See
+
+
+
+ no
+
+ true
+
+
+
+
+
+
Assembly based template loading
@@ -99,7 +180,7 @@ string mergedContent = stringWriter.ToString();
velocityEngine.MergeTemplate("MyAssembly.MyNamespace.MyTemplate.vm", Encoding.UTF8.WebName, velocityContext, stringWriter);
-
+ Using Spring's IResourceLoader to load
templates
@@ -110,9 +191,9 @@ string mergedContent = stringWriter.ToString();
object definition loads the NVelocity templates from a single
path
- <nv:engine id="velocityEngine">
+ <nv:engine id="velocityEngine">
<nv:resource-loader>
- <nv:file path="MyTemplateFolder/AnotherFolder/" />
+ <nv:spring uri="file://Template/Velocity/"/>
</nv:resource-loader>
</nv:engine>
@@ -120,24 +201,127 @@ string mergedContent = stringWriter.ToString();<nv:engine id="velocityEngine">
<nv:resource-loader>
- <nv:file path="MyTemplateFolder/AnotherFolder/" />
- <nv:file path="MyOtherTemplateFolder/" />
+ <nv:spring uri="file://Template/Velocity/"/>
+ <nv:spring uri="assembly://MyAssembly/MyNameSpace"/>
</nv:resource-loader>
</nv:engine>
- By default spring will attempt to load resources using file
- based template loading (useful for detection of template changes at
- runtime). If this is not desirable you set the
- prefer-file-system-access element of the
- </engine> element to false.
+ By default spring will attempt to load resources using NVelocity's
+ file based template loading (useful for detection of template changes at
+ runtime). If this is not desirable you set the
+ prefer-file-system-access property of the factory object
+ to false which will cause the factory to utilize the supplied
+ spring resource loader.Using the example above when resource loader paths are defined
templates can be loaded using their name:
- string mergedTemplate = VelocityEngineUtils.MergeTemplateIntostring(velocityEngine, "MyTemplate.vm", Encoding.UTF8.WebName, model);
+ string mergedTemplate = VelocityEngineUtils.MergeTemplateIntostring(velocityEngine, "MyFileTemplate.vm", Encoding.UTF8.WebName, model); // template loaded from file://Template/Velocity/
+string mergedTemplate = VelocityEngineUtils.MergeTemplateIntostring(velocityEngine, "MyAseemblyTemplate.vm", Encoding.UTF8.WebName, model); // template loaded from assembly://MyAssembly/MyNameSpace
+
+
+
+ Defining a custom resource loader
+
+ The following defines a custom resource loader (the type is an
+ extension of NVelocity's ResourceLoader
+ class):
+
+ <nv:engine id="velocityEngine">
+ <nv:resource-loader>
+ <nv:custom name="myResourceLoader"
+ description="A custom resource loader"
+ type="MyNamespace.MyResourceLoader, MyAssembly"
+ path="Template/Velocity/"/>
+ </nv:resource-loader>
+</nv:engine>
+
+
+
+
+ Resource Loader configuration options
+
+ The <nv:resource-loader> element has additional attributes
+ which define how NVelocity's resource manager and resource loader
+ behave.
+
+
+ Resource Loader Configuration Options
+
+
+
+
+
+
+
+
+
+
+
+
+ Attribute
+
+ Description
+
+ Required
+
+ Default Value
+
+
+
+
+
+ default-cache-size
+
+
+ defines resource manager global cache size, applies when
+ caching is turned on. This maps to NVelocity's resource
+ manager resource.manager.defaultcache.size
+ property
+
+
+ no
+
+ 89
+
+
+
+ template-caching
+
+
+ Enables template caching for the defined resource
+ loader. This maps to NVelocity's resource loader
+ <name>.resource.loader.cache
+ property
+
+
+ no
+
+ false
+
+
+
+ modification-check-interval
+
+
+ The modification check interval value (seconds) of the
+ resource loader, applies only to resource loader with change
+ detection capabilities (file or custom). This maps to
+ NVelocity's resource loader
+ <name>.resource.loader.modificationCheckInterval
+ property
+
+
+ no
+
+ 2
+
+
+
+
@@ -152,7 +336,7 @@ string mergedContent = stringWriter.ToString();
VelocityProperties property to the NVelocity factory
object (shown above)
- <nv:engine id="customNamespaceVelocityTemplate" config-file="foo.prop">
+ <nv:engine id="velocityTemplate" >
<nv:nvelocity-properties>
<entry key="input.encoding" value="ISO-8859-1"/>
<entry key="output.encoding" value="ISO-8859-1"/>
@@ -161,12 +345,8 @@ string mergedContent = stringWriter.ToString();
-
-
Logging
-
-
By default Spring will override NVelocity's default
ILogSystem implementation with its own
CommonsLoggingLogSystem implementation so that the
@@ -174,12 +354,8 @@ string mergedContent = stringWriter.ToString();
Spring uses. If this is not desirable, you can specify the following
property of the NVelocity factory object:
-
-
<template:nvelocity id="velocityEngine" override-logging="false" />
-
-
@@ -202,7 +378,7 @@ string mergedContent = stringWriter.ToString();
To create a VelocityEngine using the default file resource loader
use the definition:
- <!-- Simple no arg file based configuration use's NVeclocity default file resource loader -->
+ <!-- Simple no arg file based configuration use's NVelocity default file resource loader -->
<object id="velocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity" />For convenience in defining NVelocity engine instances a custom
@@ -210,13 +386,13 @@ string mergedContent = stringWriter.ToString();
done this way:
-<objects xmlns="http://www.springframework.net" xmlns:template="http://www.springframework.net/template">
+<objects xmlns="http://www.springframework.net" xmlns:nv="http://www.springframework.net/nvelocity">
-<template:nvelocity id="customNamespaceVelocityTemplate" >
- <template:resource-loader>
- <template:file path="Template/Velocity/" />
- </template:resource-loader>
-</template:nvelocity>
+<nv:nvelocity id="velocityEngine" >
+ <nv:resource-loader>
+ <nv:file path="Template/Velocity/" />
+ </nv:resource-loader>
+</nv:nvelocity>
</objects
@@ -224,7 +400,7 @@ string mergedContent = stringWriter.ToString();
resource loader can be used to define where templates reside:
<!-- Assembly based template loading with NVelocity assembly resource loader -->
-<object id="assemblyBasedVelocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity">
+<object id="velocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity">
<property name="VelocityProperties">
<dictionary key-type="string" value-type="object">
<entry key="resource.loader" value="assembly"/>
@@ -255,11 +431,12 @@ string mergedContent = stringWriter.ToString();
</object>
- By default spring will attempt to load resources using file based
- template loading (useful for detection of template changes at runtime).
- If this is not desirable you set the
+ By default spring will attempt to load resources using NVelocity's
+ file based template loading (useful for detection of template changes at
+ runtime). If this is not desirable you set the
preferFileSystemAccess property of the factory object
- to false.
+ to false which will cause the factory to utilize the supplied
+ spring resource loader.To refer to a property file based configuration of the
@@ -275,7 +452,7 @@ string mergedContent = stringWriter.ToString();
To not integrate with the Common.Logging subsystem, set the
- OverrideLogging property to false:
+ OverrideLogging property to false:
<object id="velocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity" >
<property name="OverrideLogging" value="false" />
diff --git a/src/Spring/Spring.Template.Velocity/Spring.Template.Velocity.2008.csproj b/src/Spring/Spring.Template.Velocity/Spring.Template.Velocity.2008.csproj
index c5554d35..ffebfb63 100644
--- a/src/Spring/Spring.Template.Velocity/Spring.Template.Velocity.2008.csproj
+++ b/src/Spring/Spring.Template.Velocity/Spring.Template.Velocity.2008.csproj
@@ -69,7 +69,8 @@
-
+
+
diff --git a/src/Spring/Spring.Template.Velocity/Template/Velocity/Config/TemplateNamespaceParser.cs b/src/Spring/Spring.Template.Velocity/Template/Velocity/Config/TemplateNamespaceParser.cs
index c42523af..c2003389 100644
--- a/src/Spring/Spring.Template.Velocity/Template/Velocity/Config/TemplateNamespaceParser.cs
+++ b/src/Spring/Spring.Template.Velocity/Template/Velocity/Config/TemplateNamespaceParser.cs
@@ -21,9 +21,11 @@
#region Imports
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Xml;
using NVelocity.Runtime;
+using NVelocity.Runtime.Resource.Loader;
using Spring.Core.TypeResolution;
using Spring.Objects.Factory;
using Spring.Objects.Factory.Support;
@@ -46,6 +48,7 @@ namespace Spring.Template.Velocity.Config {
]
public sealed class TemplateNamespaceParser : AbstractSingleObjectDefinitionParser {
private const string TemplateTypePrefix = "template: ";
+ private static readonly ObjectNamespaceParserHelper objectNamespaceParserHelper = new ObjectNamespaceParserHelper();
static TemplateNamespaceParser() {
TypeRegistry.RegisterType(TemplateTypePrefix + TemplateDefinitionConstants.NVelocityElement, typeof(VelocityEngineFactoryObject));
@@ -58,134 +61,369 @@ namespace Spring.Template.Velocity.Config {
}
///
- ///
+ /// Parses single object definition for the templating namespace
///
- ///
- ///
- ///
+ /// the current XmlElement to parse
+ /// the parser context
+ /// the ObjectDefinitionBuilder used to configure this object
+ ///
protected override void DoParse(XmlElement element, ParserContext parserContext, ObjectDefinitionBuilder builder) {
switch (element.LocalName) {
case TemplateDefinitionConstants.NVelocityElement:
- ParseNVelocityTemplate(element, parserContext, builder);
+ ParseNVelocityEngine(element, parserContext, builder);
return;
default:
throw new ArgumentException(string.Format("undefined element for templating namespace: {0}", element.LocalName));
}
}
- private void ParseNVelocityTemplate(XmlElement element, ParserContext parseContext, ObjectDefinitionBuilder builder) {
+ ///
+ /// Parses the object definition for the engine object, configures a single NVelocity template engine based
+ /// on the element definitions.
+ ///
+ /// the root element defining the velocity engine
+ /// the parser context
+ /// the ObjectDefinitionBuilder used to configure this object
+ private void ParseNVelocityEngine(XmlElement element, ParserContext parserContext, ObjectDefinitionBuilder builder) {
string preferFileSystemAccess = GetAttributeValue(element, TemplateDefinitionConstants.AttributePreferFileSystemAccess);
string overrideLogging = GetAttributeValue(element, TemplateDefinitionConstants.AttributeOverrideLogging);
string configFile = GetAttributeValue(element, TemplateDefinitionConstants.AttributeConfigFile);
if (StringUtils.HasText(preferFileSystemAccess)) {
- builder.AddPropertyValue(NVelocityEngineFactoryProperties.PropertyPreferFileSystemAccess, preferFileSystemAccess);
+ builder.AddPropertyValue(TemplateDefinitionConstants.PropertyPreferFileSystemAccess, preferFileSystemAccess);
}
if (StringUtils.HasText(overrideLogging)) {
- builder.AddPropertyValue(NVelocityEngineFactoryProperties.PropertyOverrideLogging, overrideLogging);
+ builder.AddPropertyValue(TemplateDefinitionConstants.PropertyOverrideLogging, overrideLogging);
}
if (StringUtils.HasText(configFile)) {
- builder.AddPropertyValue(NVelocityEngineFactoryProperties.PropertyConfigFile, configFile);
+ builder.AddPropertyValue(TemplateDefinitionConstants.PropertyConfigFile, configFile);
}
XmlNodeList childElements = element.ChildNodes;
if (childElements.Count > 0) {
- ParseChildDefinitions(childElements, parseContext, builder);
+ ParseChildDefinitions(childElements, parserContext, builder);
}
}
- private void ParseChildDefinitions(XmlNodeList childElements, ParserContext context, ObjectDefinitionBuilder builder) {
+ ///
+ /// Parses child element definitions for the NVelocity engine. Typically resource loaders and locally defined properties are parsed here
+ ///
+ /// the XmlNodeList representing the child configuration of the root NVelocity engine element
+ /// the parser context
+ /// the ObjectDefinitionBuilder used to configure this object
+ private void ParseChildDefinitions(XmlNodeList childElements, ParserContext parserContext, ObjectDefinitionBuilder builder) {
IDictionary properties = new Dictionary();
foreach (XmlElement element in childElements) {
switch (element.LocalName) {
case TemplateDefinitionConstants.ElementResourceLoader:
- ParseResourceLoader(element, context, builder, properties);
+ ParseResourceLoader(element, builder, properties);
break;
case TemplateDefinitionConstants.ElementNVelocityProperties:
- ParseNVelocityProperties(element, properties);
+ ParseNVelocityProperties(element, parserContext, properties);
break;
}
}
if (properties.Count > 0) {
- builder.AddPropertyValue(NVelocityEngineFactoryProperties.PropertyVelocityProperties, properties);
+ builder.AddPropertyValue(TemplateDefinitionConstants.PropertyVelocityProperties, properties);
}
}
- private void ParseResourceLoader(XmlElement element, ParserContext context, ObjectDefinitionBuilder builder, IDictionary properties) {
- string loaderTypeDefinition = GetAttributeValue(element, TemplateDefinitionConstants.AttributeLoaderType);
+ ///
+ /// Configures the NVelocity resource loader definitions from the xml definition
+ ///
+ /// the root resource loader element
+ /// the ObjectDefinitionBuilder used to configure this object
+ /// the properties used to initialize the velocity engine
+ private void ParseResourceLoader(XmlElement element, ObjectDefinitionBuilder builder, IDictionary properties) {
+ string caching = GetAttributeValue(element, TemplateDefinitionConstants.AttributeTemplateCaching);
+ string defaultCacheSize = GetAttributeValue(element, TemplateDefinitionConstants.AttributeDefaultCacheSize);
+ string modificationCheckInterval = GetAttributeValue(element, TemplateDefinitionConstants.AttributeModificationCheckInterval);
+
+ if (!string.IsNullOrEmpty(defaultCacheSize)) {
+ properties.Add(RuntimeConstants.RESOURCE_MANAGER_DEFAULTCACHE_SIZE, defaultCacheSize);
+ }
+
XmlNodeList loaderElements = element.ChildNodes;
- foreach (XmlElement loaderElement in loaderElements) {
- switch (loaderElement.LocalName) {
- case TemplateDefinitionConstants.ElementResourceLoaderFile:
- AppendResourceLoaderPaths(loaderElements, builder);
- break;
- case TemplateDefinitionConstants.ElementResourceLoaderAssembly:
- AppendAssemblyLoaderProperties((XmlElement)loaderElements.Item(0), properties, loaderTypeDefinition);
- break;
- }
+ switch (loaderElements[0].LocalName) {
+ case VelocityConstants.File:
+ AppendFileLoaderProperties(loaderElements, properties);
+ AppendResourceLoaderGlobalProperties(properties, VelocityConstants.File, caching,
+ modificationCheckInterval);
+ break;
+ case VelocityConstants.Assembly:
+ AppendAssemblyLoaderProperties(loaderElements, properties);
+ AppendResourceLoaderGlobalProperties(properties, VelocityConstants.Assembly, caching, null);
+ break;
+ case TemplateDefinitionConstants.Spring:
+ AppendResourceLoaderPaths(loaderElements, builder);
+ AppendResourceLoaderGlobalProperties(properties, TemplateDefinitionConstants.Spring, caching, null);
+ break;
+ case TemplateDefinitionConstants.Custom:
+ XmlElement firstElement = (XmlElement)loaderElements.Item(0);
+ AppendCustomLoaderProperties(firstElement, properties);
+ AppendResourceLoaderGlobalProperties(properties, firstElement.LocalName, caching, modificationCheckInterval);
+ break;
+ default:
+ throw new ArgumentException(string.Format("undefined element for resource loadre type: {0}", element.LocalName));
}
-
}
- private void AppendAssemblyLoaderProperties(XmlElement element, IDictionary properties, string loaderTypeDefinition) {
- string assemblyName = GetAttributeValue(element, TemplateDefinitionConstants.AttributeName);
- string loaderType = (StringUtils.HasText(loaderTypeDefinition))
- ? loaderTypeDefinition
- : "NVelocity.Runtime.Resource.Loader.AssemblyResourceLoader";
- properties.Add(RuntimeConstants.RESOURCE_LOADER, element.LocalName);
- properties.Add(element.LocalName + "." + RuntimeConstants.RESOURCE_LOADER + ".class", loaderType);
- properties.Add(element.LocalName + "." + RuntimeConstants.RESOURCE_LOADER + ".assembly", assemblyName);
+
+ ///
+ /// Set the caching and modification interval checking properties of a resource loader of a given type
+ ///
+ /// the properties used to initialize the velocity engine
+ /// type of the resource loader
+ /// caching flag
+ /// modification interval value
+ private void AppendResourceLoaderGlobalProperties(IDictionary properties, string type, string caching, string modificationInterval) {
+ AppendResourceLoaderGlobalProperty(properties, type,
+ TemplateDefinitionConstants.PropertyResourceLoaderCaching,
+ Convert.ToBoolean(caching));
+ AppendResourceLoaderGlobalProperty
+ (properties, type, TemplateDefinitionConstants.PropertyResourceLoaderModificationCheckInterval, Convert.ToInt64(modificationInterval));
}
+ ///
+ /// Set global velocity resource loader properties (caching, modification interval etc.)
+ ///
+ /// the properties used to initialize the velocity engine
+ /// the type of resource loader
+ /// the suffix property
+ /// the value of the property
+ private void AppendResourceLoaderGlobalProperty(IDictionary properties, string type, string property, object value) {
+ if (null != value) {
+ properties.Add(type + VelocityConstants.Separator + property, value);
+ }
+ }
+
+ ///
+ /// Creates a nvelocity file based resource loader by setting the required properties
+ ///
+ /// a list of nv:file elements defining the paths to template files
+ /// the properties used to initialize the velocity engine
+ private void AppendFileLoaderProperties(XmlNodeList elements, IDictionary properties) {
+ IList paths = new List(elements.Count);
+ foreach (XmlElement element in elements) {
+ paths.Add(GetAttributeValue(element, VelocityConstants.Path));
+ }
+ properties.Add(RuntimeConstants.RESOURCE_LOADER, VelocityConstants.File);
+ properties.Add(getResourceLoaderProperty(VelocityConstants.File, VelocityConstants.Class), TemplateDefinitionConstants.FileResourceLoaderClass);
+ properties.Add(getResourceLoaderProperty(VelocityConstants.File, VelocityConstants.Path), StringUtils.CollectionToCommaDelimitedString(paths));
+ }
+
+ ///
+ /// Creates a nvelocity assembly based resource loader by setting the required properties
+ ///
+ /// a list of nv:assembly elements defining the assemblies
+ /// the properties used to initialize the velocity engine
+ private void AppendAssemblyLoaderProperties(XmlNodeList elements, IDictionary properties) {
+ IList assemblies = new List(elements.Count);
+ foreach (XmlElement element in elements) {
+ assemblies.Add(GetAttributeValue(element, VelocityConstants.Name));
+ }
+ properties.Add(RuntimeConstants.RESOURCE_LOADER, VelocityConstants.Assembly);
+ properties.Add(getResourceLoaderProperty(VelocityConstants.Assembly, VelocityConstants.Class), TemplateDefinitionConstants.AssemblyResourceLoaderClass);
+ properties.Add(getResourceLoaderProperty(VelocityConstants.Assembly, VelocityConstants.Assembly), StringUtils.CollectionToCommaDelimitedString(assemblies));
+ }
+
+ ///
+ /// Creates a spring resource loader by setting the ResourceLoaderPaths of the
+ /// engine factory (the resource loader itself will be created internally either as
+ /// spring or as file resource loader based on the value of prefer-file-system-access
+ /// attribute).
+ ///
+ /// list of resource loader path elements
+ /// the object definiton builder to set the property for the engine factory
private void AppendResourceLoaderPaths(XmlNodeList elements, ObjectDefinitionBuilder builder) {
IList paths = new List();
foreach (XmlElement element in elements) {
- string path = GetAttributeValue(element, TemplateDefinitionConstants.AttributePath);
+ string path = GetAttributeValue(element, TemplateDefinitionConstants.AttributeUri);
paths.Add(path);
}
- builder.AddPropertyValue(NVelocityEngineFactoryProperties.PropertyResourceLoaderPaths, paths);
+ builder.AddPropertyValue(TemplateDefinitionConstants.PropertyResourceLoaderPaths, paths);
}
-
- private void ParseNVelocityProperties(XmlElement element, IDictionary dictionary) {
- // todo add impl
+ ///
+ /// Create a custom resource loader from an nv:custom element
+ /// generates the 4 required nvelocity props for a resource loader (name, description, class and path).
+ ///
+ /// the nv:custom xml definition element
+ /// the properties used to initialize the velocity engine
+ private void AppendCustomLoaderProperties(XmlElement element, IDictionary properties) {
+ string name = GetAttributeValue(element, VelocityConstants.Name);
+ string description = GetAttributeValue(element, VelocityConstants.Description);
+ string type = GetAttributeValue(element, VelocityConstants.Type);
+ string path = GetAttributeValue(element, VelocityConstants.Path);
+ properties.Add(RuntimeConstants.RESOURCE_LOADER, name);
+ properties.Add(getResourceLoaderProperty(name, VelocityConstants.Description), description);
+ properties.Add(getResourceLoaderProperty(name, VelocityConstants.Class), type.Replace(',', ';'));
+ properties.Add(getResourceLoaderProperty(name, VelocityConstants.Path), path);
}
-
- protected override string GetObjectTypeName(XmlElement element) {
- string typeName = GetAttributeValue(element, ObjectDefinitionConstants.TypeAttribute);
- if (StringUtils.IsNullOrEmpty(typeName)) {
- return TemplateTypePrefix + element.LocalName;
+ ///
+ /// Parses the nvelocity properties map using ObjectNamespaceParserHelper
+ /// and appends it to the properties dictionary
+ ///
+ /// root element of the map element
+ /// the parser context
+ /// the properties used to initialize the velocity engine
+ private void ParseNVelocityProperties(XmlElement element, ParserContext parserContext, IDictionary properties) {
+ IDictionary parsedProperties = objectNamespaceParserHelper.ParseDictionaryElementInternal(element, "NVelocityProperties", parserContext);
+ foreach (DictionaryEntry entry in parsedProperties) {
+ properties.Add(Convert.ToString(entry.Key), entry.Value);
}
- return typeName;
}
+ ///
+ /// construct the element type name (e.g, nv:engine, nv:resource-loader)
+ ///
+ /// the current xml element
+ protected override string GetObjectTypeName(XmlElement element) {
+ return TemplateTypePrefix + element.LocalName;
+ }
+
+
+ ///
+ /// Helper class to access the ParseDictionaryElement of the ObjectsNamespaceParser
+ /// todo: remove this and externalize the logic in ObjectsNamespaceParser.ParseDictionaryElement
+ ///
+ internal sealed class ObjectNamespaceParserHelper : ObjectsNamespaceParser {
+ public IDictionary ParseDictionaryElementInternal(XmlElement element, string name, ParserContext parserContext) {
+ return ParseDictionaryElement(element, name, parserContext);
+ }
+ }
+
+ ///
+ /// constructs an nvelocity style resource loader property in the format:
+ /// prefix.resource.loader.suffix
+ ///
+ /// the prefix
+ /// the suffix
+ /// a concatenated string like: prefix.resource.loader.suffix
+ public static string getResourceLoaderProperty(string type, string suffix) {
+ return type + VelocityConstants.Separator + RuntimeConstants.RESOURCE_LOADER + VelocityConstants.Separator +
+ suffix;
+ }
#region Element & Attribute Name Constants
- private class TemplateDefinitionConstants {
+ ///
+ /// Template definition constants
+ ///
+ public class TemplateDefinitionConstants {
+ ///
+ /// Engine element definition
+ ///
public const string NVelocityElement = "engine";
- public const string AttributePreferFileSystemAccess = "prefer-file-system-access";
- public const string AttributeConfigFile = "config-file";
- public const string AttributeOverrideLogging = "override-logging";
- public const string AttributeLoaderType = "loader-type";
- public const string ElementResourceLoader = "resource-loader";
- public const string ElementResourceLoaderFile = "file";
- public const string ElementResourceLoaderAssembly = "assembly";
- public const string ElementNVelocityProperties = "nvelocity-properties";
- public const string AttributeName = "name";
- public const string AttributePath = "path";
- }
- private class NVelocityEngineFactoryProperties {
+ ///
+ /// Spring resource loader element definition
+ ///
+ public const string Spring = "spring";
+
+ ///
+ /// Custom resource loader element definition
+ ///
+ public const string Custom = "custom";
+
+ ///
+ /// uri attribute of the spring element
+ ///
+ public const string AttributeUri = "uri";
+
+ ///
+ /// prefer-file-system-access attribute of the engine factory
+ ///
+ public const string AttributePreferFileSystemAccess = "prefer-file-system-access";
+
+ ///
+ /// config-file attribute of the engine factory
+ ///
+ public const string AttributeConfigFile = "config-file";
+
+ ///
+ /// override-logging attribute of the engine factory
+ ///
+ public const string AttributeOverrideLogging = "override-logging";
+
+ ///
+ /// template-caching attribute of the nvelocity engine
+ ///
+ public const string AttributeTemplateCaching = "template-caching";
+
+ ///
+ /// default-cache-size attribute of the nvelocity engine resource manager
+ ///
+ public const string AttributeDefaultCacheSize = "default-cache-size";
+
+ ///
+ /// modification-check-interval attribute of the nvelocity engine resource loader
+ ///
+ public const string AttributeModificationCheckInterval = "modification-check-interval";
+
+ ///
+ /// resource loader element
+ ///
+ public const string ElementResourceLoader = "resource-loader";
+
+ ///
+ /// nvelocity propeties element (map)
+ ///
+ public const string ElementNVelocityProperties = "nvelocity-properties";
+
+ ///
+ /// PreferFileSystemAccess property of the engine factory
+ ///
public const string PropertyPreferFileSystemAccess = "PreferFileSystemAccess";
+
+ ///
+ /// OverrideLogging property of the engine factory
+ ///
public const string PropertyOverrideLogging = "OverrideLogging";
+
+ ///
+ /// ConfigLocation property of the engine factory
+ ///
public const string PropertyConfigFile = "ConfigLocation";
+
+ ///
+ /// ResourceLoaderPaths property of the engine factory
+ ///
public const string PropertyResourceLoaderPaths = "ResourceLoaderPaths";
+
+ ///
+ /// VelocityProperties property of the engine factory
+ ///
public const string PropertyVelocityProperties = "VelocityProperties";
+
+ ///
+ /// resource.loader.cache property of the resource loader configuration
+ ///
+ public const string PropertyResourceLoaderCaching = "resource.loader.cache";
+
+ ///
+ /// resource.loader.modificationCheckInterval property of the resource loader configuration
+ ///
+ public const string PropertyResourceLoaderModificationCheckInterval = "resource.loader.modificationCheckInterval";
+
+ ///
+ /// the type used for file resource loader
+ ///
+ public const string FileResourceLoaderClass = "NVelocity.Runtime.Resource.Loader.FileResourceLoader; NVelocity";
+
+ ///
+ /// the type used for assembly resource loader
+ ///
+ public const string AssemblyResourceLoaderClass = "NVelocity.Runtime.Resource.Loader.AssemblyResourceLoader; NVelocity";
+
+ ///
+ /// the type used for spring resource loader
+ ///
+ public const string SpringResourceLoaderClass = "Spring.Template.Velocity.SpringResourceLoader; Spring.Template.Velocity";
}
#endregion
}
diff --git a/src/Spring/Spring.Template.Velocity/Template/Velocity/Config/spring-nvelocity-1.3.xsd b/src/Spring/Spring.Template.Velocity/Template/Velocity/Config/spring-nvelocity-1.3.xsd
index e1d8060f..951d33cb 100644
--- a/src/Spring/Spring.Template.Velocity/Template/Velocity/Config/spring-nvelocity-1.3.xsd
+++ b/src/Spring/Spring.Template.Velocity/Template/Velocity/Config/spring-nvelocity-1.3.xsd
@@ -50,7 +50,8 @@
-
+
@@ -58,7 +59,8 @@
-
+
@@ -66,7 +68,8 @@
-
+
@@ -79,9 +82,10 @@
-
+
-
+
@@ -94,7 +98,8 @@
-
+
@@ -104,14 +109,73 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ .loader.description property) of the resource loader]]>
+
+
+
+
+ .resource.loader.class property) of the resource loader]]>
+
+
+
+
+ .resource.loader.path property) of the resource loader]]>
+
+
+
+
-
+
-
+
+
+
+
+
+
+
+
+ .resource.loader.cache property) of the resource loader).]]>
+
+
+
+
+
+ .resource.loader.modificationCheckInterval property) of the resource loader,
+ applies only to resource loader with change detection capabilities (file or custom)]]>
-
-
diff --git a/src/Spring/Spring.Template.Velocity/Template/Velocity/VelocityConstants.cs b/src/Spring/Spring.Template.Velocity/Template/Velocity/VelocityConstants.cs
new file mode 100644
index 00000000..09e64d37
--- /dev/null
+++ b/src/Spring/Spring.Template.Velocity/Template/Velocity/VelocityConstants.cs
@@ -0,0 +1,12 @@
+namespace Spring.Template.Velocity{
+ public class VelocityConstants{
+ public const string File = "file";
+ public const string Type = "type";
+ public const string Assembly = "assembly";
+ public const string Class = "class";
+ public const string Name = "name";
+ public const string Description = "description";
+ public const string Path = "path";
+ public const string Separator = ".";
+ }
+}
\ No newline at end of file
diff --git a/src/Spring/Spring.Template.Velocity/Template/Velocity/VelocityEngineFactory.cs b/src/Spring/Spring.Template.Velocity/Template/Velocity/VelocityEngineFactory.cs
index 6fbe5f91..34dc126b 100644
--- a/src/Spring/Spring.Template.Velocity/Template/Velocity/VelocityEngineFactory.cs
+++ b/src/Spring/Spring.Template.Velocity/Template/Velocity/VelocityEngineFactory.cs
@@ -31,6 +31,7 @@ using NVelocity.Runtime;
using NVelocity.Runtime.Resource.Loader;
using Spring.Context.Support;
using Spring.Core.IO;
+using Spring.Util;
namespace Spring.Template.Velocity {
///
@@ -195,18 +196,17 @@ namespace Spring.Template.Velocity {
///
///
public VelocityEngine CreateVelocityEngine() {
- VelocityEngine velocityEngine = NewVelocityEngine();
ExtendedProperties extendedProperties = new ExtendedProperties();
+ VelocityEngine velocityEngine = NewVelocityEngine();
- // load defaults - see documentation why this is needed
- LoadDefaultProperties(velocityEngine);
+ LoadDefaultProperties(extendedProperties);
// Load config file if set.
if (configLocation != null) {
if (log.IsInfoEnabled) {
log.Info(string.Format("Loading Velocity config from [{0}]", configLocation));
}
- FillProperties(extendedProperties, configLocation);
+ FillProperties(extendedProperties, configLocation, false);
}
// merge local properties if set.
@@ -217,12 +217,12 @@ namespace Spring.Template.Velocity {
}
// Set a resource loader path, if required.
- if( !preferFileSystemAccess && resourceLoaderPaths.Count == 0){
+ if (!preferFileSystemAccess && resourceLoaderPaths.Count == 0) {
throw new ArgumentException("When using SpringResourceLoader you must provide a path using the ResourceLoaderPath property");
}
if (resourceLoaderPaths.Count > 0) {
- InitVelocityResourceLoader(velocityEngine, resourceLoaderPaths);
+ InitVelocityResourceLoader(velocityEngine, extendedProperties, resourceLoaderPaths);
}
// Log via Commons Logging?
@@ -233,13 +233,7 @@ namespace Spring.Template.Velocity {
PostProcessVelocityEngine(velocityEngine);
try {
- // do not init with extended properties rather set one by one
- foreach (DictionaryEntry property in extendedProperties) {
- velocityEngine.SetProperty(Convert.ToString(property.Key), property.Value);
- }
-
- // velocity engine initialization - required
- velocityEngine.Init();
+ velocityEngine.Init(extendedProperties);
} catch (Exception ex) {
throw new VelocityException(ex.ToString(), ex);
}
@@ -261,16 +255,11 @@ namespace Spring.Template.Velocity {
/// directive.manager=NVelocity.Runtime.Directive.DirectiveManager
/// runtime.introspector.uberspect=NVelocity.Util.Introspection.UberspectImpl
///
- /// the instance of the velocity engine unto which we load the default properties
- private static void LoadDefaultProperties(VelocityEngine velocityEngine) {
- ExtendedProperties extendedProperties = new ExtendedProperties();
+ private static void LoadDefaultProperties(ExtendedProperties extendedProperties) {
IResource defaultRuntimeProperties = new AssemblyResource("assembly://NVelocity/NVelocity.Runtime.Defaults/nvelocity.properties");
IResource defaultRuntimeDirectives = new AssemblyResource("assembly://NVelocity/NVelocity.Runtime.Defaults/directive.properties");
- FillProperties(extendedProperties, defaultRuntimeProperties);
- FillProperties(extendedProperties, defaultRuntimeDirectives);
- foreach (DictionaryEntry property in extendedProperties) {
- velocityEngine.SetProperty(Convert.ToString(property.Key), property.Value);
- }
+ FillProperties(extendedProperties, defaultRuntimeProperties, true);
+ FillProperties(extendedProperties, defaultRuntimeDirectives, true);
}
///
@@ -295,51 +284,37 @@ namespace Spring.Template.Velocity {
///
///
///
- protected void InitVelocityResourceLoader(VelocityEngine velocityEngine, IList paths) {
-
+ protected void InitVelocityResourceLoader(VelocityEngine velocityEngine, ExtendedProperties extendedProperties, IList paths) {
+
if (PreferFileSystemAccess) {
// Try to load via the file system, fall back to SpringResourceLoader
// (for hot detection of template changes, if possible).
IList resolvedPaths = new ArrayList();
- foreach (string path in paths){
+ foreach (string path in paths) {
IResource resource = ResourceLoader.GetResource(path);
resolvedPaths.Add(resource.File.FullName);
}
try {
-
- velocityEngine.SetProperty(RuntimeConstants.RESOURCE_LOADER, "file");
- velocityEngine.SetProperty(RuntimeConstants.FILE_RESOURCE_LOADER_CACHE, "true");
- velocityEngine.SetProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, joinList(resolvedPaths));
+ extendedProperties.SetProperty(RuntimeConstants.RESOURCE_LOADER, VelocityConstants.File);
+ extendedProperties.SetProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH,
+ StringUtils.CollectionToCommaDelimitedString(resolvedPaths));
} catch (IOException ex) {
if (log.IsDebugEnabled) {
- log.Error(string.Format("Cannot resolve resource loader path [{0}] to [File]: using SpringResourceLoader", joinList(resolvedPaths)), ex);
+ log.Error(string.Format("Cannot resolve resource loader path [{0}] to [File]: using SpringResourceLoader",
+ StringUtils.CollectionToCommaDelimitedString(resolvedPaths)), ex);
}
- InitSpringResourceLoader(velocityEngine, joinList(paths));
+ InitSpringResourceLoader(velocityEngine, extendedProperties, StringUtils.CollectionToCommaDelimitedString(paths));
}
} else {
// Always load via SpringResourceLoader (without hot detection of template changes).
if (log.IsDebugEnabled) {
log.Debug("File system access not preferred: using SpringResourceLoader");
}
- InitSpringResourceLoader(velocityEngine, joinList(paths));
+ InitSpringResourceLoader(velocityEngine, extendedProperties, StringUtils.CollectionToCommaDelimitedString(paths));
}
}
- ///
- /// Join the list of strings to a comma delimited string
- ///
- /// values list of strings to join
- /// comma delimited string representation of the list
- private static string joinList(IList values) {
- StringBuilder result = new StringBuilder();
- foreach (string value in values) {
- result.Append(value);
- result.Append(DELIMITER);
- }
- return result.ToString(0, result.Length < 1 ? 0 : result.Length - 1);
- }
-
///
/// Initialize a SpringResourceLoader for the given VelocityEngine.
/// Called by InitVelocityResourceLoader.
@@ -354,12 +329,11 @@ namespace Spring.Template.Velocity {
/// resourceLoaderPath the path to load Velocity resources from
///
///
- protected void InitSpringResourceLoader(VelocityEngine velocityEngine, string resourceLoaderPathString) {
- velocityEngine.SetProperty(RuntimeConstants.RESOURCE_LOADER, SpringResourceLoader.NAME);
+ protected void InitSpringResourceLoader(VelocityEngine velocityEngine, ExtendedProperties extendedProperties, string resourceLoaderPathString) {
+ extendedProperties.SetProperty(RuntimeConstants.RESOURCE_LOADER, SpringResourceLoader.NAME);
Type springResourceLoaderType = typeof(SpringResourceLoader);
string springResourceLoaderTypeName = springResourceLoaderType.FullName + "; " + springResourceLoaderType.Assembly.GetName().Name;
- velocityEngine.SetProperty(SpringResourceLoader.SPRING_RESOURCE_LOADER_CLASS, springResourceLoaderTypeName);
- velocityEngine.SetProperty(SpringResourceLoader.SPRING_RESOURCE_LOADER_CACHE, "true");
+ extendedProperties.SetProperty(SpringResourceLoader.SPRING_RESOURCE_LOADER_CLASS, springResourceLoaderTypeName);
velocityEngine.SetApplicationAttribute(SpringResourceLoader.SPRING_RESOURCE_LOADER, ResourceLoader);
velocityEngine.SetApplicationAttribute(SpringResourceLoader.SPRING_RESOURCE_LOADER_PATH, resourceLoaderPathString);
}
@@ -375,7 +349,7 @@ namespace Spring.Template.Velocity {
///
///
///
- protected static void PostProcessVelocityEngine(VelocityEngine velocityEngine) {
+ protected void PostProcessVelocityEngine(VelocityEngine velocityEngine) {
}
///
@@ -383,9 +357,18 @@ namespace Spring.Template.Velocity {
///
/// ExtendedProperties instance to populate
/// The resource from which to load the properties
- private static void FillProperties(ExtendedProperties extendedProperties, IInputStreamSource resource) {
+ /// A flag indicated weather the properties loaded from the resource should be appended or replaced in the extendedProperties
+ private static void FillProperties(ExtendedProperties extendedProperties, IInputStreamSource resource, bool append) {
try {
- extendedProperties.Load(resource.InputStream);
+ if (append) {
+ extendedProperties.Load(resource.InputStream);
+ } else {
+ ExtendedProperties overrides = new ExtendedProperties();
+ overrides.Load(resource.InputStream);
+ foreach (DictionaryEntry entry in overrides) {
+ extendedProperties.SetProperty(Convert.ToString(entry.Key), entry.Value);
+ }
+ }
} finally {
resource.InputStream.Close();
}
diff --git a/test/Spring/Spring.Template.Velocity.Tests/Spring.Template.Velocity.Tests.csproj b/test/Spring/Spring.Template.Velocity.Tests/Spring.Template.Velocity.Tests.csproj
index 9a8023e8..776b9e23 100644
--- a/test/Spring/Spring.Template.Velocity.Tests/Spring.Template.Velocity.Tests.csproj
+++ b/test/Spring/Spring.Template.Velocity.Tests/Spring.Template.Velocity.Tests.csproj
@@ -47,7 +47,9 @@
+
+
@@ -75,6 +77,8 @@
Always
+
+
diff --git a/test/Spring/Spring.Template.Velocity.Tests/Template/Velocity/Config/TemplateNamespaceParserTests.cs b/test/Spring/Spring.Template.Velocity.Tests/Template/Velocity/Config/TemplateNamespaceParserTests.cs
new file mode 100644
index 00000000..99f142a1
--- /dev/null
+++ b/test/Spring/Spring.Template.Velocity.Tests/Template/Velocity/Config/TemplateNamespaceParserTests.cs
@@ -0,0 +1,192 @@
+#region License
+
+/*
+ * Copyright 2002-2004 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#endregion
+
+#region Imports
+
+using System.Collections;
+using System.IO;
+using Commons.Collections;
+using NUnit.Framework;
+using NVelocity.App;
+using NVelocity.Runtime;
+using NVelocity.Runtime.Resource;
+using NVelocity.Runtime.Resource.Loader;
+using Spring.Core.IO;
+using Spring.Template.Velocity.Config;
+
+#endregion
+
+namespace Spring.Template.Velocity.Tests.Template.Velocity.Config {
+ ///
+ /// This class contains tests for the template namespace configuration parser
+ ///
+ /// Erez Mazor
+ [TestFixture]
+ public class TemplateNamespaceParserTests : VelocityEngineTestBase {
+ #region convinience properties aliases
+ private const string PropertyModificationCheck =
+ TemplateNamespaceParser.TemplateDefinitionConstants.PropertyResourceLoaderModificationCheckInterval;
+ private const string PropertyResourceLoaderCachce =
+ TemplateNamespaceParser.TemplateDefinitionConstants.PropertyResourceLoaderCaching;
+ #endregion
+
+ #region test constants
+ private const int DEFAULT_CACHE_SIZE = 200;
+ private const int DEFAULT_MOD_CHECK = 30;
+ private const bool DEFAULT_CACHE_FLAG = true;
+ #endregion
+
+ ///
+ /// Test a full file-base configuration
+ ///
+ [Test]
+ public void TestFileBasedConfig() {
+ VelocityEngine velocityEngine = appContext.GetObject("cnFileVelocityEngine") as VelocityEngine;
+ Assert.IsNotNull(velocityEngine, "velocity engine is null");
+ Assert.AreEqual(VelocityConstants.File, getSingleProperty(velocityEngine, RuntimeConstants.RESOURCE_LOADER), "incorrect resource loader");
+ Assert.AreEqual(TemplateNamespaceParser.TemplateDefinitionConstants.FileResourceLoaderClass, getSingleProperty(velocityEngine,
+ TemplateNamespaceParser.getResourceLoaderProperty(VelocityConstants.File, VelocityConstants.Class)), "incorrect resource loader type");
+ Assert.AreEqual(new string[]{"Template/Velocity/", "Template/"}, velocityEngine.GetProperty(
+ TemplateNamespaceParser.getResourceLoaderProperty(VelocityConstants.File, VelocityConstants.Path)), "incorrect resource loader path");
+ Assert.AreEqual(DEFAULT_CACHE_SIZE, velocityEngine.GetProperty(RuntimeConstants.RESOURCE_MANAGER_DEFAULTCACHE_SIZE), "incorrect default cache size");
+ Assert.AreEqual(DEFAULT_MOD_CHECK, velocityEngine.GetProperty(
+ VelocityConstants.File + VelocityConstants.Separator + PropertyModificationCheck), "incorrect mod check interval");
+ Assert.AreEqual(DEFAULT_CACHE_FLAG, velocityEngine.GetProperty(VelocityConstants.File + VelocityConstants.Separator + PropertyResourceLoaderCachce),
+ "incorrect caching flag");
+
+ AssertMergedValue(velocityEngine, "SimpleTemplate.vm");
+ }
+
+ ///
+ /// Test a full aaembly-based configuration
+ ///
+ [Test]
+ public void TestAssemblyBasedConfig() {
+ VelocityEngine velocityEngine = appContext.GetObject("cnAssemblyVelocityEngine") as VelocityEngine;
+ Assert.IsNotNull(velocityEngine, "velocity engine is null");
+ Assert.AreEqual(VelocityConstants.Assembly, getSingleProperty(velocityEngine, RuntimeConstants.RESOURCE_LOADER), "incorrect resource loader");
+ Assert.AreEqual(TemplateNamespaceParser.TemplateDefinitionConstants.AssemblyResourceLoaderClass, getSingleProperty(velocityEngine,
+ TemplateNamespaceParser.getResourceLoaderProperty(VelocityConstants.Assembly, VelocityConstants.Class)), "incorrect resource loader type");
+ Assert.AreEqual("Spring.Template.Velocity.Tests", getSingleProperty(velocityEngine,
+ TemplateNamespaceParser.getResourceLoaderProperty(VelocityConstants.Assembly,VelocityConstants.Assembly)), "incorrect resource loader path");
+ Assert.AreEqual(DEFAULT_CACHE_SIZE, velocityEngine.GetProperty(RuntimeConstants.RESOURCE_MANAGER_DEFAULTCACHE_SIZE), "incorrect default cache size");
+ Assert.AreEqual(DEFAULT_CACHE_FLAG, velocityEngine.GetProperty(VelocityConstants.Assembly + VelocityConstants.Separator + PropertyResourceLoaderCachce),
+ "incorrect caching flag");
+ AssertMergedValue(velocityEngine, "Spring.Template.Velocity.Tests.Template.Velocity.SimpleTemplate.vm");
+ }
+
+ ///
+ /// Test a full aaembly-based configuration
+ ///
+ [Test]
+ public void TestSpringBasedConfig() {
+ VelocityEngine velocityEngine = appContext.GetObject("cnSpringVelocityEngine") as VelocityEngine;
+ Assert.IsNotNull(velocityEngine, "velocity engine is null");
+ const string PropertySpring = TemplateNamespaceParser.TemplateDefinitionConstants.Spring;
+ Assert.AreEqual(PropertySpring, getSingleProperty(velocityEngine, RuntimeConstants.RESOURCE_LOADER), "incorrect resource loader");
+ Assert.AreEqual(TemplateNamespaceParser.TemplateDefinitionConstants.SpringResourceLoaderClass, getSingleProperty(velocityEngine,
+ TemplateNamespaceParser.getResourceLoaderProperty(PropertySpring, VelocityConstants.Class)), "incorrect resource loader type");
+ // no way to test the path property other than trying to actually perform a merge (it is set in velocity engine as an application attribute which is not exposed)
+ Assert.AreEqual(DEFAULT_CACHE_SIZE, velocityEngine.GetProperty(RuntimeConstants.RESOURCE_MANAGER_DEFAULTCACHE_SIZE), "incorrect default cache size");
+ Assert.AreEqual(DEFAULT_CACHE_FLAG, velocityEngine.GetProperty(PropertySpring + VelocityConstants.Separator + PropertyResourceLoaderCachce),
+ "incorrect caching flag");
+
+ AssertMergedValue(velocityEngine, "SimpleTemplate.vm");
+ AssertMergedValue(velocityEngine, "EmbeddedTemplate.vm");
+ }
+
+ ///
+ /// Test using an external configuration properties definition
+ ///
+ [Test]
+ public void TestGlobalConfig() {
+ VelocityEngine velocityEngine = appContext.GetObject("cnVelocityEngineConfig") as VelocityEngine;
+ Assert.IsNotNull(velocityEngine, "velocity engine is null");
+
+ string classProp = TemplateNamespaceParser.getResourceLoaderProperty(VelocityConstants.Assembly, VelocityConstants.Class);
+ string descProp = TemplateNamespaceParser.getResourceLoaderProperty(VelocityConstants.Assembly, VelocityConstants.Description);
+
+ Assert.AreEqual(VelocityConstants.Assembly, getSingleProperty(velocityEngine, RuntimeConstants.RESOURCE_LOADER), "incorrect resource loader");
+ Assert.AreEqual("NVelocity.Runtime.Resource.Loader.AssemblyResourceLoader",
+ getSingleProperty(velocityEngine,classProp), "incorrect resource loader type");
+ Assert.AreEqual("TestDescription", getSingleProperty(velocityEngine, descProp), "incorrect description");
+ }
+
+ ///
+ /// Test a custom resource loader definition
+ ///
+ [Test]
+ public void TestCustomResourceLoader() {
+ VelocityEngine velocityEngine = appContext.GetObject("cnVelocityEngingCustomResourceLoader") as VelocityEngine;
+ Assert.IsNotNull(velocityEngine, "velocity engine is null");
+ const string PropertyMyResourceLoader = "myResourceLoader";
+ string classProp = TemplateNamespaceParser.getResourceLoaderProperty(PropertyMyResourceLoader, VelocityConstants.Class);
+ string descProp = TemplateNamespaceParser.getResourceLoaderProperty(PropertyMyResourceLoader, VelocityConstants.Description);
+
+ Assert.AreEqual(PropertyMyResourceLoader, getSingleProperty(velocityEngine, RuntimeConstants.RESOURCE_LOADER), "incorrect resource loader");
+
+ Assert.AreEqual("Spring.Template.Velocity.Tests.Template.Velocity.Config.TestCustomResourceLoader; Spring.Template.Velocity.Tests",
+ getSingleProperty(velocityEngine, classProp), "incorrect resource loader type");
+ Assert.AreEqual(PropertyMyResourceLoader, getSingleProperty(velocityEngine, RuntimeConstants.RESOURCE_LOADER), "incorrect resource loader");
+ Assert.AreEqual("A custom resource loader",
+ getSingleProperty(velocityEngine, descProp), "incorrect resource loader description");
+ Assert.AreEqual("Template/Velocity/", getSingleProperty(velocityEngine,
+ TemplateNamespaceParser.getResourceLoaderProperty(PropertyMyResourceLoader, VelocityConstants.Path)), "incorrect resource loader path");
+
+ AssertMergedValue(velocityEngine, "Template/Velocity/SimpleTemplate.vm");
+ }
+
+ #region internal test methods
+ ///
+ /// Grab a single property from (if it's an array return the first value) from the velocityEngine
+ ///
+ private string getSingleProperty(VelocityEngine velocityEngine, string prop) {
+ object property = velocityEngine.GetProperty(prop);
+ if (property is ArrayList) {
+ ArrayList list = (ArrayList)property;
+ return (string)list[0];
+ }
+ return (string)property;
+ }
+ #endregion
+ }
+
+ #region test classes
+ ///
+ /// Test class for a custom resource loader class
+ ///
+ internal sealed class TestCustomResourceLoader : ResourceLoader {
+ public override void Init(ExtendedProperties configuration) {
+ }
+
+ public override Stream GetResourceStream(string source) {
+ return new ConfigurableResourceLoader().GetResource(source).InputStream;
+ }
+
+ public override bool IsSourceModified(Resource resource) {
+ return false;
+ }
+
+ public override long GetLastModified(Resource resource) {
+ return resource.LastModified;
+ }
+ }
+ #endregion
+}
\ No newline at end of file
diff --git a/test/Spring/Spring.Template.Velocity.Tests/Template/Velocity/EmbeddedTemplate.vm b/test/Spring/Spring.Template.Velocity.Tests/Template/Velocity/EmbeddedTemplate.vm
new file mode 100644
index 00000000..07da26e3
--- /dev/null
+++ b/test/Spring/Spring.Template.Velocity.Tests/Template/Velocity/EmbeddedTemplate.vm
@@ -0,0 +1 @@
+value=${var1}
\ No newline at end of file
diff --git a/test/Spring/Spring.Template.Velocity.Tests/Template/Velocity/VelocityEngineFactoryObjectTests.cs b/test/Spring/Spring.Template.Velocity.Tests/Template/Velocity/VelocityEngineFactoryObjectTests.cs
index 2c8113ab..9dc9f54c 100644
--- a/test/Spring/Spring.Template.Velocity.Tests/Template/Velocity/VelocityEngineFactoryObjectTests.cs
+++ b/test/Spring/Spring.Template.Velocity.Tests/Template/Velocity/VelocityEngineFactoryObjectTests.cs
@@ -21,42 +21,20 @@
#region Imports
using System;
-using System.Collections;
-using System.Text;
using NUnit.Framework;
using NVelocity.App;
-using Spring.Context.Support;
-using Spring.Objects.Factory.Xml;
#endregion
namespace Spring.Template.Velocity.Tests.Template.Velocity {
+
///
/// This class contains tests for VelocityEngineFactoryObject
///
/// Mark Pollack
/// Erez Mazor
[TestFixture]
- public class VelocityEngineFactoryObjectTests {
- private const string TEST_VALUE = "TEST_VALUE";
- private XmlApplicationContext appContext;
- private readonly Hashtable model = new Hashtable();
-
- [SetUp]
- public void Setup() {
- appContext = new XmlApplicationContext(false,
- ReadOnlyXmlTestResource.GetFilePath(
- "VelocityEngineFactoryObjectTests.xml",
- typeof(VelocityEngineFactoryObjectTests)));
- model.Add("var1", TEST_VALUE);
- }
-
- [TearDown]
- public void TearDown() {
- appContext.Dispose();
- model.Clear();
- }
-
+ public class VelocityEngineFactoryObjectTests : VelocityEngineTestBase {
///
/// Test the assemblyBasedVelocityEngine bean configuration from VelocityEngineFactoryObjectTests.xml
///
@@ -64,9 +42,8 @@ namespace Spring.Template.Velocity.Tests.Template.Velocity {
public void TestMergeUsingAssembly() {
VelocityEngine velocityEngine = appContext.GetObject("assemblyBasedVelocityEngine") as VelocityEngine;
Assert.IsNotNull(velocityEngine, "velocityEngine is null");
- string mergedTemplate = VelocityEngineUtils.MergeTemplateIntoString(velocityEngine, "Spring.Template.Velocity.Tests.Template.Velocity.SimpleTemplate.vm", Encoding.UTF8.WebName, model);
- Assert.AreEqual(string.Format("value={0}", TEST_VALUE), mergedTemplate);
- }
+ AssertMergedValue(velocityEngine, "Spring.Template.Velocity.Tests.Template.Velocity.SimpleTemplate.vm");
+ }
///
/// Test the fileBasedVelocityEngine bean configuration from VelocityEngineFactoryObjectTests.xml
@@ -75,9 +52,7 @@ namespace Spring.Template.Velocity.Tests.Template.Velocity {
public void TestMergeUsingFile() {
VelocityEngine velocityEngine = appContext.GetObject("fileBasedVelocityEngine") as VelocityEngine;
Assert.IsNotNull(velocityEngine, "velocityEngine is null");
- string mergedTemplate = VelocityEngineUtils.MergeTemplateIntoString(
- velocityEngine, "Template/Velocity/SimpleTemplate.vm", Encoding.UTF8.WebName, model);
- Assert.AreEqual(string.Format("value={0}", TEST_VALUE), mergedTemplate);
+ AssertMergedValue(velocityEngine, "Template/Velocity/SimpleTemplate.vm");
}
///
@@ -86,11 +61,9 @@ namespace Spring.Template.Velocity.Tests.Template.Velocity {
[Test]
public void TestMergeUsingCustomNamespaceDefinition() {
VelocityEngine velocityEngine =
- appContext.GetObject("customNamespaceVelocityTemplate") as VelocityEngine;
+ appContext.GetObject("cnFileVelocityEngine") as VelocityEngine;
Assert.IsNotNull(velocityEngine, "velocityEngine is null");
- string mergedTemplate = VelocityEngineUtils.MergeTemplateIntoString(velocityEngine, "SimpleTemplate.vm",
- Encoding.UTF8.WebName, model);
- Assert.AreEqual(string.Format("value={0}", "TEST_VALUE"), mergedTemplate);
+ AssertMergedValue(velocityEngine, "SimpleTemplate.vm");
}
///
@@ -101,9 +74,7 @@ namespace Spring.Template.Velocity.Tests.Template.Velocity {
VelocityEngine velocityEngine =
appContext.GetObject("pathBasedVelocityEngine") as VelocityEngine;
Assert.IsNotNull(velocityEngine, "velocityEngine is null");
- string mergedTemplate = VelocityEngineUtils.MergeTemplateIntoString(velocityEngine, "SimpleTemplate.vm",
- Encoding.UTF8.WebName, model);
- Assert.AreEqual(string.Format("value={0}", "TEST_VALUE"), mergedTemplate);
+ AssertMergedValue(velocityEngine, "SimpleTemplate.vm");
}
///
@@ -114,10 +85,7 @@ namespace Spring.Template.Velocity.Tests.Template.Velocity {
VelocityEngine velocityEngine =
appContext.GetObject("propertiesFileBasedVelocityEngine") as VelocityEngine;
Assert.IsNotNull(velocityEngine, "velocityEngine is null");
- string mergedTemplate = VelocityEngineUtils.MergeTemplateIntoString(velocityEngine,
- "Spring.Template.Velocity.Tests.Template.Velocity.SimpleTemplate.vm",
- Encoding.UTF8.WebName, model);
- Assert.AreEqual(string.Format("value={0}", "TEST_VALUE"), mergedTemplate);
+ AssertMergedValue(velocityEngine, "Spring.Template.Velocity.Tests.Template.Velocity.SimpleTemplate.vm");
}
///
@@ -128,9 +96,7 @@ namespace Spring.Template.Velocity.Tests.Template.Velocity {
VelocityEngine velocityEngine =
appContext.GetObject("springResourceLoaderBasedVelocityEngine") as VelocityEngine;
Assert.IsNotNull(velocityEngine, "velocityEngine is null");
- string mergedTemplate = VelocityEngineUtils.MergeTemplateIntoString(velocityEngine, "SimpleTemplate.vm",
- Encoding.UTF8.WebName, model);
- Assert.AreEqual(string.Format("value={0}", "TEST_VALUE"), mergedTemplate);
+ AssertMergedValue(velocityEngine, "SimpleTemplate.vm");
}
///
diff --git a/test/Spring/Spring.Template.Velocity.Tests/Template/Velocity/VelocityEngineFactoryObjectTests.xml b/test/Spring/Spring.Template.Velocity.Tests/Template/Velocity/VelocityEngineFactoryObjectTests.xml
index 2e17a5fa..567bb04d 100644
--- a/test/Spring/Spring.Template.Velocity.Tests/Template/Velocity/VelocityEngineFactoryObjectTests.xml
+++ b/test/Spring/Spring.Template.Velocity.Tests/Template/Velocity/VelocityEngineFactoryObjectTests.xml
@@ -1,12 +1,37 @@
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+