Merge pull request #42 from thomast74/SPRNET-1543

SPRNET-1543 Reviewed GetObjectDefinionNames inconsistencies
This commit is contained in:
Marko Lahma
2013-11-23 05:29:09 -08:00
18 changed files with 333 additions and 113 deletions

View File

@@ -182,8 +182,7 @@ namespace Spring.Aop.Framework.AutoProxy
string name = objectDefinitionNames[i];
if (IsObjectNameMatch(name))
{
IConfigurableObjectDefinition definition =
factory.GetObjectDefinition(name) as IConfigurableObjectDefinition;
var definition = factory.GetObjectDefinition(name) as IConfigurableObjectDefinition;
if (definition == null || IsInfrastructureType(definition.ObjectType, name))
{

View File

@@ -1338,7 +1338,21 @@ namespace Spring.Context.Support
/// <seealso cref="Spring.Objects.Factory.IListableObjectFactory.GetObjectDefinitionNames()"/>
public IList<string> GetObjectDefinitionNames()
{
return ObjectFactory.GetObjectDefinitionNames();
return GetObjectDefinitionNames(false);
}
/// <summary>
/// Return the names of all objects defined in this factory, if <code>includeAncestors</code>is <code>true</code>
/// includes all parent factories.
/// </summary>
/// <param name="includeAncestors">to include parent factories into result</param>
/// <returns>
/// The names of all objects defined in this factory, if <code>includeAncestors</code> is <code>true</code> includes all
/// objects defined in parent factories, or an empty array if none are defined.
/// </returns>
public IList<string> GetObjectDefinitionNames(bool includeAncestors)
{
return ObjectFactory.GetObjectDefinitionNames(includeAncestors);
}
/// <summary>

View File

@@ -20,6 +20,8 @@
using System.Collections.Generic;
using Spring.Objects.Factory.Support;
namespace Spring.Objects.Factory.Config
{
/// <summary>
@@ -138,8 +140,8 @@ namespace Spring.Objects.Factory.Config
/// </remarks>
/// <value>The list of names as String array (never <code>null</code>).</value>
/// <see cref="RegisterSingleton"/>
/// <see cref="Spring.Objects.Factory.Support.IObjectDefinitionRegistry.GetObjectDefinitionNames"/>
/// <see cref="Spring.Objects.Factory.IListableObjectFactory.GetObjectDefinitionNames"/>
/// <see cref="IObjectDefinitionRegistry.GetObjectDefinitionNames()"/>
/// <see cref="IListableObjectFactory.GetObjectDefinitionNames()"/>
IList<string> SingletonNames
{
get;

View File

@@ -161,6 +161,7 @@ namespace Spring.Objects.Factory.Config
private string placeholderPrefix = DefaultPlaceholderPrefix;
private string placeholderSuffix = DefaultPlaceholderSuffix;
private EnvironmentVariableMode environmentVariableMode = EnvironmentVariableMode.Fallback;
private bool includeAncestors;
/// <summary>
/// Initializes the new instance
@@ -171,6 +172,7 @@ namespace Spring.Objects.Factory.Config
}
#region Properties
/// <summary>
/// The placeholder prefix (the default is <c>${</c>).
/// </summary>
@@ -214,45 +216,58 @@ namespace Spring.Objects.Factory.Config
set { environmentVariableMode = value; }
}
public bool IncludeAncestors
{
set { includeAncestors = value; }
}
#endregion
/// <summary>
/// Apply the given properties to the supplied
/// <see cref="Spring.Objects.Factory.Config.IConfigurableListableObjectFactory"/>.
/// </summary>
/// <param name="factory">
/// The <see cref="Spring.Objects.Factory.Config.IConfigurableListableObjectFactory"/>
/// used by the application context.
/// </param>
/// <param name="props">The properties to apply.</param>
/// <exception cref="Spring.Objects.ObjectsException">
/// If an error occured.
/// </exception>
protected override void ProcessProperties(IConfigurableListableObjectFactory factory, NameValueCollection props)
{
PlaceholderResolveHandlerAdapter resolveAdapter = new PlaceholderResolveHandlerAdapter(this, props);
ObjectDefinitionVisitor visitor = new ObjectDefinitionVisitor(resolveAdapter.ParseAndResolveVariables);
/// <summary>
/// Apply the given properties to the supplied
/// <see cref="Spring.Objects.Factory.Config.IConfigurableListableObjectFactory"/>.
/// </summary>
/// <param name="factory">
/// The <see cref="Spring.Objects.Factory.Config.IConfigurableListableObjectFactory"/>
/// used by the application context.
/// </param>
/// <param name="props">The properties to apply.</param>
/// <exception cref="Spring.Objects.ObjectsException">
/// If an error occured.
/// </exception>
protected override void ProcessProperties(IConfigurableListableObjectFactory factory, NameValueCollection props)
{
PlaceholderResolveHandlerAdapter resolveAdapter = new PlaceholderResolveHandlerAdapter(this, props);
ObjectDefinitionVisitor visitor = new ObjectDefinitionVisitor(resolveAdapter.ParseAndResolveVariables);
IList<string> objectDefinitionNames = factory.GetObjectDefinitionNames();
for (int i = 0; i < objectDefinitionNames.Count; ++i)
{
string name = objectDefinitionNames[i];
IObjectDefinition definition = factory.GetObjectDefinition(name);
try
{
visitor.VisitObjectDefinition(definition);
}
catch (ObjectDefinitionStoreException ex)
{
throw new ObjectDefinitionStoreException(
definition.ResourceDescription, name, ex.Message);
}
}
IList<string> objectDefinitionNames = factory.GetObjectDefinitionNames(includeAncestors);
for (int i = 0; i < objectDefinitionNames.Count; ++i)
{
string name = objectDefinitionNames[i];
IObjectDefinition definition = factory.GetObjectDefinition(name, includeAncestors);
factory.AddEmbeddedValueResolver(resolveAdapter);
}
if (definition == null)
{
logger.ErrorFormat("'{0}' can't be found in factorys' '{1}' object definition (includeAncestor {2})",
name, factory, includeAncestors);
continue;
}
/// <summary>
try
{
visitor.VisitObjectDefinition(definition);
}
catch (ObjectDefinitionStoreException ex)
{
throw new ObjectDefinitionStoreException(
definition.ResourceDescription, name, ex.Message);
}
}
factory.AddEmbeddedValueResolver(resolveAdapter);
}
/// <summary>
/// Parse values recursively to be able to resolve cross-references between
/// placeholder values.
/// </summary>

View File

@@ -1,19 +1,19 @@
#region License
/*
* Copyright 2002-2010 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.
/*
* Copyright 2002-2010 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
@@ -79,6 +79,7 @@ namespace Spring.Objects.Factory.Config
private int order = Int32.MaxValue; // default: same as non-Ordered
private bool includeAncestors;
private bool ignoreUnresolvablePlaceholders;
private string placeholderPrefix = DefaultPlaceholderPrefix;
private string placeholderSuffix = DefaultPlaceholderSuffix;
@@ -160,6 +161,11 @@ namespace Spring.Objects.Factory.Config
set { ignoreUnresolvablePlaceholders = value; }
}
public bool IncludeAncestors
{
set { includeAncestors = value; }
}
#endregion
#region IObjectFactoryPostProcessor Members
@@ -246,11 +252,15 @@ namespace Spring.Objects.Factory.Config
TextProcessor tp = new TextProcessor(this, compositeVariableSource);
ObjectDefinitionVisitor visitor = new ObjectDefinitionVisitor(new ObjectDefinitionVisitor.ResolveHandler(tp.ParseAndResolveVariables));
IList<string> objectDefinitionNames = factory.GetObjectDefinitionNames();
IList<string> objectDefinitionNames = factory.GetObjectDefinitionNames(includeAncestors);
for (int i = 0; i < objectDefinitionNames.Count; ++i)
{
string name = objectDefinitionNames[i];
IObjectDefinition definition = factory.GetObjectDefinition( name );
IObjectDefinition definition = factory.GetObjectDefinition( name, includeAncestors );
if (definition == null)
continue;
try
{
visitor.VisitObjectDefinition( definition );

View File

@@ -96,6 +96,17 @@ namespace Spring.Objects.Factory
/// </returns>
IList<string> GetObjectDefinitionNames();
/// <summary>
/// Return the names of all objects defined in this factory, if <code>includeAncestors</code> is <code>true</code>
/// includes all parent factories.
/// </summary>
/// <param name="includeAncestors">to include parent factories in result</param>
/// <returns>
/// The names of all objects defined in this factory, if <code>includeAncestors</code> is <code>true</code> includes all
/// objects defined in parent factories, or an empty array if none are defined.
/// </returns>
IList<string> GetObjectDefinitionNames(bool includeAncestors);
/// <summary>
/// Return the names of objects matching the given <see cref="System.Type"/>
/// (including subclasses), judging from the object definitions.
@@ -121,7 +132,6 @@ namespace Spring.Objects.Factory
/// </returns>
IList<string> GetObjectNamesForType(Type type);
/// <summary>
/// Return the names of objects matching the given <see cref="System.Type"/>
/// (including subclasses), judging from the object definitions.

View File

@@ -142,7 +142,7 @@ namespace Spring.Objects.Factory
/// If this isn't also an
/// <see cref="Spring.Objects.Factory.IHierarchicalObjectFactory"/>,
/// this method will return the same as it's own
/// <see cref="Spring.Objects.Factory.IListableObjectFactory.GetObjectDefinitionNames"/>
/// <see cref="IListableObjectFactory.GetObjectDefinitionNames()"/>
/// method.
/// </param>
/// <param name="type">
@@ -197,11 +197,8 @@ namespace Spring.Objects.Factory
/// </p>
/// </remarks>
/// <param name="factory">
/// If this isn't also an
/// <see cref="Spring.Objects.Factory.IHierarchicalObjectFactory"/>,
/// this method will return the same as it's own
/// <see cref="Spring.Objects.Factory.IListableObjectFactory.GetObjectDefinitionNames"/>
/// method.
/// If this isn't also an <see cref="Spring.Objects.Factory.IHierarchicalObjectFactory"/>,
/// this method will return the same as it's own <see cref="IListableObjectFactory.GetObjectDefinitionNames()"/> method.
/// </param>
/// <param name="type">
/// The <see cref="System.Type"/> that objects must match.
@@ -209,8 +206,7 @@ namespace Spring.Objects.Factory
/// <returns>
/// The array of object names, or an empty array if none.
/// </returns>
public static IList<string> ObjectNamesForTypeIncludingAncestors(
IListableObjectFactory factory, Type type)
public static IList<string> ObjectNamesForTypeIncludingAncestors(IListableObjectFactory factory, Type type)
{
return factory.GetObjectNamesForType(type);
}

View File

@@ -2739,8 +2739,8 @@ namespace Spring.Objects.Factory.Support
/// </para>
/// </remarks>
/// <see cref="RegisterSingleton"/>
/// <see cref="Spring.Objects.Factory.Support.IObjectDefinitionRegistry.GetObjectDefinitionNames"/>
/// <see cref="Spring.Objects.Factory.IListableObjectFactory.GetObjectDefinitionNames"/>
/// <see cref="IObjectDefinitionRegistry.GetObjectDefinitionNames()"/>
/// <see cref="IListableObjectFactory.GetObjectDefinitionNames()"/>
public IList<string> SingletonNames
{
get

View File

@@ -239,9 +239,9 @@ namespace Spring.Objects.Factory.Support
if (log.IsDebugEnabled)
{
log.Debug(string.Format(
CultureInfo.InvariantCulture,
"Found depending object '{0}' for object '{1}'.",
name, objectName));
CultureInfo.InvariantCulture,
"Found depending object '{0}' for object '{1}'.",
name, objectName));
}
#endregion
@@ -276,30 +276,20 @@ namespace Spring.Objects.Factory.Support
}
private bool IsObjectDefinitionTypeMatch(string name, Type checkedType)
{
return IsObjectDefinitionTypeMatch(name, checkedType, false);
}
private bool IsObjectDefinitionTypeMatch(string name, Type checkedType, bool includeAncestor)
{
if (checkedType == null)
{
return true;
}
RootObjectDefinition rod = GetMergedObjectDefinition(name, false);
RootObjectDefinition rod = GetMergedObjectDefinition(name, includeAncestor);
return (rod.HasObjectType && checkedType.IsAssignableFrom(rod.ObjectType));
}
/*
/// <summary>
/// Merges the object definitions.
/// </summary>
/// <param name="name">Object definition name.</param>
/// <param name="parentDefinition">The parent definition.</param>
/// <param name="childDefinition">The child definition.</param>
/// <returns>Merged object definition.</returns>
protected override RootObjectDefinition MergeObjectDefinitions(string name, IObjectDefinition parentDefinition,
IObjectDefinition childDefinition)
{
RootObjectDefinition rootDefinition = base.MergeObjectDefinitions(name, parentDefinition, childDefinition);
RegisterObjectDefinition(name, rootDefinition);
return rootDefinition;
}
*/
#endregion
#region Fields
@@ -598,6 +588,7 @@ namespace Spring.Objects.Factory.Support
#region IListableObjectFactory Members
/// <summary>
/// Return the names of all objects defined in this factory.
/// </summary>
@@ -607,14 +598,28 @@ namespace Spring.Objects.Factory.Support
/// </returns>
/// <seealso cref="Spring.Objects.Factory.IListableObjectFactory.GetObjectDefinitionNames()"/>
public IList<string> GetObjectDefinitionNames()
{
return GetObjectDefinitionNames(false);
}
/// <summary>
/// Return the names of all objects defined in this factory, if <code>includeAncestors</code> is <code>true</code>
/// includes all parent factories.
/// </summary>
/// <param name="includeAncestors">to include parent factories in result</param>
/// <returns>
/// The names of all objects defined in this factory, if <code>includeAncestors</code> is <code>true</code> includes all
/// objects defined in parent factories, or an empty array if none are defined.
/// </returns>
public IList<string> GetObjectDefinitionNames(bool includeAncestors)
{
IList<string> results = new List<string>(objectDefinitionNames);
var listableObjectFactory = ParentObjectFactory as IListableObjectFactory;
if (listableObjectFactory != null)
if (includeAncestors && listableObjectFactory != null)
{
foreach (var name in listableObjectFactory.GetObjectDefinitionNames())
foreach (var name in listableObjectFactory.GetObjectDefinitionNames(includeAncestors))
{
if (!results.Contains(name))
{
@@ -640,16 +645,21 @@ namespace Spring.Objects.Factory.Support
/// </returns>
/// <seealso cref="Spring.Objects.Factory.IListableObjectFactory.GetObjectDefinitionNames()"/>
public IList<string> GetObjectDefinitionNames(Type type)
{
return GetObjectDefinitionNames(type, false);
}
public IList<string> GetObjectDefinitionNames(Type type, bool includeAncestor)
{
List<string> matches = new List<string>();
foreach (string name in objectDefinitionNames)
foreach (string name in GetObjectDefinitionNames(includeAncestor))
{
if (IsObjectDefinitionTypeMatch(name, type))
if (IsObjectDefinitionTypeMatch(name, type, includeAncestor))
{
matches.Add(name);
}
}
return matches;
return matches;
}
/// <summary>
@@ -1013,7 +1023,7 @@ namespace Spring.Objects.Factory.Support
protected List<string> DoGetObjectNamesForType(Type type, bool includeNonSingletons, bool allowEagerInit)
{
List<string> result = new List<string>();
IList<string> objectNames = GetObjectDefinitionNames();
IList<string> objectNames = GetObjectDefinitionNames(true);
foreach (string s in objectNames)
{
string objectName = s;

View File

@@ -71,8 +71,20 @@ namespace Spring.Objects.Factory.Support
/// The names of all objects defined in this registry, or an empty array
/// if none defined
/// </returns>
IList<string> GetObjectDefinitionNames ();
IList<string> GetObjectDefinitionNames();
/// <summary>
/// Return the names of all objects defined in this registry.
/// If <code>includeAncestors</code> is <code>true</code> it includes all objects in the defined parent factories.
/// </summary>
/// <param name="includeAncestors">to include parent factories in result</param>
/// <returns>
/// The names of all objects defined in this registry, if <code>includeAncestors</code> is <code>true</code> it includes
/// all objects in the defined parent factories, or an empty array if none defined
/// </returns>
IList<string> GetObjectDefinitionNames(bool includeAncestors);
/// <summary>
/// Check if this registry contains a object definition with the given name.
/// </summary>

View File

@@ -557,6 +557,20 @@ namespace Spring.Objects.Factory.Support
return names;
}
/// <summary>
/// Return the names of all objects defined in this factory, if <code>includeAncestors</code> is <code>true</code>
/// includes all parent factories.
/// </summary>
/// <param name="includeAncestors">to include parent factories in result</param>
/// <returns>
/// The names of all objects defined in this factory, if <code>includeAncestors</code> is <code>true</code> includes all
/// objects defined in parent factories, or an empty array if none are defined.
/// </returns>
public IList<string> GetObjectDefinitionNames(bool includeAncestors)
{
throw new NotSupportedException("StaticListableObjectFactory does not contain object definitions.");
}
/// <summary>
/// Return the names of objects matching the given <see cref="System.Type"/>
/// (including subclasses), judging from the object definitions.

View File

@@ -114,6 +114,11 @@ namespace Spring.Context.Support
return null;
}
public IList<string> GetObjectDefinitionNames(bool includeAncestors)
{
return null;
}
public string[] GetObjectDefinitionNames(Type type)
{
return null;

View File

@@ -63,7 +63,7 @@ namespace Spring.Objects.Factory {
protected internal void AssertCount (int count)
{
IList<string> defnames = ListableObjectFactory.GetObjectDefinitionNames();
IList<string> defnames = ListableObjectFactory.GetObjectDefinitionNames(true);
Assert.IsTrue (
defnames.Count == count,
string.Format ("We should have {0} objects, not {1}.", count, defnames.Count));
@@ -78,7 +78,7 @@ namespace Spring.Objects.Factory {
public virtual void AssertTestObjectCount (int count)
{
IList<string> defnames =
ListableObjectFactory.GetObjectNamesForType (typeof (TestObject));
ListableObjectFactory.GetObjectNamesForType(typeof (TestObject));
Assert.IsTrue (
defnames.Count == count,
string.Format ("We should have {0} objects for class {1}, not {2}.", count, typeof (TestObject).FullName, defnames.Count));

View File

@@ -104,7 +104,7 @@ namespace Spring.Objects.Factory.Config
cfg.Location = mockResource;
cfg.ConfigSections = new string[] { "" };
IConfigurableListableObjectFactory mockFactory = (IConfigurableListableObjectFactory)mocks.DynamicMock(typeof(IConfigurableListableObjectFactory));
Expect.Call(mockFactory.GetObjectDefinitionNames()).Return(new string[] {});
Expect.Call(mockFactory.GetObjectDefinitionNames(false)).Return(new string[] {});
mocks.ReplayAll();
cfg.PostProcessObjectFactory(mockFactory);
@@ -148,8 +148,8 @@ namespace Spring.Objects.Factory.Config
RootObjectDefinition def = new RootObjectDefinition(typeof(TestObject), pvs);
IConfigurableListableObjectFactory mock = (IConfigurableListableObjectFactory) mocks.CreateMock(typeof(IConfigurableListableObjectFactory));
Expect.Call(mock.GetObjectDefinitionNames()).Return(new string [] {defName});
Expect.Call(mock.GetObjectDefinition(defName)).Return(def);
Expect.Call(mock.GetObjectDefinitionNames(false)).Return(new string [] {defName});
Expect.Call(mock.GetObjectDefinition(defName, false)).Return(def);
Expect.Call(delegate { mock.AddEmbeddedValueResolver(null); }).IgnoreArguments();
mocks.ReplayAll();
@@ -165,6 +165,38 @@ namespace Spring.Objects.Factory.Config
mocks.VerifyAll();
}
[Test]
public void IncludingAncestors()
{
const string defName = "foo";
const string placeholder = "${name}";
MutablePropertyValues pvs = new MutablePropertyValues();
const string theProperty = "name";
pvs.Add(theProperty, placeholder);
RootObjectDefinition def = new RootObjectDefinition(typeof(TestObject), pvs);
IConfigurableListableObjectFactory mock = (IConfigurableListableObjectFactory)mocks.CreateMock(typeof(IConfigurableListableObjectFactory));
Expect.Call(mock.GetObjectDefinitionNames(true)).Return(new string[] { defName });
Expect.Call(mock.GetObjectDefinition(defName, true)).Return(def);
Expect.Call(delegate { mock.AddEmbeddedValueResolver(null); }).IgnoreArguments();
mocks.ReplayAll();
PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer();
cfg.IncludeAncestors = true;
NameValueCollection defaultProperties = new NameValueCollection();
const string expectedName = "Rick Evans";
defaultProperties.Add(theProperty, expectedName);
cfg.Properties = defaultProperties;
cfg.PostProcessObjectFactory(mock);
Assert.AreEqual(expectedName, def.PropertyValues.GetPropertyValue(theProperty).Value,
"Property placeholder value was not replaced with the resolved value.");
mocks.VerifyAll();
}
/// <summary>
/// Fallback is the default mode. Check if the PROCESSOR_ARCHITECTURE
/// variable is replaced.
@@ -390,8 +422,8 @@ namespace Spring.Objects.Factory.Config
properties.Add("foo", expectedName);
IConfigurableListableObjectFactory mock = (IConfigurableListableObjectFactory) mocks.CreateMock(typeof (IConfigurableListableObjectFactory));
Expect.Call(mock.GetObjectDefinitionNames()).Return(new string[] {"foo"});
Expect.Call(mock.GetObjectDefinition(null)).IgnoreArguments().Return(def);
Expect.Call(mock.GetObjectDefinitionNames(false)).Return(new string[] {"foo"});
Expect.Call(mock.GetObjectDefinition(null, false)).IgnoreArguments().Return(def);
mocks.ReplayAll();
PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer();
@@ -421,8 +453,8 @@ namespace Spring.Objects.Factory.Config
properties.Add("hope.floats", expectedName);
IConfigurableListableObjectFactory mock = (IConfigurableListableObjectFactory) mocks.CreateMock(typeof (IConfigurableListableObjectFactory));
Expect.Call(mock.GetObjectDefinitionNames()).Return(new string[] {"foo"});
Expect.Call(mock.GetObjectDefinition(null)).IgnoreArguments().Return(def);
Expect.Call(mock.GetObjectDefinitionNames(false)).Return(new string[] {"foo"});
Expect.Call(mock.GetObjectDefinition(null, false)).IgnoreArguments().Return(def);
Expect.Call(delegate { mock.AddEmbeddedValueResolver(null); }).IgnoreArguments();
mocks.ReplayAll();
@@ -451,8 +483,8 @@ namespace Spring.Objects.Factory.Config
properties.Add("hope.floats", expectedName);
IConfigurableListableObjectFactory mock = (IConfigurableListableObjectFactory) mocks.CreateMock(typeof (IConfigurableListableObjectFactory));
Expect.Call(mock.GetObjectDefinitionNames()).Return(new string[] {"foo"});
Expect.Call(mock.GetObjectDefinition(null)).IgnoreArguments().Return(def);
Expect.Call(mock.GetObjectDefinitionNames(false)).Return(new string[] {"foo"});
Expect.Call(mock.GetObjectDefinition(null, false)).IgnoreArguments().Return(def);
Expect.Call(delegate { mock.AddEmbeddedValueResolver(null); }).IgnoreArguments();
mocks.ReplayAll();
@@ -549,8 +581,8 @@ namespace Spring.Objects.Factory.Config
RootObjectDefinition def = new RootObjectDefinition(typeof(TestObject), pvs);
IConfigurableListableObjectFactory mock = (IConfigurableListableObjectFactory) mocks.CreateMock(typeof(IConfigurableListableObjectFactory));
Expect.Call(mock.GetObjectDefinitionNames()).Return(new string [] {defName});
Expect.Call(mock.GetObjectDefinition(defName)).Return(def);
Expect.Call(mock.GetObjectDefinitionNames(false)).Return(new string [] {defName});
Expect.Call(mock.GetObjectDefinition(defName, false)).Return(def);
Expect.Call(delegate { mock.AddEmbeddedValueResolver(null); }).IgnoreArguments();
mocks.ReplayAll();

View File

@@ -20,7 +20,12 @@
using System;
using System.Collections;
using System.Collections.Specialized;
using NUnit.Framework;
using Rhino.Mocks;
using Spring.Context.Support;
using Spring.Objects.Factory.Support;
@@ -33,6 +38,13 @@ namespace Spring.Objects.Factory.Config
[TestFixture]
public class VariablePlaceholderConfigurerTests
{
private MockRepository mocks;
[SetUp]
public void SetUp()
{
mocks = new MockRepository();
}
[Test]
public void ThrowsOnMissingVariableSources()
@@ -276,5 +288,32 @@ namespace Spring.Objects.Factory.Config
Assert.AreEqual("Erich", tb1.Name);
Assert.AreEqual("${nickname}", tb1.Nickname);
}
[Test]
public void InlcludeAncestors()
{
const string defName = "foo";
const string placeholder = "${name}";
MutablePropertyValues pvs = new MutablePropertyValues();
const string theProperty = "name";
pvs.Add(theProperty, placeholder);
RootObjectDefinition def = new RootObjectDefinition(typeof(TestObject), pvs);
IConfigurableListableObjectFactory mock = (IConfigurableListableObjectFactory)mocks.CreateMock(typeof(IConfigurableListableObjectFactory));
Expect.Call(mock.GetObjectDefinitionNames(true)).Return(new string[] { defName });
Expect.Call(mock.GetObjectDefinition(defName, true)).Return(def);
mocks.ReplayAll();
VariablePlaceholderConfigurer vpc = new VariablePlaceholderConfigurer();
vpc.IgnoreUnresolvablePlaceholders = true;
vpc.VariableSource = new DictionaryVariableSource(new string[] { "name", "Erich" });
vpc.IncludeAncestors = true;
vpc.PostProcessObjectFactory(mock);
mocks.VerifyAll();
}
}
}

View File

@@ -1773,6 +1773,66 @@ namespace Spring.Objects.Factory
#endregion
[Test]
public void GetObjectDefinitionNamesOnlyFromChild()
{
DefaultListableObjectFactory parent = new DefaultListableObjectFactory();
parent.RegisterObjectDefinition("testChild", new RootObjectDefinition(typeof(TestObject), null));
DefaultListableObjectFactory child = new DefaultListableObjectFactory(parent);
child.RegisterObjectDefinition("testParent", new RootObjectDefinition(typeof(NestedTestObject), null));
var names = child.GetObjectDefinitionNames();
Assert.That(names, Has.Count.EqualTo(1), "GetObjectDefinitionNames() should only return object definition names from this factory");
names = child.GetObjectDefinitionNames(false);
Assert.That(names, Has.Count.EqualTo(1), "GetObjectDefinitionNames(false) should only return object definition names from this factory");
}
[Test]
public void GetObjectDefinitionNamesIncludingParent()
{
DefaultListableObjectFactory parent = new DefaultListableObjectFactory();
parent.RegisterObjectDefinition("testChild", new RootObjectDefinition(typeof(TestObject), null));
DefaultListableObjectFactory child = new DefaultListableObjectFactory(parent);
child.RegisterObjectDefinition("testParent", new RootObjectDefinition(typeof(NestedTestObject), null));
var names = child.GetObjectDefinitionNames(true);
Assert.That(names, Has.Count.EqualTo(2), "GetObjectDefinitionNames(true) should return object definition names from this factory and parents");
}
[Test]
public void GetObjectDefinitionNamesByTypeExcludingParent()
{
DefaultListableObjectFactory parent = new DefaultListableObjectFactory();
parent.RegisterObjectDefinition("testChild", new RootObjectDefinition(typeof(TestObject), null));
DefaultListableObjectFactory child = new DefaultListableObjectFactory(parent);
child.RegisterObjectDefinition("testParent", new RootObjectDefinition(typeof(NestedTestObject), null));
var names1 = child.GetObjectDefinitionNames(typeof(NestedTestObject));
var names2 = child.GetObjectDefinitionNames(typeof(TestObject));
Assert.That(names1, Has.Count.EqualTo(1), "Should return only child object definitions");
Assert.That(names2, Has.Count.EqualTo(0), "Should not return the parent object definitions");
}
[Test]
public void GetObjectDefinitionNamesByTypeIncludingParent()
{
DefaultListableObjectFactory parent = new DefaultListableObjectFactory();
parent.RegisterObjectDefinition("testChild", new RootObjectDefinition(typeof(TestObject), null));
DefaultListableObjectFactory child = new DefaultListableObjectFactory(parent);
child.RegisterObjectDefinition("testParent", new RootObjectDefinition(typeof(NestedTestObject), null));
var names1 = child.GetObjectDefinitionNames(typeof(NestedTestObject), true);
var names2 = child.GetObjectDefinitionNames(typeof(TestObject), true);
Assert.That(names1, Has.Count.EqualTo(1), "Should return child object definitions");
Assert.That(names2, Has.Count.EqualTo(1), "Should return the parent object definitions");
}
[Test]
public void GetObjectNamesForTypeFindsFactoryObjects()
{

View File

@@ -46,12 +46,9 @@ namespace Spring.Objects.Factory
[SetUp]
public void SetUp()
{
IObjectFactory grandparent
= new XmlObjectFactory(new ReadOnlyXmlTestResource("root.xml", GetType()));
IObjectFactory parent
= new XmlObjectFactory(new ReadOnlyXmlTestResource("middle.xml", GetType()), grandparent);
IConfigurableListableObjectFactory child
= new XmlObjectFactory(new ReadOnlyXmlTestResource("leaf.xml", GetType()), parent);
IObjectFactory grandparent = new XmlObjectFactory(new ReadOnlyXmlTestResource("root.xml", GetType()));
IObjectFactory parent = new XmlObjectFactory(new ReadOnlyXmlTestResource("middle.xml", GetType()), grandparent);
IConfigurableListableObjectFactory child = new XmlObjectFactory(new ReadOnlyXmlTestResource("leaf.xml", GetType()), parent);
_factory = child;
}

View File

@@ -97,6 +97,11 @@ namespace Spring.Validation
return new List<string>(this.objects.Keys);
}
public IList<string> GetObjectDefinitionNames(bool includeAncestor)
{
return new List<string>(this.objects.Keys);
}
public IList<IObjectDefinition> GetObjectDefinitions()
{
return new List<IObjectDefinition>(this.objects.Values);