User: roelofb
Date: 2008/09/01 12:47 PM

Added:
 
/trunk/Components/Validator/Castle.Components.Validator.Tests/ContributorsTests/
  ValidatorContainerInterfaceContributorTestCase.cs
 /trunk/Components/Validator/Castle.Components.Validator/
  DefaultValidationPerformer.cs, IHasValidationPerformerDependency.cs, 
IHasValidatorRegistryDependency.cs, IHasValidatorRunnerDependency.cs, 
IValidationPerformer.cs, IValidatorContainerInterface.cs
 /trunk/Components/Validator/Castle.Components.Validator/Attributes/
  ValidatorContainerInterfaceFlagAttribute.cs
 /trunk/Components/Validator/Castle.Components.Validator/Contibutors/
  ValidatorContainerInterfaceValidationContributor.cs

Modified:
 /trunk/Components/Validator/Castle.Components.Validator.Tests/
  Castle.Components.Validator.Tests-vs2005.csproj, 
Castle.Components.Validator.Tests-vs2008.csproj
 /trunk/Components/Validator/Castle.Components.Validator/
  AccessorUtil.cs, CachedValidationRegistry.cs, 
Castle.Components.Validator-vs2005.csproj, 
Castle.Components.Validator-vs2008.csproj, IValidatorBuilder.cs, 
IValidatorRegistry.cs, IValidatorRunner.cs, ValidatorRunner.cs
 /trunk/Components/Validator/Castle.Components.Validator/Attributes/
  AbstractCrossReferenceValidationAttribute.cs, AbstractValidationAttribute.cs, 
ValidateGroupNotEmptyAttribute.cs

Log:
 Fixed COMP-ISSUE-69, applied patch (with changes) by Gauthier Segay. Changes: 
VS2005 support, removed var declaration, spelling

File Changes:

Directory: /trunk/Components/Validator/Castle.Components.Validator/Attributes/
==============================================================================

File [modified]: AbstractCrossReferenceValidationAttribute.cs
Delta lines: +1 -2
===================================================================

--- 
trunk/Components/Validator/Castle.Components.Validator/Attributes/AbstractValidationAttribute.cs
    2008-09-01 19:19:55 UTC (rev 5302)
+++ 
trunk/Components/Validator/Castle.Components.Validator/Attributes/AbstractValidationAttribute.cs
    2008-09-01 19:47:27 UTC (rev 5303)
@@ -140,7 +140,7 @@
                /// Constructs and configures an <see cref="IValidator"/>
                /// instance based on the properties set on the attribute 
instance.
                /// </summary>
-               public virtual IValidator Build(ValidatorRunner 
validatorRunner, Type type)
+               public virtual IValidator Build(IValidatorRunner 
validatorRunner, Type type)
                {
                        IValidator validator = Build();
                        
@@ -171,4 +171,4 @@
                        }
                }
        }
-}
\ No newline at end of file

File [modified]: AbstractValidationAttribute.cs
Delta lines: +1 -1
===================================================================

--- 
trunk/Components/Validator/Castle.Components.Validator/Attributes/ValidateGroupNotEmptyAttribute.cs
 2008-09-01 19:19:55 UTC (rev 5302)
+++ 
trunk/Components/Validator/Castle.Components.Validator/Attributes/ValidateGroupNotEmptyAttribute.cs
 2008-09-01 19:47:27 UTC (rev 5303)
@@ -62,7 +62,7 @@
                /// <param name="validatorRunner"></param>
                /// <param name="type"></param>
                /// <returns></returns>
-               public override IValidator Build(ValidatorRunner 
validatorRunner, Type type)
+               public override IValidator Build(IValidatorRunner 
validatorRunner, Type type)
                {
                        GroupNotEmptyValidator validator = 
(GroupNotEmptyValidator)

File [modified]: ValidateGroupNotEmptyAttribute.cs
Delta lines: +32 -0
===================================================================

--- 
trunk/Components/Validator/Castle.Components.Validator/Attributes/ValidatorContainerInterfaceFlagAttribute.cs
                               (rev 0)
+++ 
trunk/Components/Validator/Castle.Components.Validator/Attributes/ValidatorContainerInterfaceFlagAttribute.cs
       2008-09-01 19:47:27 UTC (rev 5303)
@@ -0,0 +1,33 @@
+// Copyright 2004-2008 Castle Project - http://www.castleproject.org/
+// 
+// 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.
+
+namespace Castle.Components.Validator.Attributes
+{
+       using System;
+
+       /// <summary>
+       /// <para>
+       /// This is a flag attribute, used to mark 
+       /// validator embeding enabled interface
+       /// </para>
+       /// <para>
+       /// See <see cref="IValidatorContainerInterface"/> for further details
+       /// </para>
+       /// </summary>
+       public class ValidatorContainerInterfaceFlagAttribute 
+               : Attribute
+       {
+
+       }

File [added]: ValidatorContainerInterfaceFlagAttribute.cs
Delta lines: +2 -2
===================================================================

--- 
trunk/Components/Validator/Castle.Components.Validator/CachedValidationRegistry.cs
  2008-09-01 19:19:55 UTC (rev 5302)
+++ 
trunk/Components/Validator/Castle.Components.Validator/CachedValidationRegistry.cs
  2008-09-01 19:47:27 UTC (rev 5303)
@@ -71,7 +71,7 @@
                /// <param name="targetType">Target type.</param>
                /// <param name="runWhen">Restrict the set returned to the 
phase specified</param>
                /// <returns>A Validator array</returns>
-               public IValidator[] GetValidators(ValidatorRunner 
validatorRunner, Type targetType, RunWhen runWhen)
+               public IValidator[] GetValidators(IValidatorRunner 
validatorRunner, Type targetType, RunWhen runWhen)
                {
                        PropertyInfo[] properties = (PropertyInfo[]) 
propertiesPerType[targetType];
 
@@ -102,7 +102,7 @@
                /// <param name="runWhen">Restrict the set returned to the 
phase specified</param>
                /// <returns>A Validator array</returns>
                public IValidator[] GetValidators(
-                       ValidatorRunner validatorRunner, Type targetType, 
PropertyInfo property,
+                       IValidatorRunner validatorRunner, Type targetType, 
PropertyInfo property,
                        RunWhen runWhen)
                {

Directory: /trunk/Components/Validator/Castle.Components.Validator/
===================================================================

File [modified]: AccessorUtil.cs
Delta lines: +1 -2
===================================================================

--- 
trunk/Components/Validator/Castle.Components.Validator/Attributes/AbstractCrossReferenceValidationAttribute.cs
      2008-09-01 19:19:55 UTC (rev 5302)
+++ 
trunk/Components/Validator/Castle.Components.Validator/Attributes/AbstractCrossReferenceValidationAttribute.cs
      2008-09-01 19:47:27 UTC (rev 5303)
@@ -78,7 +78,7 @@
                /// Constructs and configures an <see cref="IValidator"/>
                /// instance based on the properties set on the attribute 
instance.
                /// </summary>
-               public override IValidator Build(ValidatorRunner 
validatorRunner, Type type)
+               public override IValidator Build(IValidatorRunner 
validatorRunner, Type type)
                {
                        IValidator validator = base.Build(validatorRunner, 
type);
 
@@ -90,4 +90,4 @@
                        return validator;
                }
        }
-}
\ No newline at end of file

File [modified]: CachedValidationRegistry.cs
Delta lines: +8 -0
===================================================================

--- 
trunk/Components/Validator/Castle.Components.Validator/Castle.Components.Validator-vs2005.csproj
    2008-09-01 19:19:55 UTC (rev 5302)
+++ 
trunk/Components/Validator/Castle.Components.Validator/Castle.Components.Validator-vs2005.csproj
    2008-09-01 19:47:27 UTC (rev 5303)
@@ -62,11 +62,19 @@
     <Compile Include="Attributes\ValidateSelfAttribute.cs" />
     <Compile Include="Attributes\ValidateSetAttribute.cs" />
     <Compile Include="Attributes\ValidateSingleAttribute.cs" />
+    <Compile Include="Attributes\ValidatorContainerInterfaceFlagAttribute.cs" 
/>
     <Compile Include="Contibutors\AbstractValidationContributor.cs" />
     <Compile Include="Contibutors\SelfValidationContributor.cs" />
+    <Compile 
Include="Contibutors\ValidatorContainerInterfaceValidationContributor.cs" />
+    <Compile Include="DefaultValidationPerformer.cs" />
+    <Compile Include="IHasValidationPerformerDependency.cs" />
+    <Compile Include="IHasValidatorRegistryDependency.cs" />
+    <Compile Include="IHasValidatorRunnerDependency.cs" />
     <Compile Include="IPropertyAccessAware.cs" />
     <Compile Include="IReferenceAccessAware.cs" />
     <Compile Include="IValidationContributor.cs" />
+    <Compile Include="IValidationPerformer.cs" />
+    <Compile Include="IValidatorContainerInterface.cs" />
     <Compile Include="IValidatorRunner.cs" />
     <Compile Include="Messages.fr.Designer.cs">

File [modified]: Castle.Components.Validator-vs2005.csproj
Delta lines: +9 -2
===================================================================

--- 
trunk/Components/Validator/Castle.Components.Validator/Castle.Components.Validator-vs2008.csproj
    2008-09-01 19:19:55 UTC (rev 5302)
+++ 
trunk/Components/Validator/Castle.Components.Validator/Castle.Components.Validator-vs2008.csproj
    2008-09-01 19:47:27 UTC (rev 5303)
@@ -2,7 +2,7 @@
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>9.0.30729</ProductVersion>
+    <ProductVersion>9.0.21022</ProductVersion>
     <SchemaVersion>2.0</SchemaVersion>
     <ProjectGuid>{4C945D49-02E9-43F2-9202-E7A6E7C56E77}</ProjectGuid>
     <OutputType>Library</OutputType>
@@ -72,9 +72,15 @@
     <Compile Include="Attributes\ValidateSetAttribute.cs" />
     <Compile Include="Attributes\ValidateSingleAttribute.cs" />
     <Compile Include="Contibutors\SelfValidationContributor.cs" />
+    <Compile Include="DefaultValidationPerformer.cs" />
+    <Compile Include="IHasValidationPerformerDependency.cs" />
+    <Compile Include="IHasValidatorRegistryDependency.cs" />
+    <Compile Include="IHasValidatorRunnerDependency.cs" />
     <Compile Include="IValidationContributor.cs" />
     <Compile Include="IReferenceAccessAware.cs" />
     <Compile Include="IPropertyAccessAware.cs" />
+    <Compile Include="IValidationPerformer.cs" />
+    <Compile Include="IValidatorContainerInterface.cs" />
     <Compile Include="IValidatorRunner.cs" />
     <Compile Include="Messages.es.Designer.cs">
       <AutoGen>True</AutoGen>
@@ -136,6 +142,8 @@
     <Compile Include="AccessorUtil.cs" />
     <Compile Include="ValidationException.cs" />
     <Compile Include="ValidationInternalError.cs" />
+    <Compile Include="Attributes\ValidatorContainerInterfaceFlagAttribute.cs" 
/>
+    <Compile 
Include="Contibutors\ValidatorContainerInterfaceValidationContributor.cs" />
     <Compile Include="ValidatorRunner.cs" />
     <Compile Include="Validators\AbstractValidator.cs" />
     <Compile Include="IValidatorBuilder.cs" />
@@ -242,4 +250,4 @@
   <Target Name="AfterBuild">
   </Target>
   -->
-</Project>
\ No newline at end of file

File [modified]: Castle.Components.Validator-vs2008.csproj
Delta lines: +121 -0
===================================================================

--- 
trunk/Components/Validator/Castle.Components.Validator/Contibutors/ValidatorContainerInterfaceValidationContributor.cs
                              (rev 0)
+++ 
trunk/Components/Validator/Castle.Components.Validator/Contibutors/ValidatorContainerInterfaceValidationContributor.cs
      2008-09-01 19:47:27 UTC (rev 5303)
@@ -0,0 +1,122 @@
+// Copyright 2004-2008 Castle Project - http://www.castleproject.org/
+// 
+// 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.
+
+namespace Castle.Components.Validator.Contibutors
+{
+       using System;
+       using System.Collections.Generic;
+       using Castle.Components.Validator.Attributes;
+
+       /// <summary>
+       /// Will apply validation on members defined in derived interface 
IValidatorContainerInterface from the object instance
+       /// </summary>
+       public class ValidatorContainerInterfaceValidationContributor 
+               : AbstractValidationContributor
+                 , IHasValidationPerformerDependency
+                 , IHasValidatorRegistryDependency
+                 , IHasValidatorRunnerDependency
+       {
+               private static Dictionary<Type, IEnumerable<Type>> 
typeToValidatorContainerInterfacesMap = new Dictionary<Type, 
IEnumerable<Type>>();
+
+               private IValidatorRegistry validatorRegistry;
+               private IValidationPerformer validationPerformer;
+               private IValidatorRunner validatorRunner;
+
+               IValidationPerformer 
IHasValidationPerformerDependency.ValidationPerformer
+               {
+                       set { validationPerformer = value; }
+               }
+
+
+               IValidatorRegistry 
IHasValidatorRegistryDependency.ValidatorRegistry
+               {
+                       set { validatorRegistry = value; }
+               }
+
+
+               IValidatorRunner IHasValidatorRunnerDependency.ValidatorRunner {
+                       set { validatorRunner = value; }
+               }
+
+
+               /// <summary>
+               /// Allows for custom initialization based on type.  This will 
only be called once
+               /// for each type passed to the contributor.
+               /// </summary>
+               /// <param name="type">The type.</param>
+               protected override void Initialize(Type type)
+               {
+                       
if(!typeToValidatorContainerInterfacesMap.ContainsKey(type))
+                       {
+                               IList<Type> cachedInterfaceTypes = new 
List<Type>();
+                               Type[] interfaceTypes = type.GetInterfaces();
+                               foreach(Type interfaceType in interfaceTypes)
+                               {
+                                       if(IsInterfaceFlagged(interfaceType))
+                                               
cachedInterfaceTypes.Add(interfaceType);
+                               }
+                               typeToValidatorContainerInterfacesMap[type] = 
cachedInterfaceTypes;
+                       }
+               }
+
+               private bool IsInterfaceFlagged(Type interfaceType)
+               {
+                       object[] attributes = 
interfaceType.GetCustomAttributes(typeof(ValidatorContainerInterfaceFlagAttribute),
 false);
+                       return (attributes.Length != 0);
+               }
+
+
+               /// <summary>
+               /// Determines whether the specified instance is valid.  
Returns an
+               /// <see cref="ErrorSummary"/> that will be appended to the 
existing
+               /// error summary for an object.
+               /// </summary>
+               /// <param name="instance">The instance.</param>
+               /// <param name="when">The when.</param>
+               /// <returns></returns>
+               protected override ErrorSummary IsValidInternal(object 
instance, RunWhen when)
+               {
+                       ErrorSummary summary = new ErrorSummary();
+
+                       // perform validation on each validator container 
interfaces
+                       foreach (Type validatorContainerType in 
GetValidatorContainerInterfacesForType(instance.GetType()))
+                       {
+                               // don't run any other contributors
+                               IValidationContributor[] contributors = null;
+
+                               validationPerformer.PerformValidation(
+                                       instance,
+                                       
RequestValidatorsToRegistry(validatorContainerType, when),
+                                       contributors,
+                                       when,
+                                       summary
+                                       );
+                       }
+                       return summary;
+               }
+
+               private IEnumerable<Type> 
GetValidatorContainerInterfacesForType(Type type)
+               {
+                       return typeToValidatorContainerInterfacesMap[type];
+               }
+
+               private IValidator[] RequestValidatorsToRegistry(Type 
validatorContainerType, RunWhen when)
+               {
+                       return validatorRegistry.GetValidators(
+                               validatorRunner, 
+                               validatorContainerType,
+                               when);
+               }
+       }

File [added]: DefaultValidationPerformer.cs
Delta lines: +26 -0
===================================================================

--- 
trunk/Components/Validator/Castle.Components.Validator/IHasValidationPerformerDependency.cs
                         (rev 0)
+++ 
trunk/Components/Validator/Castle.Components.Validator/IHasValidationPerformerDependency.cs
 2008-09-01 19:47:27 UTC (rev 5303)
@@ -0,0 +1,27 @@
+// Copyright 2004-2008 Castle Project - http://www.castleproject.org/
+// 
+// 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.
+
+namespace Castle.Components.Validator
+{
+       /// <summary>
+       /// For class having dependency on <see cref="IValidationPerformer"/> 
instance
+       /// </summary>
+       public interface IHasValidationPerformerDependency
+       {
+               /// <summary>
+               /// <see cref="IValidationPerformer"/> instance dependency 
setter
+               /// </summary>
+               IValidationPerformer ValidationPerformer { set; }
+       }

File [added]: IHasValidationPerformerDependency.cs
Delta lines: +26 -0
===================================================================

--- 
trunk/Components/Validator/Castle.Components.Validator/IHasValidatorRegistryDependency.cs
                           (rev 0)
+++ 
trunk/Components/Validator/Castle.Components.Validator/IHasValidatorRegistryDependency.cs
   2008-09-01 19:47:27 UTC (rev 5303)
@@ -0,0 +1,27 @@
+// Copyright 2004-2008 Castle Project - http://www.castleproject.org/
+// 
+// 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.
+
+namespace Castle.Components.Validator
+{
+       /// <summary>
+       /// For class having dependency on <see cref="IValidatorRegistry"/> 
instance
+       /// </summary>
+       public interface IHasValidatorRegistryDependency
+       {
+               /// <summary>
+               /// <see cref="IValidatorRegistry"/> instance dependency setter
+               /// </summary>
+               IValidatorRegistry ValidatorRegistry { set; }
+       }

File [added]: IHasValidatorRegistryDependency.cs
Delta lines: +26 -0
===================================================================

--- 
trunk/Components/Validator/Castle.Components.Validator/IHasValidatorRunnerDependency.cs
                             (rev 0)
+++ 
trunk/Components/Validator/Castle.Components.Validator/IHasValidatorRunnerDependency.cs
     2008-09-01 19:47:27 UTC (rev 5303)
@@ -0,0 +1,27 @@
+// Copyright 2004-2008 Castle Project - http://www.castleproject.org/
+// 
+// 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.
+
+namespace Castle.Components.Validator
+{
+       /// <summary>
+       /// For class having dependency on <see cref="IValidatorRunner"/> 
instance
+       /// </summary>
+       public interface IHasValidatorRunnerDependency
+       {
+               /// <summary>
+               /// <see cref="IValidatorRunner"/> instance dependency setter
+               /// </summary>
+               IValidatorRunner ValidatorRunner { set; }
+       }

File [added]: IHasValidatorRunnerDependency.cs
Delta lines: +54 -0
===================================================================

--- 
trunk/Components/Validator/Castle.Components.Validator/IValidationPerformer.cs  
                            (rev 0)
+++ 
trunk/Components/Validator/Castle.Components.Validator/IValidationPerformer.cs  
    2008-09-01 19:47:27 UTC (rev 5303)
@@ -0,0 +1,54 @@
+// Copyright 2004-2008 Castle Project - http://www.castleproject.org/
+// 
+// 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.
+
+namespace Castle.Components.Validator
+{
+       using System.Collections.Generic;
+
+       /// <summary>
+       /// 
+       /// </summary>
+       public interface IValidationPerformer
+       {
+               /// <summary>
+               /// Performs validation on a given object instance
+               /// </summary>
+               /// <param name="objectInstance">object instance to 
validate</param>
+               /// <param name="validators">validators to apply</param>
+               /// <param name="contributors">validation contributors to 
apply</param>
+               /// <param name="runWhen">Restrict the set returned to the 
phase specified</param>
+               /// <param name="summaryToPopulate">instance which will be 
populated by the performed validation</param>
+               /// <returns>wether the instance is valid or not</returns>
+               bool PerformValidation(
+                       object objectInstance,
+                       IEnumerable<IValidator> validators,
+                       IEnumerable<IValidationContributor> contributors,
+                       RunWhen runWhen,
+                       ErrorSummary summaryToPopulate
+                       );
+
+               /// <summary>
+               /// Executes the validation contributors.
+               /// </summary>
+               /// <param name="objectInstance">The object instance.</param>
+               /// <param name="contributors">contributors to apply</param>
+               /// <param name="summaryToPopulate">The summary to 
populate.</param>
+               /// <param name="runWhen">Restrict the set returned to the 
phase specified</param>
+               void ExecuteContributors(
+                       object objectInstance,
+                       IEnumerable<IValidationContributor> contributors,
+                       ErrorSummary summaryToPopulate,
+                       RunWhen runWhen);
+       }
+}

File [added]: IValidationPerformer.cs
Delta lines: +1 -2
===================================================================

--- trunk/Components/Validator/Castle.Components.Validator/IValidatorBuilder.cs 
2008-09-01 19:19:55 UTC (rev 5302)
+++ trunk/Components/Validator/Castle.Components.Validator/IValidatorBuilder.cs 
2008-09-01 19:47:27 UTC (rev 5303)
@@ -35,6 +35,6 @@
                /// <param name="validatorRunner">The validator runner.</param>
                /// <param name="type">The type that this validator is built 
for</param>
                /// <returns></returns>
-               IValidator Build(ValidatorRunner validatorRunner, Type type);
+               IValidator Build(IValidatorRunner validatorRunner, Type type);
        }
-}
\ No newline at end of file

File [modified]: IValidatorBuilder.cs
Delta lines: +40 -0
===================================================================

--- 
trunk/Components/Validator/Castle.Components.Validator/IValidatorContainerInterface.cs
                              (rev 0)
+++ 
trunk/Components/Validator/Castle.Components.Validator/IValidatorContainerInterface.cs
      2008-09-01 19:47:27 UTC (rev 5303)
@@ -0,0 +1,41 @@
+// Copyright 2004-2008 Castle Project - http://www.castleproject.org/
+// 
+// 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.
+
+namespace Castle.Components.Validator 
+{
+       using Castle.Components.Validator.Attributes;
+
+       /// <summary>
+       /// This is a base interface that should be implemented by 
+       /// interfaces that have members with validation attributes.
+       /// </summary>
+       /// <remarks>
+       /// Note that that the interface should be explicitely flagged 
+       /// with the <see cref="ValidatorContainerInterfaceFlagAttribute"/>
+       /// attribute
+       /// </remarks>
+       /// <example>
+       /// [ValidatorContainerInterfaceFlag]
+       /// public interface IMyModelValidationDeclaration
+       ///             : IValidatorContainerInterface
+       /// {
+       ///             [ValidateNonEmpty]
+       ///             string MyProperty { get; }
+       /// }
+       /// </example>
+       public interface IValidatorContainerInterface
+       { 
+               
+       }

File [added]: IValidatorContainerInterface.cs
Delta lines: +2 -3
===================================================================

--- 
trunk/Components/Validator/Castle.Components.Validator/IValidatorRegistry.cs    
    2008-09-01 19:19:55 UTC (rev 5302)
+++ 
trunk/Components/Validator/Castle.Components.Validator/IValidatorRegistry.cs    
    2008-09-01 19:47:27 UTC (rev 5303)
@@ -32,7 +32,7 @@
                /// <param name="targetType">Target type.</param>
                /// <param name="runWhen">Restrict the set returned to the 
phase specified</param>
                /// <returns>A Validator array</returns>
-               IValidator[] GetValidators(ValidatorRunner validatorRunner, 
Type targetType, RunWhen runWhen);
+               IValidator[] GetValidators(IValidatorRunner validatorRunner, 
Type targetType, RunWhen runWhen);
 
                /// <summary>
                /// Gets all validators associated with a property.
@@ -45,7 +45,7 @@
                /// <param name="property">The property.</param>
                /// <param name="runWhen">Restrict the set returned to the 
phase specified</param>
                /// <returns>A Validator array</returns>
-               IValidator[] GetValidators(ValidatorRunner validatorRunner, 
Type targetType, PropertyInfo property, RunWhen runWhen);
+               IValidator[] GetValidators(IValidatorRunner validatorRunner, 
Type targetType, PropertyInfo property, RunWhen runWhen);
 
                /// <summary>
                /// Gets the property value accessor.
@@ -68,4 +68,4 @@
                /// <param name="key">The key.</param>
                string GetStringFromResource(string key);
        }
-}
\ No newline at end of file

File [modified]: IValidatorRegistry.cs
Delta lines: +25 -2
===================================================================

--- trunk/Components/Validator/Castle.Components.Validator/IValidatorRunner.cs  
2008-09-01 19:19:55 UTC (rev 5302)
+++ trunk/Components/Validator/Castle.Components.Validator/IValidatorRunner.cs  
2008-09-01 19:47:27 UTC (rev 5303)
@@ -1,5 +1,22 @@
+// Copyright 2004-2008 Castle Project - http://www.castleproject.org/
+// 
+// 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.
+
 namespace Castle.Components.Validator
 {
+
+       using System.Collections;
+       
        /// <summary>
        /// Defines the entry point for validation.
        /// </summary>
@@ -39,7 +56,7 @@
                /// for detailed conditions.
                /// </returns>
                bool HasErrors(object instance);
-
+               
                /// <summary>
                /// Gets the error list per instance.
                /// </summary>
@@ -49,5 +66,12 @@
                /// was either valid or has not been validated before.
                /// </returns>
                ErrorSummary GetErrorSummary(object instance);
+               
+               /// <summary>
+               /// Gets the extended properties, which allows <see 
cref="IValidator"/> 
+               /// implementation to store additional information to track 
state.
+               /// </summary>
+               /// <value>The extended properties.</value>
+               IDictionary ExtendedProperties { get ; }
        }
-}
\ No newline at end of file

File [modified]: IValidatorRunner.cs
Delta lines: +79 -64
===================================================================

--- trunk/Components/Validator/Castle.Components.Validator/ValidatorRunner.cs   
2008-09-01 19:19:55 UTC (rev 5302)
+++ trunk/Components/Validator/Castle.Components.Validator/ValidatorRunner.cs   
2008-09-01 19:47:27 UTC (rev 5303)
@@ -18,6 +18,7 @@
        using System.Collections;
        using System.Collections.Generic;
        using System.Reflection;
+       using Castle.Components.Validator.Contibutors;
 
        /// <summary>
        /// Coordinates the gathering and execution of validators.
@@ -46,13 +47,29 @@
                        /// Default setting is false: the validation runner 
will not infer validators based on data types
                        /// </summary>
                        public const bool InferValidators = false;
+                       /// <summary>
+                       /// 
+                       /// </summary>
+                       public static readonly IValidationPerformer 
DefaultValidationPerformer = new DefaultValidationPerformer();
+
+                       /// <summary>
+                       /// 
+                       /// </summary>
+                       public static IValidationContributor[] 
DefaultContributors =
+                               new IValidationContributor[]
+                                       {
+                                               new SelfValidationContributor(),
+                                               new 
ValidatorContainerInterfaceValidationContributor()
+                                       };
                }
+
                private readonly static IDictionary<Type, Type> type2Validator;
                private readonly IDictionary extendedProperties = new 
Hashtable();
                private readonly IDictionary<object, ErrorSummary> 
errorPerInstance;
                private readonly bool inferValidators;
                private readonly IValidatorRegistry registry;
                private readonly List<IValidationContributor> contributors = 
new List<IValidationContributor>();
+               private readonly IValidationPerformer validationPerformer;
 
                static ValidatorRunner()
                {
@@ -77,49 +94,65 @@
                /// Initializes a new instance of the <see 
cref="ValidatorRunner"/> class.
                /// </summary>
                /// <param name="registry">The registry.</param>
-               public ValidatorRunner(IValidatorRegistry registry) : 
this(DefaultSettings.InferValidators, registry)
-               {
-                       contributors.Add(new SelfValidationContributor());
-               }
+               public ValidatorRunner(IValidatorRegistry registry) 
+                       : this(DefaultSettings.InferValidators, registry)
+               {}
 
                /// <summary>
                /// Initializes a new instance of the <see 
cref="ValidatorRunner"/> class.
                /// </summary>
-               /// <param name="contributors">The contributors.</param>
+               /// <param name="inferValidators">If true, the runner will try 
to infer the validators based on data types</param>
                /// <param name="registry">The registry.</param>
-               public ValidatorRunner(IValidationContributor[] contributors, 
IValidatorRegistry registry) :
-                       this(DefaultSettings.InferValidators, registry, 
contributors)
-               {
-               }
+               public ValidatorRunner(bool inferValidators, IValidatorRegistry 
registry)
+                       : this(inferValidators, registry, 
DefaultSettings.DefaultContributors)
+               {}
 
                /// <summary>
                /// Initializes a new instance of the <see 
cref="ValidatorRunner"/> class.
                /// </summary>
-               /// <param name="inferValidators">If true, the runner will try 
to infer the validators based on data types</param>
+               /// <param name="contributors">The contributors.</param>
                /// <param name="registry">The registry.</param>
-               /// <param name="contributors">The contributors.</param>
-               public ValidatorRunner(bool inferValidators, IValidatorRegistry 
registry, IValidationContributor[] contributors) : 
-                       this(inferValidators, registry)
-               {
-                       this.contributors.AddRange(contributors);
-               }
+               public ValidatorRunner(IValidationContributor[] contributors, 
IValidatorRegistry registry)
+                       : this(DefaultSettings.InferValidators, registry, 
contributors)
+               {}
 
                /// <summary>
                /// Initializes a new instance of the <see 
cref="ValidatorRunner"/> class.
                /// </summary>
                /// <param name="inferValidators">If true, the runner will try 
to infer the validators based on data types</param>
                /// <param name="registry">The registry.</param>
-               public ValidatorRunner(bool inferValidators, IValidatorRegistry 
registry)
-               {
+               /// <param name="contributors">The contributors.</param>
+               public ValidatorRunner(bool inferValidators, IValidatorRegistry 
registry, IValidationContributor[] contributors) {
                        if (registry == null) throw new 
ArgumentNullException("registry");
 
                        this.inferValidators = inferValidators;
 
+                       validationPerformer = 
DefaultSettings.DefaultValidationPerformer;
+
                        errorPerInstance = new Dictionary<object, 
ErrorSummary>();
 
                        this.registry = registry;
+                       this.contributors.AddRange(contributors);
+
+                       // resolve contributor dependencies if needed
+                       foreach(IValidationContributor contributor in 
this.contributors)
+                       {
+                               IHasValidationPerformerDependency 
hasPerformerDependency = (contributor as IHasValidationPerformerDependency);
+                               if (hasPerformerDependency != null)
+                                       
hasPerformerDependency.ValidationPerformer = this.validationPerformer;
+                               
+                               IHasValidatorRunnerDependency 
hasValidatorRunnerDependency = contributor as IHasValidatorRunnerDependency;
+                               if (hasValidatorRunnerDependency != null)
+                                       
hasValidatorRunnerDependency.ValidatorRunner = this;
+                               
+                               IHasValidatorRegistryDependency 
hasValidatorRegistryDependency = (contributor as 
IHasValidatorRegistryDependency);
+                               if (hasValidatorRegistryDependency != null) 
+                                       
hasValidatorRegistryDependency.ValidatorRegistry = registry;
+                       }
+
                }
 
+
                /// <summary>
                /// Determines whether the specified instance is valid.
                /// <para>
@@ -151,13 +184,22 @@
                        if (objectInstance == null) throw new 
ArgumentNullException("objectInstance");
 
                        bool isValid;
-
+                       
                        ErrorSummary summary = new ErrorSummary();
 
-                       IEnumerable<IValidator> validators = 
GetValidators(objectInstance, runWhen);
+                       IValidator[] validators = GetValidators(objectInstance, 
runWhen);
                        
-                       isValid = PerformValidation(objectInstance, validators, 
runWhen, summary);
+                       SortValidators(validators);
 
+                       isValid = validationPerformer.PerformValidation(
+                               objectInstance,
+                               validators,
+                               contributors,
+                               runWhen,
+                               summary);
+
+                       SetErrorSummaryForInstance(objectInstance, summary);
+
                        return isValid;
                }
 
@@ -203,6 +245,7 @@
                        return validators;
                }
 
+
                /// <summary>
                /// Gets the error list per instance.
                /// </summary>
@@ -238,47 +281,6 @@
                }
 
                /// <summary>
-               /// main validation logic happens here
-               /// </summary>
-               /// <param name="objectInstance">object instance to be 
validated</param>
-               /// <param name="validators">the validators to run</param>
-               /// <param name="runWhen">The run when.</param>
-               /// <param name="summaryToPopulate">The summary to 
populate.</param>
-               /// <returns></returns>
-               protected virtual bool PerformValidation(object objectInstance, 
IEnumerable<IValidator> validators, RunWhen runWhen, ErrorSummary 
summaryToPopulate) 
-               {
-                       foreach (IValidator validator in validators) 
-                       {
-                               if (!validator.IsValid(objectInstance)) {
-                                       string name = validator.FriendlyName ?? 
validator.Name;
-                                       
summaryToPopulate.RegisterErrorMessage(name, validator.ErrorMessage);
-                               }
-                       }
-
-                       ExecuteContributors(objectInstance, summaryToPopulate, 
runWhen);
-
-                       SetErrorSummaryForInstance(objectInstance, 
summaryToPopulate);
-
-                       bool isValid = !summaryToPopulate.HasError;
-                       return isValid;
-               }
-
-               /// <summary>
-               /// Executes the validation contributors.
-               /// </summary>
-               /// <param name="objectInstance">The object instance.</param>
-               /// <param name="summaryToPopulate">The summary to 
populate.</param>
-               /// <param name="runWhen">The run when.</param>
-               private void ExecuteContributors(object objectInstance, 
ErrorSummary summaryToPopulate, RunWhen runWhen)
-               {
-                       foreach (IValidationContributor contributor in 
contributors)
-                       {
-                               ErrorSummary errors = 
contributor.IsValid(objectInstance, runWhen);
-                               summaryToPopulate.RegisterErrorsFrom(errors);
-                       }
-               }
-
-               /// <summary>
                /// associate error summary to the object instance
                /// </summary>
                /// <param name="objectInstance">object instance to associate 
validation error summary with</param>
@@ -302,13 +304,26 @@
                        Array.Sort(validators, ValidatorComparer.Instance);
                }
 
-
                private IValidator[] GetValidators(object objectInstance, 
RunWhen runWhen) 
                {
                        if (objectInstance == null) throw new 
ArgumentNullException("objectInstance");
 
-                       IValidator[] validators = registry.GetValidators(this, 
objectInstance.GetType(), runWhen);
+                       IValidator[] validators = 
GetValidatorsForDeclaringType(objectInstance.GetType(), runWhen);
 
+                       return validators;
+               }
+
+               /// <summary>
+               /// 
+               /// </summary>
+               /// <param name="declaringType"></param>
+               /// <param name="runWhen"></param>
+               /// <returns></returns>
+               protected IValidator[] GetValidatorsForDeclaringType(Type 
declaringType, RunWhen runWhen) 
+               {
+
+                       IValidator[] validators = registry.GetValidators(this, 
declaringType, runWhen);
+
                        SortValidators(validators);
 

File [modified]: ValidatorRunner.cs
Delta lines: +1 -0
===================================================================

--- 
trunk/Components/Validator/Castle.Components.Validator.Tests/Castle.Components.Validator.Tests-vs2005.csproj
        2008-09-01 19:19:55 UTC (rev 5302)
+++ 
trunk/Components/Validator/Castle.Components.Validator.Tests/Castle.Components.Validator.Tests-vs2005.csproj
        2008-09-01 19:47:27 UTC (rev 5303)
@@ -40,6 +40,7 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="ContributorsTests\SelfValidationContributorTestCase.cs" 
/>
+    <Compile 
Include="ContributorsTests\ValidatorContainerInterfaceContributorTestCase.cs" />
     <Compile Include="ErrorSummaryTestCase.cs" />
     <Compile Include="Messages.Designer.cs">

Directory: /trunk/Components/Validator/Castle.Components.Validator.Tests/
=========================================================================

File [modified]: Castle.Components.Validator.Tests-vs2005.csproj
Delta lines: +1 -1
===================================================================

--- 
trunk/Components/Validator/Castle.Components.Validator.Tests/Castle.Components.Validator.Tests-vs2008.csproj
        2008-09-01 19:19:55 UTC (rev 5302)
+++ 
trunk/Components/Validator/Castle.Components.Validator.Tests/Castle.Components.Validator.Tests-vs2008.csproj
        2008-09-01 19:47:27 UTC (rev 5303)
@@ -81,6 +81,7 @@
     <Compile Include="ContributorsTests\SelfValidationContributorTestCase.cs" 
/>
     <Compile Include="ValidatorTests\SetValidatorTestCase.cs" />
     <Compile Include="ValidatorTests\SingleValidatorTestCase.cs" />
+    <Compile 
Include="ContributorsTests\ValidatorContainerInterfaceContributorTestCase.cs" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference 
Include="..\Castle.Components.Validator\Castle.Components.Validator-vs2008.csproj">
@@ -109,4 +110,4 @@
   <Target Name="AfterBuild">
   </Target>
   -->
-</Project>
\ No newline at end of file

File [modified]: Castle.Components.Validator.Tests-vs2008.csproj
Delta lines: +126 -0
===================================================================

--- 
trunk/Components/Validator/Castle.Components.Validator.Tests/ContributorsTests/ValidatorContainerInterfaceContributorTestCase.cs
                            (rev 0)
+++ 
trunk/Components/Validator/Castle.Components.Validator.Tests/ContributorsTests/ValidatorContainerInterfaceContributorTestCase.cs
    2008-09-01 19:47:27 UTC (rev 5303)
@@ -0,0 +1,127 @@
+// Copyright 2004-2008 Castle Project - http://www.castleproject.org/
+// 
+// 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.
+
+namespace Castle.Components.Validator.Tests.ContributorsTests
+{
+       using Castle.Components.Validator.Attributes;
+       using Castle.Components.Validator.Contibutors;
+       using NUnit.Framework;
+
+       [TestFixture]
+       public class ValidatorContainerInterfaceContributorTestCase
+       {
+               private ValidatorContainerInterfaceValidationContributor 
contributor;
+
+               #region test case model
+               class Form1
+                       : IForm1Validation1
+                         , IForm1Validation2
+                         , IForm1Validation3
+                        , IForm1Validation4
+               {
+                       private string userId_, password_, 
passwordConfirmation_, magicNumber_;
+                       public string UserId { get { return userId_; } set { 
userId_ = value; } }
+                       public string Password { get { return password_; } set 
{ password_ = value; } }
+                       public string PasswordConfirmation { get { return 
passwordConfirmation_; } set { passwordConfirmation_ = value; } }
+                       public string MagicNumber { get { return magicNumber_; 
} set { magicNumber_ = value;} }
+               }
+
+               [ValidatorContainerInterfaceFlag]
+               interface IForm1Validation1
+                       : IValidatorContainerInterface
+               {
+                       [ValidateNonEmpty]
+                       [ValidateLength(1)]
+                       string UserId { get; }
+                       [ValidateNonEmpty]
+                       [ValidateLength(8)]
+                       string Password { get; }
+               }
+
+               [ValidatorContainerInterfaceFlag]
+               interface IForm1Validation2
+                       : IValidatorContainerInterface
+               {
+                       [ValidateSameAs("Password")]
+                       string PasswordConfirmation { get; }
+               }
+
+               interface IForm1Validation3
+                       : IValidatorContainerInterface
+               {
+                       [ValidateSameAs("Password")]
+                       string PasswordConfirmation { get; }
+               }
+
+               [ValidatorContainerInterfaceFlag]
+               interface IForm1Validation4
+                       : IValidatorContainerInterface {
+                       [ValidateInteger(RunWhen = RunWhen.Update)]
+                       string MagicNumber { get; }
+               }
+
+               #endregion
+
+
+               [SetUp]
+               public void Init() {
+                       contributor = new 
ValidatorContainerInterfaceValidationContributor();
+
+                       new ValidatorRunner(new IValidationContributor[] 
{contributor}, new CachedValidationRegistry());
+               }
+
+
+
+               [Test]
+               public void AssertErrorsAreFoundInImplementedInterfaceMembers()
+               {
+                       Form1 model = new Form1();
+                       ErrorSummary errorsummary = contributor.IsValid(model, 
RunWhen.Everytime);
+                       
+                       // validation should fail because there are 
ValidateNonEmpty
+                       // and ValidateLength attributes mismatching on base 
interface
+                       // of Form1
+                       Assert.IsTrue(errorsummary.HasError);
+                       
+                       model.UserId = "a";
+                       model.PasswordConfirmation = model.Password = 
"12345678";
+                       errorsummary = contributor.IsValid(model, 
RunWhen.Everytime);
+                       Assert.IsFalse(errorsummary.HasError);
+                       
+               }
+
+               [Test]
+               public void HonorsRunWhen()
+               {
+                       Form1 model = new Form1();
+                       model.UserId = "a";
+                       model.PasswordConfirmation = model.Password = 
"12345678";
+
+                       model.MagicNumber = "i";
+                       ErrorSummary errorsummary = contributor.IsValid(model, 
RunWhen.Update);
+
+                       // validation should fail MagicNumber is invalid on 
update
+                       Assert.IsTrue(errorsummary.HasError);
+
+                       errorsummary = contributor.IsValid(model, 
RunWhen.Insert);
+                       Assert.IsFalse(errorsummary.HasError);
+
+                       model.MagicNumber = "1";
+                       errorsummary = contributor.IsValid(model, 
RunWhen.Update);
+                       Assert.IsFalse(errorsummary.HasError);
+                       
+               }
+
+       }

Directory: /trunk/Components/Validator/Castle.Components.Validator/Contibutors/
===============================================================================

File [added]: ValidatorContainerInterfaceValidationContributor.cs
Delta lines: +46 -0
===================================================================

--- 
trunk/Components/Validator/Castle.Components.Validator/DefaultValidationPerformer.cs
                                (rev 0)
+++ 
trunk/Components/Validator/Castle.Components.Validator/DefaultValidationPerformer.cs
        2008-09-01 19:47:27 UTC (rev 5303)
@@ -0,0 +1,47 @@
+// Copyright 2004-2008 Castle Project - http://www.castleproject.org/
+// 
+// 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.
+
+namespace Castle.Components.Validator
+{
+       using System.Collections.Generic;
+
+       /// <summary>
+       /// Default validation performer implementation
+       /// </summary>
+       public class DefaultValidationPerformer : IValidationPerformer {
+
+               bool IValidationPerformer.PerformValidation(object 
objectInstance, IEnumerable<IValidator> validators, 
IEnumerable<IValidationContributor> contributors, RunWhen runWhen, ErrorSummary 
summaryToPopulate) {
+                       foreach (IValidator validator in validators) {
+                               if (!validator.IsValid(objectInstance)) {
+                                       string name = validator.FriendlyName ?? 
validator.Name;
+                                       
summaryToPopulate.RegisterErrorMessage(name, validator.ErrorMessage);
+                               }
+                       }
+
+                       if(contributors != null)
+                               (this as 
IValidationPerformer).ExecuteContributors(objectInstance, contributors, 
summaryToPopulate, runWhen);
+
+                       bool isValid = !summaryToPopulate.HasError;
+                       return isValid;
+               }
+
+               void IValidationPerformer.ExecuteContributors(object 
objectInstance, IEnumerable<IValidationContributor> contributors, ErrorSummary 
summaryToPopulate, RunWhen runWhen) {
+                       foreach (IValidationContributor contributor in 
contributors) {
+                               ErrorSummary errors = 
contributor.IsValid(objectInstance, runWhen);
+                               summaryToPopulate.RegisterErrorsFrom(errors);
+                       }
+               }
+
+       }

Directory: 
/trunk/Components/Validator/Castle.Components.Validator.Tests/ContributorsTests/
===========================================================================================

File [added]: ValidatorContainerInterfaceContributorTestCase.cs
Delta lines: +0 -0
===================================================================


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Castle Project Commits" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/castle-project-commits?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to