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
-~----------~----~----~----~------~----~------~--~---