SPRNET-1236 - NVelocity integration

This commit is contained in:
markpollack
2009-07-28 05:04:37 +00:00
parent f46b755b99
commit a5172768e7
8 changed files with 166 additions and 104 deletions

View File

@@ -28,7 +28,7 @@
<title>Introduction</title>
<para>The Spring Framework features integration classes for templating
engine support. Currently, Spring supports the <ulink
engine support. Spring 1.3 provides support for the <ulink
url="http://www.castleproject.org/others/nvelocity/index.html">NVelocity</ulink>
templating engine.</para>
</section>
@@ -37,24 +37,34 @@
<title>Dependencies</title>
<para>The Spring NVelocity support depends on the Castle project's
NVelocity implementation which is provided in the lib directory of the
spring release.</para>
NVelocity implementation which is located in the lib directory of the
Spring release.</para>
</section>
<section xml:id="templating-nvelocity-factory">
<title>Using the NVelocity Factory Object</title>
<title>Configuring a VelocityEngine</title>
<para>The NVelocity template engine is set up using a
<literal>IFactoryObject</literal> with optional configuration parameters
to define where templates reside, define logging and more.</para>
to define where templates reside, define logging and more. For more
information on <literal>IFactoryObjects</literal> see <xref
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>
<section xml:id="templating-nvelocity-file">
<title>Simple file based template engine definition</title>
<para>A simple definition of the template engine:</para>
<para>You create a simple definition of the template engine that uses
the default resource loader as follows:</para>
<programlisting language="myxml">&lt;!-- Simple no arg file based configuration use's NVeclocity default file resource loader --&gt;
&lt;object id="velocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity" /&gt;</programlisting>
<programlisting language="myxml">&lt;objects xmlns="http://www.springframework.net" xmlns:nv="http://www.springframework.net/nvelocity"&gt;
&lt;!-- Simple no arg file based configuration use's NVeclocity default file resource loader --&gt;
&lt;nv:engine id="velocityEngine" /&gt;
&lt;/objects&gt;</programlisting>
<para>The velocity engine could then be used to load and merge a local
template using a simple relative path:</para>
@@ -65,6 +75,10 @@ modelTable.Add("var1", TEST_VALUE);
VelocityContext velocityContext = new VelocityContext(modelTable);
velocityEngine.MergeTemplate("Template/Velocity/MyTemplate.vm", Encoding.UTF8.WebName, velocityContext, stringWriter);
string mergedContent = stringWriter.ToString();</programlisting>
<para>To disable the use of NVelocity's file loader that tracks runtime
changes, set the element <literal>prefer-file-system-access</literal> of
&lt;engine/&gt; to false.</para>
</section>
<section xml:id="templating-nvelocity-assembly">
@@ -73,65 +87,51 @@ string mergedContent = stringWriter.ToString();</programlisting>
<para>When templates are packaged in an assembly, NVelocity's assembly
resource loader can be used to define where templates reside:</para>
<programlisting language="myxml">&lt;!-- Assembly based template loading with NVelocity assembly resource loader --&gt;
&lt;object id="assemblyBasedVelocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity"&gt;
&lt;property name="VelocityProperties"&gt;
&lt;dictionary key-type="string" value-type="object"&gt;
&lt;entry key="resource.loader" value="assembly"/&gt;
&lt;entry key="assembly.resource.loader.class" value="NVelocity.Runtime.Resource.Loader.AssemblyResourceLoader"/&gt;
&lt;entry key="assembly.resource.loader.assembly" value="MyAssembly"/&gt;
&lt;/dictionary&gt;
&lt;/property&gt;
&lt;/object&gt;</programlisting>
<programlisting language="myxml">&lt;nv:engine id="velocityEngine" &gt;
&lt;nv:resource-loader&gt;
&lt;nv:assembly name="MyAssembly" /&gt;
&lt;/nv:resource-loader&gt;
&lt;/nv:nvelocity&gt;</programlisting>
<para>Using the example above the template would be loaded using a
namespace syntax for the template resource:</para>
<programlisting language="csharp">velocityEngine.MergeTemplate("MyAssembly.MyNamespace.MyTemplate.vm", Encoding.UTF8.WebName, velocityContext, stringWriter);</programlisting>
<para>Using the custom namespace the same definition could be
simplified:</para>
<programlisting language="myxml">&lt;template:nvelocity id="velocityEngine" &gt;
&lt;template:resource-loader&gt;
&lt;template:assembly name="MyAssembly" /&gt;
&lt;/template:resource-loader&gt;
&lt;/template:nvelocity&gt;</programlisting>
</section>
<section xml:id="templating-nvelocity-resource-loader">
<title>Using Spring's <literal>IResourceLoader</literal> to load
templates</title>
<para>In some cases Spring's resource abstraction can be beneficial to
load templates from a variety of resources. A spring resource loader
extension to the NVelocity resource loader implementation is provided
for this use case.</para>
<para>In some cases Spring's <link linkend="resources">IResource</link>
abstraction can be beneficial to load templates from a variety of
resources. A Spring IResource loader extension to the NVelocity resource
loader implementation is provided for this use case. The following
object definition loads the NVelocity templates from a single
path</para>
<programlisting language="myxml">&lt;object id="velocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity" &gt;
&lt;property name="ResourceLoaderPath" value="file://MyTemplateFolder/AnotherFolder/" /&gt;
&lt;/object&gt;
</programlisting>
<programlisting>&lt;nv:engine id="velocityEngine"&gt;
&lt;nv:resource-loader&gt;
&lt;nv:file path="MyTemplateFolder/AnotherFolder/" /&gt;
&lt;/nv:resource-loader&gt;
&lt;/nv:engine&gt;</programlisting>
<para>Or with multiple locations</para>
<programlisting language="myxml">&lt;object id="velocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity" &gt;
&lt;property name="ResourceLoaderPaths" &gt;
&lt;list&gt;
&lt;value&gt;file://MyTemplateFolder/&lt;/value&gt;
&lt;value&gt;file://MyOtherTemplateFolder/&lt;/value&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;/object&gt;</programlisting>
<programlisting language="myxml">&lt;nv:engine id="velocityEngine"&gt;
&lt;nv:resource-loader&gt;
&lt;nv:file path="MyTemplateFolder/AnotherFolder/" /&gt;
&lt;nv:file path="MyOtherTemplateFolder/" /&gt;
&lt;/nv:resource-loader&gt;
&lt;/nv:engine&gt;
</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>preferFileSystemAccess</literal> property of the factory
object to <literal>false</literal>
(<literal>prefer-file-system-access="false"</literal> for custom
namespace use)</para>
<literal>prefer-file-system-access</literal> element of the
&lt;/engine&gt; element to <literal>false.</literal></para>
</note>
<para>Using the example above when resource loader paths are defined
@@ -146,19 +146,22 @@ string mergedContent = stringWriter.ToString();</programlisting>
<para>If so desired one could provide a custom configuration resource to
customize the NVelocity configuration:</para>
<programlisting language="myxml">&lt;object id="velocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity" &gt;
&lt;property name="ConfigLocation " value="file://Template/Velocity/config.properties" /&gt;
&lt;/object&gt;</programlisting>
<programlisting language="myxml">&lt;nv:engine id="velocityEngine" config-file="file://Template/Velocity/config.properties"/&gt;</programlisting>
<para>
<note>
<para>You can override specific properties by providing the <literal>VelocityProperties</literal> property to the NVelocity factory object (shown above)</para>
</note>
</para>
<para>You can override specific properties by providing the
<literal>VelocityProperties</literal> property to the NVelocity factory
object (shown above)</para>
<programlisting>&lt;nv:engine id="customNamespaceVelocityTemplate" config-file="foo.prop"&gt;
&lt;nv:nvelocity-properties&gt;
&lt;entry key="input.encoding" value="ISO-8859-1"/&gt;
&lt;entry key="output.encoding" value="ISO-8859-1"/&gt;
&lt;/nv:nvelocity-properties&gt;
&lt;/nv:engine&gt;</programlisting>
</section>
<section xml:id="templating-nvelocity-resource-logging">
<title>Logging</title>
@@ -166,30 +169,17 @@ string mergedContent = stringWriter.ToString();</programlisting>
<para>By default Spring will override NVelocity's default
<literal>ILogSystem</literal> implementation with its own
<literal>CommonsLoggingLogSystem</literal> implementation. If this is
not desirable, you can specify the following property of the NVelocity
factory object:</para>
<literal>CommonsLoggingLogSystem</literal> implementation so that the
logging stream of NVelocity will go to the same logging subsystem that
Spring uses. If this is not desirable, you can specify the following
property of the NVelocity factory object:</para>
<programlisting language="myxml">&lt;object id="velocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity" &gt;
&lt;property name="OverrideLogging" value="false" /&gt;
&lt;/object&gt;</programlisting>
or
<programlisting language="myxml">&lt;template:nvelocity id="velocityEngine" override-logging="false" /&gt;
</programlisting>
<note>
<para>You can override specific NVelocity properties locally by
providing a dictionary as the <literal>VelocityProperties</literal>
property of the NVelocity factory object (shown above)</para>
</note>
</section>
</section>
@@ -203,9 +193,19 @@ string mergedContent = stringWriter.ToString();</programlisting>
</section>
<section xml:id="templating-nvelocity-resource-namespace">
<title>Namespace</title>
<title>Configuring a VelocityEngine without a custom namespace</title>
<para>For convinience in defining NVelocity engine instances a custom
<para>While most users will prefer to use the NVelocity custom namespace
to configure a VelocityEngine, you can also use standard &lt;object/&gt;
definition syntax as shown below:</para>
<para>To create a VelocityEngine using the default file resource loader
use the definition:</para>
<programlisting>&lt;!-- Simple no arg file based configuration use's NVeclocity default file resource loader --&gt;
&lt;object id="velocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity" /&gt;</programlisting>
<para>For convenience in defining NVelocity engine instances a custom
namespace is provided, for example the resource loader definition could be
done this way:</para>
@@ -218,6 +218,69 @@ string mergedContent = stringWriter.ToString();</programlisting>
&lt;/template:resource-loader&gt;
&lt;/template:nvelocity&gt;
&lt;/objects&gt;</programlisting>
&lt;/objects</programlisting>
<para>When templates are packaged in an assembly, NVelocity's assembly
resource loader can be used to define where templates reside:</para>
<programlisting language="myxml">&lt;!-- Assembly based template loading with NVelocity assembly resource loader --&gt;
&lt;object id="assemblyBasedVelocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity"&gt;
&lt;property name="VelocityProperties"&gt;
&lt;dictionary key-type="string" value-type="object"&gt;
&lt;entry key="resource.loader" value="assembly"/&gt;
&lt;entry key="assembly.resource.loader.class" value="NVelocity.Runtime.Resource.Loader.AssemblyResourceLoader"/&gt;
&lt;entry key="assembly.resource.loader.assembly" value="MyAssembly"/&gt;
&lt;/dictionary&gt;
&lt;/property&gt;
&lt;/object&gt;</programlisting>
<para>To load NVelocity templates from a single path use the
definition:</para>
<programlisting language="myxml">&lt;object id="velocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity" &gt;
&lt;property name="ResourceLoaderPath" value="file://MyTemplateFolder/AnotherFolder/" /&gt;
&lt;/object&gt;
</programlisting>
<para>To load NVelocity templates from multiple paths use the
definition:</para>
<programlisting language="myxml">&lt;object id="velocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity" &gt;
&lt;property name="ResourceLoaderPaths" &gt;
&lt;list&gt;
&lt;value&gt;file://MyTemplateFolder/&lt;/value&gt;
&lt;value&gt;file://MyOtherTemplateFolder/&lt;/value&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;/object&gt;</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>preferFileSystemAccess</literal> property of the factory object
to <literal>false.</literal></para>
</note>
<para>To refer to a property file based configuration of the
TemplateEngine use the definition:</para>
<programlisting language="myxml">&lt;object id="velocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity" &gt;
&lt;property name="ConfigLocation " value="file://Template/Velocity/config.properties" /&gt;
&lt;/object&gt;</programlisting>
<para><note>
<para>You can override specific properties by providing the
<literal>VelocityProperties</literal> property.</para>
</note></para>
<para>To not integrate with the Common.Logging subsystem, set the
OverrideLogging property to false: </para>
<programlisting language="myxml">&lt;object id="velocityEngine" type="Spring.Template.Velocity.VelocityEngineFactoryObject, Spring.Template.Velocity" &gt;
&lt;property name="OverrideLogging" value="false" /&gt;
&lt;/object&gt;</programlisting>
<para></para>
</section>
</chapter>

View File

@@ -103,7 +103,7 @@ namespace Spring.Objects.Factory.Xml
wellknownNamespaceParserTypeNames["http://www.springframework.net/nms"] = "Spring.Messaging.Nms.Config.NmsNamespaceParser, Spring.Messaging.Nms";
wellknownNamespaceParserTypeNames["http://www.springframework.net/ems"] = "Spring.Messaging.Ems.Config.EmsNamespaceParser, Spring.Messaging.Ems";
wellknownNamespaceParserTypeNames["http://www.springframework.net/validation"] = "Spring.Validation.Config.ValidationNamespaceParser, Spring.Core";
wellknownNamespaceParserTypeNames["http://www.springframework.net/template"] = "Spring.Template.Config.TemplateNamespaceParser, Spring.Template.Velocity";
wellknownNamespaceParserTypeNames["http://www.springframework.net/nvelocity"] = "Spring.Template.Velocity.Config.TemplateNamespaceParser, Spring.Template.Velocity";
Reset();
}

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<ProductVersion>9.0.21022</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{BF3AB954-8375-407C-9E98-4C51D8072784}</ProjectGuid>
<OutputType>Library</OutputType>
@@ -67,7 +67,7 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Compile Include="Template\Config\TemplateNamespaceParser.cs" />
<Compile Include="Template\Velocity\Config\TemplateNamespaceParser.cs" />
<Compile Include="Template\Velocity\CommonsLoggingLogSystem.cs" />
<Compile Include="Template\Velocity\SpringResourceLoader.cs" />
<Compile Include="Template\Velocity\VelocityEngineFactory.cs" />
@@ -102,7 +102,7 @@
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Template\Config\spring-template-1.2.xsd" />
<EmbeddedResource Include="Template\Velocity\Config\spring-nvelocity-1.3.xsd" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

View File

@@ -33,16 +33,16 @@ using Spring.Util;
#endregion
namespace Spring.Template.Config {
namespace Spring.Template.Velocity.Config {
/// <summary>
/// Implementation of the custom configuration parser for template configurations
/// </summary>
/// <author>Erez Mazor</author>
[
NamespaceParser(
Namespace = "http://www.springframework.net/template",
Namespace = "http://www.springframework.net/nvelocity",
SchemaLocationAssemblyHint = typeof(TemplateNamespaceParser),
SchemaLocation = "/Spring.Template.Config/spring-template-1.2.xsd")
SchemaLocation = "/Spring.Template.Velocity.Config/spring-nvelocity-1.3.xsd")
]
public sealed class TemplateNamespaceParser : AbstractSingleObjectDefinitionParser {
private const string TemplateTypePrefix = "template: ";
@@ -167,7 +167,7 @@ namespace Spring.Template.Config {
#region Element & Attribute Name Constants
private class TemplateDefinitionConstants {
public const string NVelocityElement = "nvelocity";
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";

View File

@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns="http://www.springframework.net/template"
<xsd:schema xmlns="http://www.springframework.net/nvelocity"
xmlns:objects="http://www.springframework.net"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:vs="http://schemas.microsoft.com/Visual-Studio-Intellisense"
targetNamespace="http://www.springframework.net/template"
targetNamespace="http://www.springframework.net/nvelocity"
elementFormDefault="qualified"
attributeFormDefault="unqualified"
vs:friendlyname="Spring.NET Templating Framework Configuration"
vs:friendlyname="Spring.NET NVelocity Templating Framework Configuration"
vs:ishtmlschema="false"
vs:iscasesensitive="true"
vs:requireattributequotes="true"
@@ -113,5 +113,5 @@
</xsd:complexType>
<xsd:element name="nvelocity" type="nvelocityTemplate" />
<xsd:element name="engine" type="nvelocityTemplate" />
</xsd:schema>

View File

@@ -67,7 +67,7 @@ namespace Spring.Template.Velocity{
/// <param name="model">the Hashtable that contains model names as keys and model objects</param>
/// <returns>the result as string</returns>
/// <exception cref="VelocityException">thrown if any exception is thrown by the velocity engine</exception>
public static string MergeTemplateIntostring(
public static string MergeTemplateIntoString(
VelocityEngine velocityEngine, string templateLocation, string encoding, Hashtable model) {
StringWriter result = new StringWriter();

View File

@@ -64,7 +64,7 @@ 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);
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);
}
@@ -75,7 +75,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(
string mergedTemplate = VelocityEngineUtils.MergeTemplateIntoString(
velocityEngine, "Template/Velocity/SimpleTemplate.vm", Encoding.UTF8.WebName, model);
Assert.AreEqual(string.Format("value={0}", TEST_VALUE), mergedTemplate);
}
@@ -88,7 +88,7 @@ namespace Spring.Template.Velocity.Tests.Template.Velocity {
VelocityEngine velocityEngine =
appContext.GetObject("customNamespaceVelocityTemplate") as VelocityEngine;
Assert.IsNotNull(velocityEngine, "velocityEngine is null");
string mergedTemplate = VelocityEngineUtils.MergeTemplateIntostring(velocityEngine, "SimpleTemplate.vm",
string mergedTemplate = VelocityEngineUtils.MergeTemplateIntoString(velocityEngine, "SimpleTemplate.vm",
Encoding.UTF8.WebName, model);
Assert.AreEqual(string.Format("value={0}", "TEST_VALUE"), mergedTemplate);
}
@@ -101,7 +101,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",
string mergedTemplate = VelocityEngineUtils.MergeTemplateIntoString(velocityEngine, "SimpleTemplate.vm",
Encoding.UTF8.WebName, model);
Assert.AreEqual(string.Format("value={0}", "TEST_VALUE"), mergedTemplate);
}
@@ -114,7 +114,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,
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);
@@ -128,7 +128,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",
string mergedTemplate = VelocityEngineUtils.MergeTemplateIntoString(velocityEngine, "SimpleTemplate.vm",
Encoding.UTF8.WebName, model);
Assert.AreEqual(string.Format("value={0}", "TEST_VALUE"), mergedTemplate);
}

View File

@@ -1,13 +1,12 @@
<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net" xmlns:template="http://www.springframework.net/template">
<template:nvelocity id="customNamespaceVelocityTemplate" >
<template:resource-loader>
<template:file path="Template/Velocity/" />
</template:resource-loader>
</template:nvelocity>
<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:resource-loader>
</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">