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:
erezmazor
2009-08-01 12:00:30 +00:00
parent 05cfcbc832
commit 546003e095
13 changed files with 938 additions and 206 deletions

View File

@@ -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\" />

View File

@@ -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
}

View File

@@ -0,0 +1 @@
value=${var1}

View File

@@ -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>

View File

@@ -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">

View File

@@ -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
}
}

View File

@@ -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