1 // Copyright 2004-2007 Castle Project - http://www.castleproject.org/
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle
.ActiveRecord
18 using System
.Collections
;
20 using Castle
.ActiveRecord
.Framework
;
21 using Castle
.ActiveRecord
.Framework
.Internal
;
22 using Castle
.Components
.Validator
;
25 /// Extends <see cref="ActiveRecordBase"/> adding automatic validation support.
29 /// public class Customer : ActiveRecordBase
33 /// [Property, ValidateNotEmpty]
36 /// get { return _name; }
37 /// set { _name = value; }
40 /// [Property, ValidateNotEmpty, ValidateEmail]
43 /// get { return _email; }
44 /// set { _email = value; }
49 public abstract class ActiveRecordValidationBase
: ActiveRecordBase
52 private ValidatorRunner __runner
= new ValidatorRunner(ActiveRecordModelBuilder
.ValidatorRegistry
);
54 [System
.Xml
.Serialization
.XmlIgnore
]
55 private IDictionary __failedProperties
;
58 /// Constructs an ActiveRecordValidationBase
60 public ActiveRecordValidationBase()
65 /// Performs the fields validation. Returns true if no
66 /// validation error was found.
68 /// <returns></returns>
69 public virtual bool IsValid()
71 return IsValid(RunWhen
.Everytime
);
75 /// Performs the fields validation for the specified action.
77 /// <param name="runWhen">Use validators appropriate to the action being performed.</param>
78 /// <returns>True if no validation error was found</returns>
79 public virtual bool IsValid(RunWhen runWhen
)
81 __failedProperties
= new Hashtable();
85 __runner
= new ValidatorRunner(ActiveRecordModelBuilder
.ValidatorRegistry
);
88 bool returnValue
= __runner
.IsValid(this, runWhen
);
92 Type type
= GetType();
93 ErrorSummary summary
= __runner
.GetErrorSummary(this);
95 foreach(string property
in summary
.InvalidProperties
)
97 __failedProperties
.Add(type
.GetProperty(property
), new ArrayList(summary
.GetErrorsForProperty(property
)));
105 /// Returns a list of current validation errors messages.
107 public virtual String
[] ValidationErrorMessages
111 if (__runner
== null)
113 __runner
= new ValidatorRunner(ActiveRecordModelBuilder
.ValidatorRegistry
);
116 if (__runner
.GetErrorSummary(this) == null)
121 return __runner
.GetErrorSummary(this).ErrorMessages
;
126 /// Maps a specific PropertyInfo to a list of
127 /// error messages. Useful for frameworks.
129 [System
.Xml
.Serialization
.XmlIgnore
]
130 public virtual IDictionary PropertiesValidationErrorMessage
132 get { return __failedProperties; }
136 /// Override the base hook to call validators required for create.
138 /// <param name="state">The current state of the object</param>
139 /// <returns>Returns true if the state has changed otherwise false</returns>
140 protected internal override bool BeforeSave(IDictionary state
)
142 if (!IsValid(RunWhen
.Insert
))
147 return base.BeforeSave(state
);
151 /// Override the base hook to call validators required for update.
153 /// <param name="id">object id</param>
154 /// <param name="previousState">The previous state of the object</param>
155 /// <param name="currentState">The current state of the object</param>
156 /// <param name="types">Property types</param>
157 /// <returns>Returns true if the state has changed otherwise false</returns>
158 protected internal override bool OnFlushDirty(object id
, IDictionary previousState
, IDictionary currentState
, NHibernate
.Type
.IType
[] types
)
160 if (!IsValid(RunWhen
.Update
))
165 return base.OnFlushDirty(id
, previousState
, currentState
, types
);
169 /// Throws an exception explaining why the save or update
170 /// cannot be executed when fields are not ok to pass.
173 /// You can override this method to declare a better behavior.
175 protected virtual void OnNotValid()
177 throw new ValidationException( "Can't save or update as there is one (or more) field that has not passed the validation test", ValidationErrorMessages
);