resolved SPRNET-1035
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
#region License
|
||||
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright 2002-2007 the original author or authors.
|
||||
*
|
||||
@@ -14,302 +14,338 @@
|
||||
* 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
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Globalization;
|
||||
using Common.Logging;
|
||||
using Spring.Collections;
|
||||
using Spring.Core;
|
||||
|
||||
namespace Spring.Objects.Factory.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// Resolves placeholder values in one or more object definitions
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The placeholder syntax follows the NAnt style: <c>${...}</c>.
|
||||
/// Placeholders values are resolved against a list of
|
||||
/// <see cref="IVariableSource"/>s. In case of multiple definitions
|
||||
/// for the same property placeholder name, the first one in the
|
||||
/// list is used.
|
||||
/// <para>Variable substitution is performed on simple property values,
|
||||
/// lists, dictionaries, sets, constructor
|
||||
/// values, object type name, and object names in
|
||||
/// runtime object references (
|
||||
/// <see cref="Spring.Objects.Factory.Config.RuntimeObjectReference"/>).</para>
|
||||
/// <para>Furthermore, placeholder values can also cross-reference other
|
||||
/// placeholders, in the manner of the following example where the
|
||||
/// <c>rootPath</c> property is cross-referenced by the <c>subPath</c>
|
||||
/// property.
|
||||
/// </para>
|
||||
/// <example>
|
||||
/// <code escaped="true">
|
||||
/// <name-values>
|
||||
/// <add key="rootPath" value="myrootdir"/>
|
||||
/// <add key="subPath" value="${rootPath}/subdir"/>
|
||||
/// </name-values>
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// <para>If a configurer cannot resolve a placeholder, and the value of the
|
||||
/// <see cref="Spring.Objects.Factory.Config.PropertyPlaceholderConfigurer.IgnoreUnresolvablePlaceholders"/>
|
||||
/// property is currently set to <see langword="false"/>, an
|
||||
/// <see cref="Spring.Objects.Factory.ObjectDefinitionStoreException"/>
|
||||
/// will be thrown. </para>
|
||||
/// </remarks>
|
||||
/// <author>Mark Pollack</author>
|
||||
public class VariablePlaceholderConfigurer : IObjectFactoryPostProcessor, IOrdered
|
||||
{
|
||||
#region Fields
|
||||
private int order = Int32.MaxValue; // default: same as non-Ordered
|
||||
|
||||
private bool ignoreUnresolvablePlaceholders;
|
||||
|
||||
private IList variableSourceList;
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Sets the list of <see cref="IVariableSource"/>s that will be used to resolve placeholder names.
|
||||
/// </summary>
|
||||
/// <value>A list of <see cref="IVariableSource"/>s.</value>
|
||||
public IList VariableSources
|
||||
{
|
||||
set { variableSourceList = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets <see cref="IVariableSource"/> that will be used to resolve placeholder names.
|
||||
/// </summary>
|
||||
/// <value>A <see cref="IVariableSource"/> instance.</value>
|
||||
public IVariableSource VariableSource
|
||||
{
|
||||
set
|
||||
{
|
||||
variableSourceList = new ArrayList();
|
||||
variableSourceList.Add(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether unresolved placeholders should be ignored.
|
||||
/// </summary>
|
||||
public bool IgnoreUnresolvablePlaceholders
|
||||
{
|
||||
set { ignoreUnresolvablePlaceholders = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IObjectFactoryPostProcessor Members
|
||||
|
||||
/// <summary>
|
||||
/// Modify the application context's internal object factory after its
|
||||
/// standard initialization.
|
||||
/// </summary>
|
||||
/// <param name="factory">The object factory used by the application context.</param>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// All object definitions will have been loaded, but no objects will have
|
||||
/// been instantiated yet. This allows for overriding or adding properties
|
||||
/// even to eager-initializing objects.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <exception cref="Spring.Objects.ObjectsException">
|
||||
/// In case of errors.
|
||||
/// </exception>
|
||||
public void PostProcessObjectFactory(IConfigurableListableObjectFactory factory)
|
||||
{
|
||||
try
|
||||
{
|
||||
ProcessProperties(factory);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (typeof (ObjectsException).IsInstanceOfType(ex))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ObjectsException(
|
||||
"Errored while postprocessing an object factory.", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IOrdered Members
|
||||
|
||||
/// <summary>
|
||||
/// Return the order value of this object, where a higher value means greater in
|
||||
/// terms of sorting.
|
||||
/// </summary>
|
||||
/// <returns>The order value.</returns>
|
||||
/// <seealso cref="Spring.Core.IOrdered.Order"/>
|
||||
public int Order
|
||||
{
|
||||
get { return order; }
|
||||
set { order = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Apply the property replacement using the specified <see cref="IVariableSource"/>s for all
|
||||
/// object in 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>
|
||||
/// <exception cref="Spring.Objects.ObjectsException">
|
||||
/// If an error occured.
|
||||
/// </exception>
|
||||
protected virtual void ProcessProperties(IConfigurableListableObjectFactory factory)
|
||||
{
|
||||
IVariableSource compositeVariableSource =
|
||||
new PlaceholderResolvingCompositeVariableSource(variableSourceList, ignoreUnresolvablePlaceholders);
|
||||
ObjectDefinitionVisitor visitor = new ObjectDefinitionVisitor(compositeVariableSource);
|
||||
|
||||
string[] objectDefinitionNames = factory.GetObjectDefinitionNames();
|
||||
for (int i = 0; i < objectDefinitionNames.Length; ++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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Helper class
|
||||
internal class PlaceholderResolvingCompositeVariableSource : IVariableSource
|
||||
{
|
||||
private string placeholderPrefix = "${";
|
||||
private string placeholderSuffix = "}";
|
||||
private bool ignoreUnresolvablePlaceholders;
|
||||
|
||||
private ILog logger = LogManager.GetLogger(typeof (PlaceholderResolvingCompositeVariableSource));
|
||||
|
||||
private IList variableSourceList;
|
||||
|
||||
public PlaceholderResolvingCompositeVariableSource(IList variableSourceList, bool ignoreUnresolvablePlaceholders)
|
||||
{
|
||||
this.variableSourceList = variableSourceList;
|
||||
this.ignoreUnresolvablePlaceholders = ignoreUnresolvablePlaceholders;
|
||||
}
|
||||
|
||||
#region IVariableSource Members
|
||||
|
||||
public string ResolveVariable(string rawStringValue)
|
||||
{
|
||||
return ParseAndResolveVariable(rawStringValue, new HashedSet());
|
||||
}
|
||||
|
||||
|
||||
//TODO handle resolved values at are not string - identify this case as only 1 placeholder present?
|
||||
|
||||
private string ParseAndResolveVariable(string strVal, ISet visitedPlaceholders)
|
||||
{
|
||||
int startIndex = strVal.IndexOf(placeholderPrefix);
|
||||
while (startIndex != -1)
|
||||
{
|
||||
int endIndex = strVal.IndexOf(
|
||||
placeholderSuffix, startIndex + placeholderPrefix.Length);
|
||||
if (endIndex != -1)
|
||||
{
|
||||
int pos = startIndex + placeholderPrefix.Length;
|
||||
string placeholder = strVal.Substring(pos, endIndex - pos);
|
||||
if (visitedPlaceholders.Contains(placeholder))
|
||||
{
|
||||
throw new ObjectDefinitionStoreException(
|
||||
string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"Circular placeholder reference '{0}' detected. ",
|
||||
placeholder));
|
||||
}
|
||||
visitedPlaceholders.Add(placeholder);
|
||||
string resolvedValue = ResolvePlaceholderVariable(placeholder);
|
||||
if (resolvedValue != null)
|
||||
{
|
||||
resolvedValue = ParseAndResolveVariable(resolvedValue, visitedPlaceholders);
|
||||
|
||||
#region Instrumentation
|
||||
|
||||
if (logger.IsDebugEnabled)
|
||||
{
|
||||
logger.Debug(string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"Resolving placeholder '{0}' to '{1}'.", placeholder, resolvedValue));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
strVal = strVal.Substring(0, startIndex) + resolvedValue + strVal.Substring(endIndex + 1);
|
||||
startIndex = strVal.IndexOf(placeholderPrefix, startIndex + resolvedValue.Length);
|
||||
}
|
||||
else if (ignoreUnresolvablePlaceholders)
|
||||
{
|
||||
// simply return the unprocessed value...
|
||||
return strVal;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ObjectDefinitionStoreException(string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"Could not resolve placeholder '{0}'.", placeholder));
|
||||
}
|
||||
visitedPlaceholders.Remove(placeholder);
|
||||
}
|
||||
else
|
||||
{
|
||||
startIndex = -1;
|
||||
}
|
||||
}
|
||||
return strVal;
|
||||
}
|
||||
|
||||
private string ResolvePlaceholderVariable(string variableName)
|
||||
{
|
||||
foreach (IVariableSource variableSource in variableSourceList)
|
||||
{
|
||||
//TODO handle resolved values at are not strings?
|
||||
|
||||
object resolvedValue = variableSource.ResolveVariable(variableName);
|
||||
if (resolvedValue is string)
|
||||
{
|
||||
}
|
||||
if (resolvedValue != null)
|
||||
{
|
||||
if (resolvedValue is string)
|
||||
{
|
||||
return resolvedValue as string;
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Warn("Placeholder " + variableSource + " resolved to object type [" + resolvedValue.GetType() + "]. Only string type currently supported");
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Globalization;
|
||||
using Common.Logging;
|
||||
using Spring.Collections;
|
||||
using Spring.Core;
|
||||
|
||||
namespace Spring.Objects.Factory.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// Resolves placeholder values in one or more object definitions
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The placeholder syntax follows the NAnt style: <c>${...}</c>.
|
||||
/// Placeholders values are resolved against a list of
|
||||
/// <see cref="IVariableSource"/>s. In case of multiple definitions
|
||||
/// for the same property placeholder name, the first one in the
|
||||
/// list is used.
|
||||
/// <para>Variable substitution is performed on simple property values,
|
||||
/// lists, dictionaries, sets, constructor
|
||||
/// values, object type name, and object names in
|
||||
/// runtime object references (
|
||||
/// <see cref="Spring.Objects.Factory.Config.RuntimeObjectReference"/>).</para>
|
||||
/// <para>Furthermore, placeholder values can also cross-reference other
|
||||
/// placeholders, in the manner of the following example where the
|
||||
/// <c>rootPath</c> property is cross-referenced by the <c>subPath</c>
|
||||
/// property.
|
||||
/// </para>
|
||||
/// <example>
|
||||
/// <code escaped="true">
|
||||
/// <name-values>
|
||||
/// <add key="rootPath" value="myrootdir"/>
|
||||
/// <add key="subPath" value="${rootPath}/subdir"/>
|
||||
/// </name-values>
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// <para>If a configurer cannot resolve a placeholder, and the value of the
|
||||
/// <see cref="Spring.Objects.Factory.Config.PropertyPlaceholderConfigurer.IgnoreUnresolvablePlaceholders"/>
|
||||
/// property is currently set to <see langword="false"/>, an
|
||||
/// <see cref="Spring.Objects.Factory.ObjectDefinitionStoreException"/>
|
||||
/// will be thrown. </para>
|
||||
/// </remarks>
|
||||
/// <author>Mark Pollack</author>
|
||||
public class VariablePlaceholderConfigurer : IObjectFactoryPostProcessor, IOrdered
|
||||
{
|
||||
/// <summary>
|
||||
/// The default placeholder prefix.
|
||||
/// </summary>
|
||||
public const string DefaultPlaceholderPrefix = "${";
|
||||
|
||||
/// <summary>
|
||||
/// The default placeholder suffix.
|
||||
/// </summary>
|
||||
public const string DefaultPlaceholderSuffix = "}";
|
||||
|
||||
#region Fields
|
||||
|
||||
private int order = Int32.MaxValue; // default: same as non-Ordered
|
||||
|
||||
private bool ignoreUnresolvablePlaceholders;
|
||||
private string placeholderPrefix = DefaultPlaceholderPrefix;
|
||||
private string placeholderSuffix = DefaultPlaceholderSuffix;
|
||||
|
||||
private IList variableSourceList;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
/// <summary>
|
||||
/// Sets the list of <see cref="IVariableSource"/>s that will be used to resolve placeholder names.
|
||||
/// </summary>
|
||||
/// <value>A list of <see cref="IVariableSource"/>s.</value>
|
||||
public IList VariableSources
|
||||
{
|
||||
set { variableSourceList = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets <see cref="IVariableSource"/> that will be used to resolve placeholder names.
|
||||
/// </summary>
|
||||
/// <value>A <see cref="IVariableSource"/> instance.</value>
|
||||
public IVariableSource VariableSource
|
||||
{
|
||||
set
|
||||
{
|
||||
variableSourceList = new ArrayList();
|
||||
variableSourceList.Add( value );
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The placeholder prefix (the default is <c>${</c>).
|
||||
/// </summary>
|
||||
/// <seealso cref="DefaultPlaceholderPrefix"/>
|
||||
public string PlaceholderPrefix
|
||||
{
|
||||
set { placeholderPrefix = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The placeholder suffix (the default is <c>}</c>)
|
||||
/// </summary>
|
||||
/// <seealso cref="DefaultPlaceholderSuffix"/>
|
||||
public string PlaceholderSuffix
|
||||
{
|
||||
set { placeholderSuffix = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether unresolved placeholders should be ignored.
|
||||
/// </summary>
|
||||
public bool IgnoreUnresolvablePlaceholders
|
||||
{
|
||||
set { ignoreUnresolvablePlaceholders = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IObjectFactoryPostProcessor Members
|
||||
|
||||
/// <summary>
|
||||
/// Modify the application context's internal object factory after its
|
||||
/// standard initialization.
|
||||
/// </summary>
|
||||
/// <param name="factory">The object factory used by the application context.</param>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// All object definitions will have been loaded, but no objects will have
|
||||
/// been instantiated yet. This allows for overriding or adding properties
|
||||
/// even to eager-initializing objects.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <exception cref="Spring.Objects.ObjectsException">
|
||||
/// In case of errors.
|
||||
/// </exception>
|
||||
public void PostProcessObjectFactory( IConfigurableListableObjectFactory factory )
|
||||
{
|
||||
try
|
||||
{
|
||||
ProcessProperties( factory );
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (typeof( ObjectsException ).IsInstanceOfType( ex ))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ObjectsException(
|
||||
"Errored while postprocessing an object factory.", ex );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IOrdered Members
|
||||
|
||||
/// <summary>
|
||||
/// Return the order value of this object, where a higher value means greater in
|
||||
/// terms of sorting.
|
||||
/// </summary>
|
||||
/// <returns>The order value.</returns>
|
||||
/// <seealso cref="Spring.Core.IOrdered.Order"/>
|
||||
public int Order
|
||||
{
|
||||
get { return order; }
|
||||
set { order = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Apply the property replacement using the specified <see cref="IVariableSource"/>s for all
|
||||
/// object in 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>
|
||||
/// <exception cref="Spring.Objects.ObjectsException">
|
||||
/// If an error occured.
|
||||
/// </exception>
|
||||
protected virtual void ProcessProperties( IConfigurableListableObjectFactory factory )
|
||||
{
|
||||
IVariableSource compositeVariableSource = new PlaceholderResolvingCompositeVariableSource( placeholderPrefix
|
||||
, placeholderSuffix
|
||||
, variableSourceList
|
||||
, ignoreUnresolvablePlaceholders );
|
||||
ObjectDefinitionVisitor visitor = new ObjectDefinitionVisitor( compositeVariableSource );
|
||||
|
||||
string[] objectDefinitionNames = factory.GetObjectDefinitionNames();
|
||||
for (int i = 0; i < objectDefinitionNames.Length; ++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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Helper class
|
||||
|
||||
private class PlaceholderResolvingCompositeVariableSource : IVariableSource
|
||||
{
|
||||
private readonly ILog logger = LogManager.GetLogger( typeof( PlaceholderResolvingCompositeVariableSource ) );
|
||||
|
||||
private readonly string placeholderPrefix;
|
||||
private readonly string placeholderSuffix;
|
||||
private readonly bool ignoreUnresolvablePlaceholders;
|
||||
private readonly IList variableSourceList;
|
||||
|
||||
public PlaceholderResolvingCompositeVariableSource( string placeholderPrefix, string placeholderSuffix, IList variableSourceList, bool ignoreUnresolvablePlaceholders )
|
||||
{
|
||||
this.placeholderPrefix = placeholderPrefix;
|
||||
this.placeholderSuffix = placeholderSuffix;
|
||||
this.variableSourceList = variableSourceList;
|
||||
this.ignoreUnresolvablePlaceholders = ignoreUnresolvablePlaceholders;
|
||||
}
|
||||
|
||||
#region IVariableSource Members
|
||||
|
||||
public string ResolveVariable( string rawStringValue )
|
||||
{
|
||||
return ParseAndResolveVariable( rawStringValue, new HashedSet() );
|
||||
}
|
||||
|
||||
|
||||
//TODO handle resolved values at are not string - identify this case as only 1 placeholder present?
|
||||
|
||||
private string ParseAndResolveVariable( string strVal, ISet visitedPlaceholders )
|
||||
{
|
||||
int startIndex = strVal.IndexOf( placeholderPrefix );
|
||||
while (startIndex != -1)
|
||||
{
|
||||
int endIndex = strVal.IndexOf(
|
||||
placeholderSuffix, startIndex + placeholderPrefix.Length );
|
||||
if (endIndex != -1)
|
||||
{
|
||||
int pos = startIndex + placeholderPrefix.Length;
|
||||
string placeholder = strVal.Substring( pos, endIndex - pos );
|
||||
if (visitedPlaceholders.Contains( placeholder ))
|
||||
{
|
||||
throw new ObjectDefinitionStoreException(
|
||||
string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"Circular placeholder reference '{0}' detected. ",
|
||||
placeholder ) );
|
||||
}
|
||||
visitedPlaceholders.Add( placeholder );
|
||||
string resolvedValue = ResolvePlaceholderVariable( placeholder );
|
||||
if (resolvedValue != null)
|
||||
{
|
||||
resolvedValue = ParseAndResolveVariable( resolvedValue, visitedPlaceholders );
|
||||
|
||||
#region Instrumentation
|
||||
|
||||
if (logger.IsDebugEnabled)
|
||||
{
|
||||
logger.Debug( string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"Resolving placeholder '{0}' to '{1}'.", placeholder, resolvedValue ) );
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
strVal = strVal.Substring( 0, startIndex ) + resolvedValue + strVal.Substring( endIndex + placeholderSuffix.Length );
|
||||
startIndex = strVal.IndexOf( placeholderPrefix, startIndex + resolvedValue.Length);
|
||||
}
|
||||
else if (ignoreUnresolvablePlaceholders)
|
||||
{
|
||||
// simply return the unprocessed value...
|
||||
return strVal;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ObjectDefinitionStoreException( string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"Could not resolve placeholder '{0}'.", placeholder ) );
|
||||
}
|
||||
visitedPlaceholders.Remove( placeholder );
|
||||
}
|
||||
else
|
||||
{
|
||||
startIndex = -1;
|
||||
}
|
||||
}
|
||||
return strVal;
|
||||
}
|
||||
|
||||
private string ResolvePlaceholderVariable( string variableName )
|
||||
{
|
||||
foreach (IVariableSource variableSource in variableSourceList)
|
||||
{
|
||||
//TODO handle resolved values at are not strings?
|
||||
|
||||
object resolvedValue = variableSource.ResolveVariable( variableName );
|
||||
if (resolvedValue is string)
|
||||
{
|
||||
}
|
||||
if (resolvedValue != null)
|
||||
{
|
||||
if (resolvedValue is string)
|
||||
{
|
||||
return resolvedValue as string;
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Warn( "Placeholder " + variableSource + " resolved to object type [" + resolvedValue.GetType() + "]. Only string type currently supported" );
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,24 @@ namespace Spring.Objects.Factory.Config
|
||||
[TestFixture]
|
||||
public class VariablePlaceholderConfigurerTests
|
||||
{
|
||||
private class DictionaryVariableSource : IVariableSource
|
||||
{
|
||||
private Hashtable variables = new Hashtable();
|
||||
|
||||
public DictionaryVariableSource(params string[] args)
|
||||
{
|
||||
for(int i=0;i<args.Length;i+=2)
|
||||
{
|
||||
variables[args[i]] = args[i+1];
|
||||
}
|
||||
}
|
||||
|
||||
public string ResolveVariable(string name)
|
||||
{
|
||||
return (string) variables[name];
|
||||
}
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
@@ -72,6 +90,31 @@ namespace Spring.Objects.Factory.Config
|
||||
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void UsesCustomVariablePrefixSuffix()
|
||||
{
|
||||
StaticApplicationContext ac = new StaticApplicationContext();
|
||||
|
||||
MutablePropertyValues pvs = new MutablePropertyValues();
|
||||
pvs.Add("age", "%[maxResults]%");
|
||||
pvs.Add("name", "%[name]%");
|
||||
ac.RegisterSingleton("tb1", typeof(TestObject), pvs);
|
||||
|
||||
IList variableSources = new ArrayList();
|
||||
variableSources.Add( new DictionaryVariableSource( new string[] { "maxResults", "35", "name", "Erich" } ) );
|
||||
|
||||
|
||||
pvs = new MutablePropertyValues();
|
||||
pvs.Add("VariableSources", variableSources);
|
||||
pvs.Add("PlaceholderPrefix", "%[");
|
||||
pvs.Add("PlaceholderSuffix", "]%");
|
||||
|
||||
ac.RegisterSingleton("configurer", typeof(VariablePlaceholderConfigurer), pvs);
|
||||
ac.Refresh();
|
||||
|
||||
TestObject tb1 = (TestObject)ac.GetObject("tb1");
|
||||
Assert.AreEqual(35, tb1.Age);
|
||||
Assert.AreEqual("Erich", tb1.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user