Hi Fabricio,
On Monday, September 8, 2003, at 12:27 PM, Fabricio Voznika wrote:
> There is a problem with the 3 methods solution. Pretty close to
> 99% of the times, exactly the same validation will be performed when
> the object is created and updated. Having 3 method will create the
> need to add another method with common validation and call it from
> validateForInsert and validateForUpdate (or make one call the other).
> There could be 2 methods (validateForInsertAndUpdate and
> validateForDelete), but I don't like it because it mixes both
> solutions.
As I see it, the exception should not be thrown till the end of all
validation to avoid unneeded try/catch everywhere in the code...So we
need some API for easy chaining of validation info... Here is how I see
it work (with a common method in addition to the 3 state-specific
methods).
DataObject API:
public void validateForSave(ValidationResult); // common validation
public void validateForInsert(ValidationResult); // noop, for
subclassing only
public void validateForUpdate(ValidationResult); // noop, for
subclassing only
public void validateForDelete(ValidationResult); // noop, for
subclassing only
flow of events in DataContext on commit:
ValidationResult validation = new ValidationResult();
while('has more objects") {
nextDataObject. validateForSave(validation);
// check persistence state and call appropriate method
nextDataObject. validateForXXX(validation);
}
// if validation failed
throw new ValidationException(validation);
Notes on the API above:
1. validateForXXX all take a shared ValidationResult and throw no
exceptions by themselves
2. All methods but validateForSave do nothing and exist for
subclassing only
> * The error message:
> Usually a String with the error message will do it. Is there a need
> for more complicated messages, with formatting (like font properties,
> etc)? One could say it's the presentation layer problem, but the
> presentation layer might not have enough information to show an
> important word in bold. This is very implementation dependent
I can't think of any extra info to capture. You got it all. Though I'd
say such things like formatting shouldn't be a part of this package
(also since we have failure codes, a caller can always redefine
messages). Things like localization might be a nice addition (we may
ignore it initially I guess, since the rest of the exceptions are not
localized either).
Few notes on the naming:
> Error : Interface
I suggest something other than Error for the interface name (say
ValidationFailure). Error is to close to "java.lang.Error" ( especially
bad since "java.lang" is imported by default).
> ----
> getErrorString() : String // Shows error in a nice string format
How about "getDescription"? We can make it localizable at some
point......
> getError() : Object // Error object. Usually a String but it could be
> anything
Maybe we can call it something like "getCode()" and define a few codes
for known errors (NULL_NOT_ALLOWED, MAX_LENGTH_EXCEEDED, etc.). Users
can define their own as well.
> ValidationResult : Class
> ----
> addError(Error)
> addError(Object, String, Object) // Create default error and call
> addError(Error)
> getErrors() : List
> getErrorsFor(Object) : List
> getErrorsFor(Object, Property) : List
> hasErrors() : boolean
> hasErrorsFor(Object) : boolean
> hasErrorsFor(Object, Property) : boolean
s/Error/Failure/g - to be consistent with the interface above.
> ValidationException : Exception
> ----
> getValidationResult() : ValidationResult
If the call to validation is plugged in to commitChanges (I assume it
will be), then I suggest extending a RuntimeException, so that we do
not have to change the existing DataContext paradigms.
Andrus
This archive was generated by hypermail 2.0.0 : Tue Sep 09 2003 - 01:03:37 EDT