#region License
/*
* Copyright 2002-2005 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;
using System.Collections;
using System.ComponentModel;
using System.Globalization;
using Common.Logging;
using Spring.Util;
#endregion
namespace Spring.Core.IO{
/// <summary>
/// Custom type converter for <see cref="Spring.Core.IO.IResource"/> instances.
/// </summary>
/// <remarks>
/// <p>
/// A resource path may contain placeholder variables of the form <c>${...}</c>
/// that will be expended to <b>environment variables</b>.
/// </p>
/// <p>
/// Currently only supports conversion from a <see cref="System.String"/>
/// instance.
/// </p>
/// </remarks>
/// <example>
/// <p>
/// On Win9x boxes, this resource path, <c>${userprofile}\objects.xml</c> will
/// be expanded at runtime with the value of the <c>'userprofile'</c> environment
/// variable substituted for the <c>'${userprofile}'</c> portion of the path.
/// </p>
/// <code escaped="true">
/// // assuming a user called Rick, running on a plain vanilla Windows XP setup...
/// // this resource path...
///
/// ${userprofile}\objects.xml
///
/// // will become (after expansion)...
///
/// C:\Documents and Settings\Rick\objects.xml
/// </code>
/// </example>
/// <author>Mark Pollack</author>
/// <seealso cref="Spring.Core.IO.IResourceLoader"/>
/// <seealso cref="System.ComponentModel.TypeConverter"/>
public class ResourceConverter : TypeConverter
{
private ILog _log = LogManager.GetLogger(typeof (ResourceConverter));
private IResourceLoader _resourceLoader;
#region Constructor (s) / Destructor
/// <summary>
/// Creates a new instance of the
/// <see cref="Spring.Core.IO.ResourceConverter"/> class.
/// </summary>
public ResourceConverter()
{
_resourceLoader = new ConfigurableResourceLoader();
}
/// <summary>
/// Creates a new instance of the
/// <see cref="Spring.Core.IO.ResourceConverter"/> class using the specified resourceLoader.
/// </summary>
/// <param name="resourceLoader">the underlying IResourceLoader to be used to resolve resources</param>
public ResourceConverter( IResourceLoader resourceLoader )
{
AssertUtils.ArgumentNotNull( resourceLoader, "resourceLoader" );
_resourceLoader = resourceLoader;
}
#endregion
/// <summary>
/// Returns whether this converter can convert an object of one
/// <see cref="System.Type"/> to a <see cref="Spring.Core.IO.IResource"/>
/// </summary>
/// <param name="context">
/// A <see cref="System.ComponentModel.ITypeDescriptorContext"/>
/// that provides a format context.
/// </param>
/// <param name="sourceType">
/// A <see cref="System.Type"/> that represents the
/// <see cref="System.Type"/> you want to convert from.
/// </param>
/// <returns>
/// <see langword="true"/> if the conversion is possible.
/// </returns>
public override bool CanConvertFrom(
ITypeDescriptorContext context,
Type sourceType)
{
if (sourceType == typeof (string))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
/// <summary>
/// Convert from a string value to a
/// <see cref="Spring.Core.IO.IResource"/> instance.
/// </summary>
/// <param name="context">
/// A <see cref="System.ComponentModel.ITypeDescriptorContext"/>
/// that provides a format context.
/// </param>
/// <param name="culture">
/// The <see cref="System.Globalization.CultureInfo"/> to use
/// as the current culture.
/// </param>
/// <param name="value">
/// The value that is to be converted.
/// </param>
/// <returns>
/// An <see cref="Spring.Core.IO.IResource"/> if successful.
/// </returns>
/// <exception cref="System.UriFormatException">
/// If the resource name objectained form the supplied
/// <paramref name="value"/> is malformed.
/// </exception>
/// <exception cref="System.Exception">
/// In the case of any errors arising from the instantiation of the
/// returned <see cref="Spring.Core.IO.IResource"/> instance.
/// </exception>
public override object ConvertFrom(
ITypeDescriptorContext context,
CultureInfo culture, object value)
{
string resource = value as string;
if (resource != null)
{
return GetResourceLoader().GetResource(ResolvePath(resource));
}
return base.ConvertFrom(context, culture, value);
}
/// <summary>
/// Resolve the given path, replacing placeholder values with
/// corresponding property values if necessary.
/// </summary>
/// <remarks>
/// <p>
/// This implementation resolves environment variables only.
/// </p>
/// </remarks>
/// <param name="path">The original resource path.</param>
/// <returns>The resolved resource path.</returns>
protected virtual string ResolvePath(string path)
{
// quite inefficient, but cost is only ever paid once at startup...
IList expressions = StringUtils.GetAntExpressions(path);
foreach (string expression in expressions)
{
string environmentValue
= Environment.GetEnvironmentVariable(expression);
if (environmentValue != null)
{
path = StringUtils.SetAntExpression(
path, expression, environmentValue);
}
else
{
#region Instrumentation
if (_log.IsWarnEnabled)
{
_log.Warn(string.Format(
CultureInfo.InvariantCulture,
"Could not resolve placeholder '{0}' in resource path " +
"'{1}' as an environment variable.", expression, path));
}
#endregion
}
}
return path;
}
/// <summary>
/// Return the <see cref="Spring.Core.IO.IResourceLoader"/> used to
/// resolve the string.
/// </summary>
/// <returns>
/// The <see cref="Spring.Core.IO.IResourceLoader"/> used to resolve
/// the string.
/// </returns>
protected internal virtual IResourceLoader GetResourceLoader()
{
return _resourceLoader;
}
}
}
|