using System;
using System.Collections;
using Spring.Collections;
using Spring.Util;
using Spring.Validation;
namespace Spring.DataBinding{
/// <summary>
/// Abstract base class for <see cref="IBinding"/> implementations.
/// </summary>
/// <author>Aleksandar Seovic</author>
public abstract class AbstractBinding : IBinding
{
#region Fields
/// <summary>
/// The name of the always filled error provider
/// </summary>
public static readonly string ALL_BINDINGERRORS_PROVIDER = "__all_bindingerrors";
// each Binding instance needs its own ID
private readonly string BINDING_ID = Guid.NewGuid().ToString("N");
private BindingDirection direction = BindingDirection.Bidirectional;
private BindingErrorMessage errorMessage;
private string[] errorProviders;
#endregion
#region Properties
/// <summary>
/// Gets or sets a flag specifying whether this binding is valid.
/// </summary>
/// <value>
/// <c>true</c> if this binding evaluated without errors;
/// <c>false</c> otherwise.
/// </value>
public bool IsValid(IValidationErrors errors)
{
if (errors == null) return true;
IList errorList = errors.GetErrors(ALL_BINDINGERRORS_PROVIDER);
return (errorList == null) || (!errorList.Contains(this.ErrorMessage));
}
/// <summary>
/// Marks this binding's state as invalid for this validationErrors collection.
/// Returns false if <paramref name="validationErrors"/> is null.
/// </summary>
/// <param name="validationErrors"></param>
/// <returns>false, if validationErrors is null</returns>
protected bool SetInvalid(IValidationErrors validationErrors)
{
if (validationErrors != null)
{
foreach (string provider in this.ErrorProviders)
{
validationErrors.AddError(provider, this.ErrorMessage);
}
return true;
}
return false;
}
///<summary>
/// Gets the unique ID of this binding instance.
///</summary>
public string Id
{
get { return BINDING_ID; }
}
/// <summary>
/// Gets or sets the <see cref="BindingDirection"/>.
/// </summary>
/// <value>The binding direction.</value>
public BindingDirection Direction
{
get { return direction; }
set { direction = value; }
}
/// <summary>
/// Gets the error message.
/// </summary>
/// <value>The error message.</value>
public BindingErrorMessage ErrorMessage
{
get { return errorMessage; }
}
/// <summary>
/// Gets the error providers.
/// </summary>
public string[] ErrorProviders
{
get { return errorProviders; }
}
#endregion
/// <summary>
/// Initializes a new instance of the <see cref="T:System.Object"></see> class.
/// </summary>
protected AbstractBinding()
{
this.errorMessage = new BindingErrorMessage( this.Id, "Binding-Error");
this.errorProviders = new string[] { ALL_BINDINGERRORS_PROVIDER };
}
#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>
public virtual void BindSourceToTarget(object source, object target, IValidationErrors validationErrors)
{
BindSourceToTarget(source, target, validationErrors, null);
}
/// <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>
public virtual void BindTargetToSource(object source, object target, IValidationErrors validationErrors)
{
BindTargetToSource(source, target, validationErrors, null);
}
/// <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 abstract void BindSourceToTarget(object source, object target, IValidationErrors validationErrors, IDictionary 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 abstract void BindTargetToSource(object source, object target, IValidationErrors validationErrors, IDictionary variables);
/// <summary>
/// Sets error message that should be displayed in the case
/// of a non-fatal binding error.
/// </summary>
/// <param name="messageId">
/// Resource ID of the error message.
/// </param>
/// <param name="errorProviders">
/// List of error providers message should be added to.
/// </param>
public void SetErrorMessage(string messageId, params string[] errorProviders)
{
AssertUtils.ArgumentHasText(messageId, "messageId");
if (errorProviders == null || errorProviders.Length == 0)
{
throw new ArgumentException("At least one error provider has to be specified.", "providers");
}
this.errorMessage = new BindingErrorMessage(this.BINDING_ID, messageId, null);
Set providers = new HashedSet();
providers.Add(ALL_BINDINGERRORS_PROVIDER);
providers.AddAll(errorProviders);
errorProviders = new string[providers.Count];
providers.CopyTo(errorProviders, 0);
this.errorProviders = errorProviders;
}
#endregion
///<summary>
///Determines whether the specified <see cref="T:System.Object"></see> is equal to the current <see cref="T:System.Object"></see>.
///</summary>
///<returns>
///true if the specified <see cref="T:System.Object"></see> is equal to the current <see cref="T:System.Object"></see>; otherwise, false.
///</returns>
///<param name="obj">The <see cref="T:System.Object"></see> to compare with the current <see cref="T:System.Object"></see>. </param><filterpriority>2</filterpriority>
public override bool Equals(object obj)
{
AbstractBinding other = obj as AbstractBinding;
return (other != null) && (this.Id == other.Id);
}
///<summary>
///Serves as a hash function for a particular type. <see cref="M:System.Object.GetHashCode"></see> is suitable for use in hashing algorithms and data structures like a hash table.
///</summary>
///<returns>
///A hash code for the current <see cref="T:System.Object"></see>.
///</returns>
public override int GetHashCode()
{
return this.Id.GetHashCode();
}
}
}
|