SPRNET-1237: Custom namespace enhancements and some bug fixes
- Parsing of velocity properties in custom namespace - Additional configuration options for velocity resource loader and resource manager - Additional namespace element for spring and custom resource loader definitions
This commit is contained in:
@@ -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 <xref
|
||||
linkend="context-custom-parsers" />. </para>
|
||||
linkend="context-custom-parsers" />.</para>
|
||||
|
||||
<section xml:id="templating-nvelocity-file">
|
||||
<title>Simple file based template engine definition</title>
|
||||
@@ -67,7 +67,8 @@
|
||||
</objects></programlisting>
|
||||
|
||||
<para>The velocity engine could then be used to load and merge a local
|
||||
template using a simple relative path:</para>
|
||||
template using a simple relative path (the default resource loader path
|
||||
is the current execution directory):</para>
|
||||
|
||||
<programlisting language="csharp">StringWriter stringWriter = new StringWriter();
|
||||
Hashtable modelTable = new Hashtable();
|
||||
@@ -81,6 +82,86 @@ string mergedContent = stringWriter.ToString();</programlisting>
|
||||
<engine/> to false.</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="templating-nvelocity-engine-configuration">
|
||||
<title>Configuration Options</title>
|
||||
|
||||
<para>You can define several attributes on the <engine> element to
|
||||
control how the factory is configured:</para>
|
||||
|
||||
<table id="template-velocity-engine-config-tbl">
|
||||
<title>Engine Factory Configuration Options</title>
|
||||
|
||||
<tgroup cols="4">
|
||||
<colspec colname="c1" colwidth="2*" />
|
||||
|
||||
<colspec colname="c2" colwidth="4*" />
|
||||
|
||||
<colspec colname="c3" colwidth="1*" />
|
||||
|
||||
<colspec colname="c4" colwidth="1*" />
|
||||
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Attribute</entry>
|
||||
|
||||
<entry>Description</entry>
|
||||
|
||||
<entry>Required</entry>
|
||||
|
||||
<entry>Default Value</entry>
|
||||
</row>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>config-file</entry>
|
||||
|
||||
<entry>
|
||||
<para>A uri of a properties file defining the NVelocity
|
||||
configuration. This value accepts all spring resource loader
|
||||
uri (e.g., file://, http://). See <xref
|
||||
linkend="templating-nvelocity-resource-config" /></para>
|
||||
</entry>
|
||||
|
||||
<entry>no</entry>
|
||||
|
||||
<entry>N/A</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>prefer-file-system-access</entry>
|
||||
|
||||
<entry>
|
||||
<para>Instructs the NVelocity engine factory to attempt use
|
||||
NVelocity's file loader. When set to false the provided
|
||||
<literal>SpringResourceLoader</literal> will be used (and the <literal>ResourceLoaderPath</literal>
|
||||
property must be set)</para>
|
||||
</entry>
|
||||
|
||||
<entry>no</entry>
|
||||
|
||||
<entry>true</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>override-logging</entry>
|
||||
|
||||
<entry>
|
||||
<para>Instructs the NVelocity engine factory to use the
|
||||
provided spring commons logging based logging system. See See
|
||||
<xref
|
||||
linkend="templating-nvelocity-resource-logging" /></para>
|
||||
</entry>
|
||||
|
||||
<entry>no</entry>
|
||||
|
||||
<entry>true</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</section>
|
||||
|
||||
<section xml:id="templating-nvelocity-assembly">
|
||||
<title>Assembly based template loading</title>
|
||||
|
||||
@@ -99,7 +180,7 @@ string mergedContent = stringWriter.ToString();</programlisting>
|
||||
<programlisting language="csharp">velocityEngine.MergeTemplate("MyAssembly.MyNamespace.MyTemplate.vm", Encoding.UTF8.WebName, velocityContext, stringWriter);</programlisting>
|
||||
</section>
|
||||
|
||||
<section xml:id="templating-nvelocity-resource-loader">
|
||||
<section xml:id="templating-nvelocity-spring-resource-loader">
|
||||
<title>Using Spring's <literal>IResourceLoader</literal> to load
|
||||
templates</title>
|
||||
|
||||
@@ -110,9 +191,9 @@ string mergedContent = stringWriter.ToString();</programlisting>
|
||||
object definition loads the NVelocity templates from a single
|
||||
path</para>
|
||||
|
||||
<programlisting><nv:engine id="velocityEngine">
|
||||
<programlisting language="myxml"><nv:engine id="velocityEngine">
|
||||
<nv:resource-loader>
|
||||
<nv:file path="MyTemplateFolder/AnotherFolder/" />
|
||||
<nv:spring uri="file://Template/Velocity/"/>
|
||||
</nv:resource-loader>
|
||||
</nv:engine></programlisting>
|
||||
|
||||
@@ -120,24 +201,127 @@ string mergedContent = stringWriter.ToString();</programlisting>
|
||||
|
||||
<programlisting language="myxml"><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>
|
||||
</programlisting>
|
||||
|
||||
<note>
|
||||
<para>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
|
||||
<literal>prefer-file-system-access</literal> element of the
|
||||
</engine> element to <literal>false.</literal></para>
|
||||
<para>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
|
||||
<literal>prefer-file-system-access</literal> property of the factory object
|
||||
to <literal>false</literal> which will cause the factory to utilize the supplied
|
||||
spring resource loader.</para>
|
||||
</note>
|
||||
|
||||
<para>Using the example above when resource loader paths are defined
|
||||
templates can be loaded using their name:</para>
|
||||
|
||||
<programlisting language="csharp">string mergedTemplate = VelocityEngineUtils.MergeTemplateIntostring(velocityEngine, "MyTemplate.vm", Encoding.UTF8.WebName, model);</programlisting>
|
||||
<programlisting language="csharp">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</programlisting>
|
||||
</section>
|
||||
|
||||
<section xml:id="templating-nvelocity-custom-resource-loader">
|
||||
<title>Defining a custom resource loader</title>
|
||||
|
||||
<para>The following defines a custom resource loader (the type is an
|
||||
extension of NVelocity's <literal>ResourceLoader</literal>
|
||||
class):</para>
|
||||
|
||||
<programlisting language="myxml"><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>
|
||||
</programlisting>
|
||||
</section>
|
||||
|
||||
<section xml:id="templating-nvelocity-resource-loader-configuration">
|
||||
<title>Resource Loader configuration options</title>
|
||||
|
||||
<para>The <nv:resource-loader> element has additional attributes
|
||||
which define how NVelocity's resource manager and resource loader
|
||||
behave.</para>
|
||||
|
||||
<table id="templating-nvelocity-resource-loader-configuration-tbl">
|
||||
<title>Resource Loader Configuration Options</title>
|
||||
|
||||
<tgroup cols="4">
|
||||
<colspec colname="c1" colwidth="2*" />
|
||||
|
||||
<colspec colname="c2" colwidth="4*" />
|
||||
|
||||
<colspec colname="c3" colwidth="1*" />
|
||||
|
||||
<colspec colname="c4" colwidth="1*" />
|
||||
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Attribute</entry>
|
||||
|
||||
<entry>Description</entry>
|
||||
|
||||
<entry>Required</entry>
|
||||
|
||||
<entry>Default Value</entry>
|
||||
</row>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>default-cache-size</entry>
|
||||
|
||||
<entry>
|
||||
<para>defines resource manager global cache size, applies when
|
||||
caching is turned on. This maps to NVelocity's resource
|
||||
manager <literal>resource.manager.defaultcache.size</literal>
|
||||
property</para>
|
||||
</entry>
|
||||
|
||||
<entry>no</entry>
|
||||
|
||||
<entry>89</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>template-caching</entry>
|
||||
|
||||
<entry>
|
||||
<para>Enables template caching for the defined resource
|
||||
loader. This maps to NVelocity's resource loader
|
||||
<literal><name>.resource.loader.cache</literal>
|
||||
property</para>
|
||||
</entry>
|
||||
|
||||
<entry>no</entry>
|
||||
|
||||
<entry>false</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>modification-check-interval</entry>
|
||||
|
||||
<entry>
|
||||
<para>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
|
||||
<literal><name>.resource.loader.modificationCheckInterval</literal>
|
||||
property</para>
|
||||
</entry>
|
||||
|
||||
<entry>no</entry>
|
||||
|
||||
<entry>2</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</section>
|
||||
|
||||
<section xml:id="templating-nvelocity-resource-config">
|
||||
@@ -152,7 +336,7 @@ string mergedContent = stringWriter.ToString();</programlisting>
|
||||
<literal>VelocityProperties</literal> property to the NVelocity factory
|
||||
object (shown above)</para>
|
||||
|
||||
<programlisting><nv:engine id="customNamespaceVelocityTemplate" config-file="foo.prop">
|
||||
<programlisting language="myxml"><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();</programlisting>
|
||||
</section>
|
||||
|
||||
<section xml:id="templating-nvelocity-resource-logging">
|
||||
|
||||
|
||||
<title>Logging</title>
|
||||
|
||||
|
||||
|
||||
<para>By default Spring will override NVelocity's default
|
||||
<literal>ILogSystem</literal> implementation with its own
|
||||
<literal>CommonsLoggingLogSystem</literal> implementation so that the
|
||||
@@ -174,12 +354,8 @@ string mergedContent = stringWriter.ToString();</programlisting>
|
||||
Spring uses. If this is not desirable, you can specify the following
|
||||
property of the NVelocity factory object:</para>
|
||||
|
||||
|
||||
|
||||
<programlisting language="myxml"><template:nvelocity id="velocityEngine" override-logging="false" />
|
||||
</programlisting>
|
||||
|
||||
|
||||
</section>
|
||||
</section>
|
||||
|
||||
@@ -202,7 +378,7 @@ string mergedContent = stringWriter.ToString();</programlisting>
|
||||
<para>To create a VelocityEngine using the default file resource loader
|
||||
use the definition:</para>
|
||||
|
||||
<programlisting><!-- Simple no arg file based configuration use's NVeclocity default file resource loader -->
|
||||
<programlisting language="myxml"><!-- Simple no arg file based configuration use's NVelocity default file resource loader -->
|
||||
<object id="velocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity" /></programlisting>
|
||||
|
||||
<para>For convenience in defining NVelocity engine instances a custom
|
||||
@@ -210,13 +386,13 @@ string mergedContent = stringWriter.ToString();</programlisting>
|
||||
done this way:</para>
|
||||
|
||||
<programlisting language="myxml">
|
||||
<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</programlisting>
|
||||
|
||||
@@ -224,7 +400,7 @@ string mergedContent = stringWriter.ToString();</programlisting>
|
||||
resource loader can be used to define where templates reside:</para>
|
||||
|
||||
<programlisting language="myxml"><!-- 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();</programlisting>
|
||||
</object></programlisting>
|
||||
|
||||
<note>
|
||||
<para>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
|
||||
<para>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
|
||||
<literal>preferFileSystemAccess</literal> property of the factory object
|
||||
to <literal>false.</literal></para>
|
||||
to <literal>false</literal> which will cause the factory to utilize the supplied
|
||||
spring resource loader.</para>
|
||||
</note>
|
||||
|
||||
<para>To refer to a property file based configuration of the
|
||||
@@ -275,7 +452,7 @@ string mergedContent = stringWriter.ToString();</programlisting>
|
||||
</note></para>
|
||||
|
||||
<para>To not integrate with the Common.Logging subsystem, set the
|
||||
OverrideLogging property to false: </para>
|
||||
OverrideLogging property to false:</para>
|
||||
|
||||
<programlisting language="myxml"><object id="velocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity" >
|
||||
<property name="OverrideLogging" value="false" />
|
||||
|
||||
@@ -69,7 +69,8 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="Template\Velocity\Config\TemplateNamespaceParser.cs" />
|
||||
<Compile Include="Template\Velocity\CommonsLoggingLogSystem.cs" />
|
||||
<Compile Include="Template\Velocity\SpringResourceLoader.cs" />
|
||||
<Compile Include="Template\Velocity\SpringResourceLoader.cs" />
|
||||
<Compile Include="Template\Velocity\VelocityConstants.cs" />
|
||||
<Compile Include="Template\Velocity\VelocityEngineFactory.cs" />
|
||||
<Compile Include="Template\Velocity\VelocityEngineFactoryObject.cs" />
|
||||
<Compile Include="Template\Velocity\VelocityEngineUtils.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 {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// Parses single object definition for the templating namespace
|
||||
/// </summary>
|
||||
/// <param name="element"></param>
|
||||
/// <param name="parserContext"></param>
|
||||
/// <param name="builder"></param>
|
||||
/// <param name="element">the current XmlElement to parse</param>
|
||||
/// <param name="parserContext">the parser context</param>
|
||||
/// <param name="builder">the ObjectDefinitionBuilder used to configure this object</param>
|
||||
/// <see cref="AbstractSingleObjectDefinitionParser"/>
|
||||
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) {
|
||||
/// <summary>
|
||||
/// Parses the object definition for the engine object, configures a single NVelocity template engine based
|
||||
/// on the element definitions.
|
||||
/// </summary>
|
||||
/// <param name="element">the root element defining the velocity engine</param>
|
||||
/// <param name="parserContext">the parser context</param>
|
||||
/// <param name="builder">the ObjectDefinitionBuilder used to configure this object</param>
|
||||
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) {
|
||||
/// <summary>
|
||||
/// Parses child element definitions for the NVelocity engine. Typically resource loaders and locally defined properties are parsed here
|
||||
/// </summary>
|
||||
/// <param name="childElements">the XmlNodeList representing the child configuration of the root NVelocity engine element</param>
|
||||
/// <param name="parserContext">the parser context</param>
|
||||
/// <param name="builder">the ObjectDefinitionBuilder used to configure this object</param>
|
||||
private void ParseChildDefinitions(XmlNodeList childElements, ParserContext parserContext, ObjectDefinitionBuilder builder) {
|
||||
IDictionary<string, object> properties = new Dictionary<string, object>();
|
||||
|
||||
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<string, object> properties) {
|
||||
string loaderTypeDefinition = GetAttributeValue(element, TemplateDefinitionConstants.AttributeLoaderType);
|
||||
/// <summary>
|
||||
/// Configures the NVelocity resource loader definitions from the xml definition
|
||||
/// </summary>
|
||||
/// <param name="element">the root resource loader element</param>
|
||||
/// <param name="builder">the ObjectDefinitionBuilder used to configure this object</param>
|
||||
/// <param name="properties">the properties used to initialize the velocity engine</param>
|
||||
private void ParseResourceLoader(XmlElement element, ObjectDefinitionBuilder builder, IDictionary<string, object> 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<string, object> 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);
|
||||
|
||||
/// <summary>
|
||||
/// Set the caching and modification interval checking properties of a resource loader of a given type
|
||||
/// </summary>
|
||||
/// <param name="properties">the properties used to initialize the velocity engine</param>
|
||||
/// <param name="type">type of the resource loader</param>
|
||||
/// <param name="caching">caching flag</param>
|
||||
/// <param name="modificationInterval">modification interval value</param>
|
||||
private void AppendResourceLoaderGlobalProperties(IDictionary<string, object> properties, string type, string caching, string modificationInterval) {
|
||||
AppendResourceLoaderGlobalProperty(properties, type,
|
||||
TemplateDefinitionConstants.PropertyResourceLoaderCaching,
|
||||
Convert.ToBoolean(caching));
|
||||
AppendResourceLoaderGlobalProperty
|
||||
(properties, type, TemplateDefinitionConstants.PropertyResourceLoaderModificationCheckInterval, Convert.ToInt64(modificationInterval));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set global velocity resource loader properties (caching, modification interval etc.)
|
||||
/// </summary>
|
||||
/// <param name="properties">the properties used to initialize the velocity engine</param>
|
||||
/// <param name="type">the type of resource loader</param>
|
||||
/// <param name="property">the suffix property</param>
|
||||
/// <param name="value">the value of the property</param>
|
||||
private void AppendResourceLoaderGlobalProperty(IDictionary<string, object> properties, string type, string property, object value) {
|
||||
if (null != value) {
|
||||
properties.Add(type + VelocityConstants.Separator + property, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a nvelocity file based resource loader by setting the required properties
|
||||
/// </summary>
|
||||
/// <param name="elements">a list of nv:file elements defining the paths to template files</param>
|
||||
/// <param name="properties">the properties used to initialize the velocity engine</param>
|
||||
private void AppendFileLoaderProperties(XmlNodeList elements, IDictionary<string, object> properties) {
|
||||
IList paths = new List<string>(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));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a nvelocity assembly based resource loader by setting the required properties
|
||||
/// </summary>
|
||||
/// <param name="elements">a list of nv:assembly elements defining the assemblies</param>
|
||||
/// <param name="properties">the properties used to initialize the velocity engine</param>
|
||||
private void AppendAssemblyLoaderProperties(XmlNodeList elements, IDictionary<string, object> properties) {
|
||||
IList assemblies = new List<string>(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));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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).
|
||||
/// </summary>
|
||||
/// <param name="elements">list of resource loader path elements</param>
|
||||
/// <param name="builder">the object definiton builder to set the property for the engine factory</param>
|
||||
private void AppendResourceLoaderPaths(XmlNodeList elements, ObjectDefinitionBuilder builder) {
|
||||
IList<string> paths = new List<string>();
|
||||
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<string, object> dictionary) {
|
||||
// todo add impl
|
||||
/// <summary>
|
||||
/// 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).
|
||||
/// </summary>
|
||||
/// <param name="element">the nv:custom xml definition element</param>
|
||||
/// <param name="properties">the properties used to initialize the velocity engine</param>
|
||||
private void AppendCustomLoaderProperties(XmlElement element, IDictionary<string, object> 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;
|
||||
/// <summary>
|
||||
/// Parses the nvelocity properties map using <code>ObjectNamespaceParserHelper</code>
|
||||
/// and appends it to the properties dictionary
|
||||
/// </summary>
|
||||
/// <param name="element">root element of the map element</param>
|
||||
/// <param name="parserContext">the parser context</param>
|
||||
/// <param name="properties">the properties used to initialize the velocity engine</param>
|
||||
private void ParseNVelocityProperties(XmlElement element, ParserContext parserContext, IDictionary<string, object> properties) {
|
||||
IDictionary parsedProperties = objectNamespaceParserHelper.ParseDictionaryElementInternal(element, "NVelocityProperties", parserContext);
|
||||
foreach (DictionaryEntry entry in parsedProperties) {
|
||||
properties.Add(Convert.ToString(entry.Key), entry.Value);
|
||||
}
|
||||
return typeName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// construct the element type name (e.g, nv:engine, nv:resource-loader)
|
||||
/// </summary>
|
||||
/// <param name="element">the current xml element</param>
|
||||
protected override string GetObjectTypeName(XmlElement element) {
|
||||
return TemplateTypePrefix + element.LocalName;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Helper class to access the ParseDictionaryElement of the ObjectsNamespaceParser
|
||||
/// todo: remove this and externalize the logic in ObjectsNamespaceParser.ParseDictionaryElement
|
||||
/// </summary>
|
||||
internal sealed class ObjectNamespaceParserHelper : ObjectsNamespaceParser {
|
||||
public IDictionary ParseDictionaryElementInternal(XmlElement element, string name, ParserContext parserContext) {
|
||||
return ParseDictionaryElement(element, name, parserContext);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// constructs an nvelocity style resource loader property in the format:
|
||||
/// prefix.resource.loader.suffix
|
||||
/// </summary>
|
||||
/// <param name="type">the prefix</param>
|
||||
/// <param name="suffix">the suffix</param>
|
||||
/// <returns>a concatenated string like: prefix.resource.loader.suffix</returns>
|
||||
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 {
|
||||
/// <summary>
|
||||
/// Template definition constants
|
||||
/// </summary>
|
||||
public class TemplateDefinitionConstants {
|
||||
/// <summary>
|
||||
/// Engine element definition
|
||||
/// </summary>
|
||||
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 {
|
||||
/// <summary>
|
||||
/// Spring resource loader element definition
|
||||
/// </summary>
|
||||
public const string Spring = "spring";
|
||||
|
||||
/// <summary>
|
||||
/// Custom resource loader element definition
|
||||
/// </summary>
|
||||
public const string Custom = "custom";
|
||||
|
||||
/// <summary>
|
||||
/// uri attribute of the spring element
|
||||
/// </summary>
|
||||
public const string AttributeUri = "uri";
|
||||
|
||||
/// <summary>
|
||||
/// prefer-file-system-access attribute of the engine factory
|
||||
/// </summary>
|
||||
public const string AttributePreferFileSystemAccess = "prefer-file-system-access";
|
||||
|
||||
/// <summary>
|
||||
/// config-file attribute of the engine factory
|
||||
/// </summary>
|
||||
public const string AttributeConfigFile = "config-file";
|
||||
|
||||
/// <summary>
|
||||
/// override-logging attribute of the engine factory
|
||||
/// </summary>
|
||||
public const string AttributeOverrideLogging = "override-logging";
|
||||
|
||||
/// <summary>
|
||||
/// template-caching attribute of the nvelocity engine
|
||||
/// </summary>
|
||||
public const string AttributeTemplateCaching = "template-caching";
|
||||
|
||||
/// <summary>
|
||||
/// default-cache-size attribute of the nvelocity engine resource manager
|
||||
/// </summary>
|
||||
public const string AttributeDefaultCacheSize = "default-cache-size";
|
||||
|
||||
/// <summary>
|
||||
/// modification-check-interval attribute of the nvelocity engine resource loader
|
||||
/// </summary>
|
||||
public const string AttributeModificationCheckInterval = "modification-check-interval";
|
||||
|
||||
/// <summary>
|
||||
/// resource loader element
|
||||
/// </summary>
|
||||
public const string ElementResourceLoader = "resource-loader";
|
||||
|
||||
/// <summary>
|
||||
/// nvelocity propeties element (map)
|
||||
/// </summary>
|
||||
public const string ElementNVelocityProperties = "nvelocity-properties";
|
||||
|
||||
/// <summary>
|
||||
/// PreferFileSystemAccess property of the engine factory
|
||||
/// </summary>
|
||||
public const string PropertyPreferFileSystemAccess = "PreferFileSystemAccess";
|
||||
|
||||
/// <summary>
|
||||
/// OverrideLogging property of the engine factory
|
||||
/// </summary>
|
||||
public const string PropertyOverrideLogging = "OverrideLogging";
|
||||
|
||||
/// <summary>
|
||||
/// ConfigLocation property of the engine factory
|
||||
/// </summary>
|
||||
public const string PropertyConfigFile = "ConfigLocation";
|
||||
|
||||
/// <summary>
|
||||
/// ResourceLoaderPaths property of the engine factory
|
||||
/// </summary>
|
||||
public const string PropertyResourceLoaderPaths = "ResourceLoaderPaths";
|
||||
|
||||
/// <summary>
|
||||
/// VelocityProperties property of the engine factory
|
||||
/// </summary>
|
||||
public const string PropertyVelocityProperties = "VelocityProperties";
|
||||
|
||||
/// <summary>
|
||||
/// resource.loader.cache property of the resource loader configuration
|
||||
/// </summary>
|
||||
public const string PropertyResourceLoaderCaching = "resource.loader.cache";
|
||||
|
||||
/// <summary>
|
||||
/// resource.loader.modificationCheckInterval property of the resource loader configuration
|
||||
/// </summary>
|
||||
public const string PropertyResourceLoaderModificationCheckInterval = "resource.loader.modificationCheckInterval";
|
||||
|
||||
/// <summary>
|
||||
/// the type used for file resource loader
|
||||
/// </summary>
|
||||
public const string FileResourceLoaderClass = "NVelocity.Runtime.Resource.Loader.FileResourceLoader; NVelocity";
|
||||
|
||||
/// <summary>
|
||||
/// the type used for assembly resource loader
|
||||
/// </summary>
|
||||
public const string AssemblyResourceLoaderClass = "NVelocity.Runtime.Resource.Loader.AssemblyResourceLoader; NVelocity";
|
||||
|
||||
/// <summary>
|
||||
/// the type used for spring resource loader
|
||||
/// </summary>
|
||||
public const string SpringResourceLoaderClass = "Spring.Template.Velocity.SpringResourceLoader; Spring.Template.Velocity";
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -50,7 +50,8 @@
|
||||
<xsd:attribute name="config-file" use="optional">
|
||||
<xsd:simpleType>
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[Optional location of a properties file defining the NVelocity configuration.]]></xsd:documentation>
|
||||
<xsd:documentation><![CDATA[Optional location of a properties file defining the
|
||||
NVelocity configuration.]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:restriction base="objects:nonNullString"/>
|
||||
</xsd:simpleType>
|
||||
@@ -58,7 +59,8 @@
|
||||
<xsd:attribute name="prefer-file-system-access" use="optional" default="true">
|
||||
<xsd:simpleType>
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[Optional. Instructs the NVelocity engine factory to attempt use NVelocity's file loader with hot tracking.]]></xsd:documentation>
|
||||
<xsd:documentation><![CDATA[Optional. Instructs the NVelocity engine factory to
|
||||
attempt use NVelocity's file loader with hot tracking.]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:restriction base="xsd:boolean"/>
|
||||
</xsd:simpleType>
|
||||
@@ -66,7 +68,8 @@
|
||||
<xsd:attribute name="override-logging" use="optional" default="true">
|
||||
<xsd:simpleType>
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[Optional. Instructs the NVelocity engine factory to use the provided spring commons logging based logging system.]]></xsd:documentation>
|
||||
<xsd:documentation><![CDATA[Optional. Instructs the NVelocity engine factory to use the provided
|
||||
spring commons logging based logging system.]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:restriction base="xsd:boolean"/>
|
||||
</xsd:simpleType>
|
||||
@@ -79,9 +82,10 @@
|
||||
<xsd:documentation><![CDATA[Defines Assembly based template loader.]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:choice>
|
||||
<xsd:element name="assembly" minOccurs="1" maxOccurs="1">
|
||||
<xsd:element name="assembly" minOccurs="1" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[The assembly where templates reside.]]></xsd:documentation>
|
||||
<xsd:documentation><![CDATA[An assembly based resource loader, when used
|
||||
NVelocity's AssemblyResourceLoader will be used.]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="name" type="objects:nonNullString" use="required">
|
||||
@@ -94,7 +98,8 @@
|
||||
</xsd:element>
|
||||
<xsd:element name="file" minOccurs="1" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[The location of the template files.]]></xsd:documentation>
|
||||
<xsd:documentation><![CDATA[A file based resource loader, when used NVelocity's
|
||||
FileResourceLoader will be used.]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="path" type="objects:nonNullString" use="required">
|
||||
@@ -104,14 +109,73 @@
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="spring" minOccurs="1" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[A spring resource loader based on spring's resource abstraction.
|
||||
When used detection of template changes is disabled]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="uri" type="objects:nonNullString" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[A fully qualified spring resource locator
|
||||
(e.g., file://, assembly://, http://) uri]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="custom" minOccurs="1" maxOccurs="1">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[A custom resource loader.]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="name" type="objects:nonNullString" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[A logical name (resource.loader property) for the resource loader
|
||||
(e.g., custom), cannot contain whitespace.]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="description" type="objects:nonNullString" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[Description (<name>.loader.description property) of the resource loader]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="type" type="objects:nonNullString" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[The type (<name>.resource.loader.class property) of the resource loader]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="path" type="objects:nonNullString" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[The paths (<name>.resource.loader.path property) of the resource loader]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
<xsd:attribute name="loader-type" type="objects:nonNullString" use="optional">
|
||||
<xsd:attribute name="default-cache-size" type="xsd:integer" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[Optional. The NVelocity.Runtime.Resource.Loader.ResourceLoader extension class used to load the files. By default a file based resource loader is used (unless prefer-file-system-access is set to false)]]></xsd:documentation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[Optional (default is 89, resource.manager.defaultcache.size property),
|
||||
defines resource manager global cache size
|
||||
applies when caching is turned on]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="template-caching" type="xsd:boolean" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[Enabled or disables template caching
|
||||
(<name>.resource.loader.cache property) of the resource loader).]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="modification-check-interval" type="xsd:integer" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[The modification check interval value
|
||||
(<name>.resource.loader.modificationCheckInterval property) of the resource loader,
|
||||
applies only to resource loader with change detection capabilities (file or custom)]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
|
||||
<xsd:element name="engine" type="nvelocityTemplate" />
|
||||
</xsd:schema>
|
||||
|
||||
@@ -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 = ".";
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
/// <summary>
|
||||
@@ -195,18 +196,17 @@ namespace Spring.Template.Velocity {
|
||||
/// <see cref="PostProcessVelocityEngine" />
|
||||
/// <see cref="VelocityEngine.Init()" />
|
||||
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 <br/>
|
||||
/// runtime.introspector.uberspect=NVelocity.Util.Introspection.UberspectImpl <br/>
|
||||
/// </summary>
|
||||
/// <param name="velocityEngine">the instance of the velocity engine unto which we load the default properties</param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -295,51 +284,37 @@ namespace Spring.Template.Velocity {
|
||||
/// <see cref="SpringResourceLoader"/>
|
||||
/// <see cref="InitSpringResourceLoader"/>
|
||||
/// <see cref="CreateVelocityEngine"/>
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Join the list of strings to a comma delimited string
|
||||
/// </summary>
|
||||
/// <param name="values">values list of strings to join</param>
|
||||
/// <returns>comma delimited string representation of the list</returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a SpringResourceLoader for the given VelocityEngine.
|
||||
/// <br/>Called by <code>InitVelocityResourceLoader</code>.
|
||||
@@ -354,12 +329,11 @@ namespace Spring.Template.Velocity {
|
||||
/// <param name="resourceLoaderPathString">resourceLoaderPath the path to load Velocity resources from</param>
|
||||
/// <see cref="SpringResourceLoader"/>
|
||||
/// <see cref="InitVelocityResourceLoader"/>
|
||||
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 {
|
||||
/// <exception cref="IOException" />
|
||||
/// <see cref="CreateVelocityEngine"/>
|
||||
/// <see cref="VelocityEngine.Init()"/>
|
||||
protected static void PostProcessVelocityEngine(VelocityEngine velocityEngine) {
|
||||
protected void PostProcessVelocityEngine(VelocityEngine velocityEngine) {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -383,9 +357,18 @@ namespace Spring.Template.Velocity {
|
||||
/// </summary>
|
||||
/// <param name="extendedProperties">ExtendedProperties instance to populate</param>
|
||||
/// <param name="resource">The resource from which to load the properties</param>
|
||||
private static void FillProperties(ExtendedProperties extendedProperties, IInputStreamSource resource) {
|
||||
/// <param name="append">A flag indicated weather the properties loaded from the resource should be appended or replaced in the extendedProperties</param>
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -47,7 +47,9 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Template\Velocity\Config\TemplateNamespaceParserTests.cs" />
|
||||
<Compile Include="Template\Velocity\VelocityEngineFactoryObjectTests.cs" />
|
||||
<Compile Include="Template\Velocity\VelocityEngineTestBase.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\src\Spring\Spring.Core\Spring.Core.2008.csproj">
|
||||
@@ -75,6 +77,8 @@
|
||||
<None Include="Template\Velocity\config.properties">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<EmbeddedResource Include="Template\Velocity\EmbeddedTemplate.vm">
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Properties\" />
|
||||
|
||||
@@ -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 {
|
||||
/// <summary>
|
||||
/// This class contains tests for the template namespace configuration parser
|
||||
/// </summary>
|
||||
/// <author>Erez Mazor</author>
|
||||
[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
|
||||
|
||||
/// <summary>
|
||||
/// Test a full file-base configuration
|
||||
/// </summary>
|
||||
[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");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test a full aaembly-based configuration
|
||||
/// </summary>
|
||||
[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");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test a full aaembly-based configuration
|
||||
/// </summary>
|
||||
[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");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test using an external configuration properties definition
|
||||
/// </summary>
|
||||
[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");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test a custom resource loader definition
|
||||
/// </summary>
|
||||
[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
|
||||
/// <summary>
|
||||
/// Grab a single property from (if it's an array return the first value) from the velocityEngine
|
||||
/// </summary>
|
||||
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
|
||||
/// <summary>
|
||||
/// Test class for a custom resource loader class
|
||||
/// </summary>
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
value=${var1}
|
||||
@@ -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 {
|
||||
|
||||
/// <summary>
|
||||
/// This class contains tests for VelocityEngineFactoryObject
|
||||
/// </summary>
|
||||
/// <author>Mark Pollack</author>
|
||||
/// <author>Erez Mazor</author>
|
||||
[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 {
|
||||
/// <summary>
|
||||
/// Test the assemblyBasedVelocityEngine bean configuration from VelocityEngineFactoryObjectTests.xml
|
||||
/// </summary>
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,12 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<objects xmlns="http://www.springframework.net" xmlns:nv="http://www.springframework.net/nvelocity">
|
||||
|
||||
<nv:engine id="customNamespaceVelocityTemplate">
|
||||
<nv:resource-loader>
|
||||
<nv:file path="Template/Velocity/" />
|
||||
<nv:engine id="cnFileVelocityEngine" >
|
||||
<nv:resource-loader default-cache-size="200" modification-check-interval="30" template-caching="true">
|
||||
<nv:file path="Template/Velocity/" />
|
||||
<nv:file path="Template/" />
|
||||
</nv:resource-loader>
|
||||
</nv:engine>
|
||||
|
||||
<nv:engine id="cnAssemblyVelocityEngine" >
|
||||
<nv:resource-loader default-cache-size="200" modification-check-interval="30" template-caching="true">
|
||||
<nv:assembly name="Spring.Template.Velocity.Tests" />
|
||||
</nv:resource-loader>
|
||||
</nv:engine>
|
||||
|
||||
<nv:engine id="cnSpringVelocityEngine" prefer-file-system-access="false">
|
||||
<nv:resource-loader default-cache-size="200" modification-check-interval="30" template-caching="true">
|
||||
<nv:spring uri="file://Template/Velocity/"/>
|
||||
<nv:spring uri="assembly://Spring.Template.Velocity.Tests/Spring.Template.Velocity.Tests.Template.Velocity/"/>
|
||||
</nv:resource-loader>
|
||||
</nv:engine>
|
||||
|
||||
<nv:engine id="cnVelocityEngineConfig" config-file="file://Template/Velocity/config.properties" override-logging="false" />
|
||||
|
||||
<nv:engine id="cnVelocityEngingCustomResourceLoader">
|
||||
<nv:resource-loader default-cache-size="200" modification-check-interval="30" template-caching="true">
|
||||
<nv:custom name="myResourceLoader"
|
||||
description="A custom resource loader"
|
||||
type="Spring.Template.Velocity.Tests.Template.Velocity.Config.TestCustomResourceLoader, Spring.Template.Velocity.Tests"
|
||||
path="Template/Velocity/"/>
|
||||
</nv:resource-loader>
|
||||
</nv:engine>
|
||||
|
||||
</nv:engine>
|
||||
|
||||
<!-- Does file system access with hot tracking with NVelocity assembly resource loader -->
|
||||
<object id="assemblyBasedVelocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity">
|
||||
<property name="VelocityProperties">
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2002-2009 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.Text;
|
||||
using NUnit.Framework;
|
||||
using NVelocity.App;
|
||||
using Spring.Context.Support;
|
||||
using Spring.Objects.Factory.Xml;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Template.Velocity.Tests.Template.Velocity {
|
||||
public class VelocityEngineTestBase {
|
||||
protected XmlApplicationContext appContext;
|
||||
protected readonly Hashtable model = new Hashtable();
|
||||
protected const string TEST_VALUE = "TEST_VALUE";
|
||||
|
||||
#region setup
|
||||
[SetUp]
|
||||
public void Setup() {
|
||||
appContext = new XmlApplicationContext(false,
|
||||
ReadOnlyXmlTestResource.GetFilePath(
|
||||
"VelocityEngineFactoryObjectTests.xml",
|
||||
typeof(VelocityEngineFactoryObjectTests)));
|
||||
model.Add("var1", TEST_VALUE);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region teardown
|
||||
[TearDown]
|
||||
public void TearDown() {
|
||||
appContext.Dispose();
|
||||
model.Clear();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region base helper methods
|
||||
/// <summary>
|
||||
/// Basic method for asserting the expected TEST_VALUE in the merged template
|
||||
/// </summary>
|
||||
protected void AssertMergedValue(VelocityEngine velocityEngine, string template){
|
||||
string mergedTemplate = VelocityEngineUtils.MergeTemplateIntoString(velocityEngine, template, Encoding.UTF8.WebName, model);
|
||||
Assert.AreEqual(string.Format("value={0}", TEST_VALUE), mergedTemplate);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
resource.loader=assembly
|
||||
assembly.resource.loader.class=NVelocity.Runtime.Resource.Loader.AssemblyResourceLoader
|
||||
assembly.resource.loader.assembly=Spring.Template.Velocity.Tests
|
||||
assembly.resource.loader.assembly=Spring.Template.Velocity.Tests
|
||||
assembly.resource.loader.description=TestDescription
|
||||
Reference in New Issue
Block a user