using System;
using System.Collections;
using System.Reflection;
using Common.Logging;
using Spring.Globalization;
using Spring.Validation;
namespace Spring.DataBinding{
/// <summary>
/// Abstract base class for simple, one-to-one <see cref="IBinding"/> implementations.
/// </summary>
/// <author>Aleksandar Seovic</author>
public abstract class AbstractSimpleBinding : AbstractBinding
{
#region Fields
private readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private IFormatter formatter;
#endregion
#region Constructor(s)
/// <summary>
/// Initialize a new instance of <see cref="AbstractSimpleBinding"/> without any <see cref="IFormatter"/>
/// </summary>
protected AbstractSimpleBinding()
{
}
/// <summary>
/// Initialize a new instance of <see cref="AbstractSimpleBinding"/> with the
/// specified <see cref="IFormatter"/>.
/// </summary>
protected AbstractSimpleBinding(IFormatter formatter)
{
this.formatter = formatter;
}
#endregion
#region Properties
/// <summary>
/// Gets or sets the <see cref="IFormatter"/> to use.
/// </summary>
/// <value>The formatter to use.</value>
public IFormatter Formatter
{
get { return formatter; }
set { formatter = value; }
}
#endregion
#region IBinding Implementation
/// <summary>
/// Binds source object to target object.
/// </summary>
/// <param name="source">
/// The source object.
/// </param>
/// <param name="target">
/// The target object.
/// </param>
/// <param name="validationErrors">
/// Validation errors collection that type conversion errors should be added to.
/// </param>
/// <param name="variables">
/// Variables that should be used during expression evaluation.
/// </param>
public override void BindSourceToTarget(object source, object target, IValidationErrors validationErrors,
IDictionary variables)
{
if (this.IsValid(validationErrors)
&& (this.Direction == BindingDirection.Bidirectional || this.Direction == BindingDirection.SourceToTarget))
{
try
{
DoBindSourceToTarget(source, target, variables);
}
catch (Exception)
{
if (!SetInvalid(validationErrors)) throw;
}
}
}
/// <summary>
/// Concrete implementation if source to target binding.
/// </summary>
/// <param name="source">
/// The source object.
/// </param>
/// <param name="target">
/// The target object.
/// </param>
/// <param name="variables">
/// Variables that should be used during expression evaluation.
/// </param>
protected virtual void DoBindSourceToTarget(object source, object target, IDictionary variables)
{
object value = this.GetSourceValue(source, variables);
if (this.Formatter != null && value is string)
{
value = this.Formatter.Parse((string)value);
}
this.SetTargetValue(target, value, variables);
}
/// <summary>
/// Binds target object to source object.
/// </summary>
/// <param name="source">
/// The source object.
/// </param>
/// <param name="target">
/// The target object.
/// </param>
/// <param name="validationErrors">
/// Validation errors collection that type conversion errors should be added to.
/// </param>
/// <param name="variables">
/// Variables that should be used during expression evaluation.
/// </param>
public override void BindTargetToSource(object source, object target, IValidationErrors validationErrors,
IDictionary variables)
{
if (this.IsValid(validationErrors)
&& (this.Direction == BindingDirection.Bidirectional || this.Direction == BindingDirection.TargetToSource))
{
try
{
DoBindTargetToSource(source, target, variables);
}
catch (Exception ex)
{
log.Warn(string.Format("Failed binding[{0}]:{1}", this.Id, ex));
if (!SetInvalid(validationErrors)) throw;
}
}
}
/// <summary>
/// Concrete implementation of target to source binding.
/// </summary>
/// <param name="source">
/// The source object.
/// </param>
/// <param name="target">
/// The target object.
/// </param>
/// <param name="variables">
/// Variables that should be used during expression evaluation.
/// </param>
protected virtual void DoBindTargetToSource(object source, object target, IDictionary variables)
{
object value = this.GetTargetValue(target, variables);
if (this.Formatter != null)
{
value = this.Formatter.Format(value);
}
this.SetSourceValue(source, value, variables);
}
#endregion
#region Abstract Methods
/// <summary>
/// Gets the source value for the binding.
/// </summary>
/// <param name="source">
/// Source object to extract value from.
/// </param>
/// <param name="variables">
/// Variables for expression evaluation.
/// </param>
/// <returns>
/// The source value for the binding.
/// </returns>
protected abstract object GetSourceValue(object source, IDictionary variables);
/// <summary>
/// Sets the source value for the binding.
/// </summary>
/// <param name="source">
/// The source object to set the value on.
/// </param>
/// <param name="value">
/// The value to set.
/// </param>
/// <param name="variables">
/// Variables for expression evaluation.
/// </param>
protected abstract void SetSourceValue(object source, object value, IDictionary variables);
/// <summary>
/// Gets the target value for the binding.
/// </summary>
/// <param name="target">
/// Source object to extract value from.
/// </param>
/// <param name="variables">
/// Variables for expression evaluation.
/// </param>
/// <returns>
/// The target value for the binding.
/// </returns>
protected abstract object GetTargetValue(object target, IDictionary variables);
/// <summary>
/// Sets the target value for the binding.
/// </summary>
/// <param name="target">
/// The target object to set the value on.
/// </param>
/// <param name="value">
/// The value to set.
/// </param>
/// <param name="variables">
/// Variables for expression evaluation.
/// </param>
protected abstract void SetTargetValue(object target, object value, IDictionary variables);
#endregion
}
}
|