Re: Object validation

From: Fabricio Voznika (fabricio.voznik..artmouth.EDU)
Date: Mon Sep 08 2003 - 12:27:54 EDT

  • Next message: Mike Kienenberger: "class generator not substituting formatVariableName correctly with custom supertemplate"

    Hi all,

        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.
        The downside of having only one method is that the user will always
    have to test the PersistenceState, to avoid silly validations when
    they're not needed.
        What is the general feeling?

        Now with the ValidationResult. What information is needed to be
    stored in it?

    * The source of the error:
    Usually the pair Object, Property should be enough to identify the
    source. Where property could be null to indicate a general error in the
    object, i.e., a Person cannot be created between 8-10pm.
    The object could also be null in case we want to use the same Validation
    mechanism to flag other errors in the application and use a common error
    handling code.
    I could also see that some errors may be generated by a set of
    properties (start date later than end date), is it something we want to
    track or not to keep it simple? Are there other ways to identify the
    source other than Object, Property pairs?

    * 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.

    Having this in mind I suggest creating these classes:

    Error : Interface

    ----
    getErrorString() : String  // Shows error in a nice string format
    getSource() : Object
    getProperty() : String  // javaBeanStylePropertyName
    getError() : Object  // Error object. Usually a String but it could be 
    anything
    

    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

    ValidationException : Exception ---- getValidationResult() : ValidationResult

    ValidationResult will be passed as parameter to validateForXXX and will be accessible via the ValidationException.

    Will it work for everyone?

    Thanks, Fabricio.

    Dirk Olmes wrote:

    >>>>Yeah, all this logic can exist as a part of >>>>DataContext.commitChanges(). Now, do we want to split >>>>"validateForSave" >>>>into separate "validateForInsert", "validateForDelete", etc., just >>>>like >>>>EOF does? I don't think it matters either way. I vote for a single >>>>method since object internally can determine its state. Maybe instead >>>>of "DataObject.validateForSave" call it >>>>"DataObject.validateForCommit"? >>>> >>>> >>>I've been in situations where I had to perform certain validation >>>steps only >>>for newly created objects. So I'd vote for separate methods just like EOF >>>does, that shouldn't be hard to implement either. >>> >>> >>Doesn't matter to me. >> >> >> >>>The original idea was to use >>>DataContext events just for that, maybe that's still a good idea? >>> >>> >>> >>If I understand correctly this meant that event listeners (e.g. >>DataObjects themselves) would perform the validation. But event >>listeners logically are simply "consumers" of events, not delegates. >> >> > >The DataObjects really should be performing validation. The original idea >was to register an object as event listener who triggers the appropriate >method(s) in the DataObjects in return, just like what's implemented in >ContextCommitObserver. > > > >>So there is no clean way for them to interrupt the flow that caused the >>event. >> >> > >Throwing an exception should "bubble through" all the way to >DataContext.commit in the current implementation, since that's single-threaded. > > > >>And in general they should be unaware of the event dispatch >>mechanism. >> >> > >Agreed. > > > >>For instance, what if we'll make it multithreaded, and there >>will be no way to throw an exception from "validate" thread to stop >>commit, since "commit" is done in a different thread. >>Validation procedure on the other hand should interrupt the flow in >>case of errors and provide the user with detailed information about the >>failures. >> >> > >Generally true. But we won't be able to use the multithreaded dispatch >mechanism for anything in cayenne that has influence on the flow of control. Any >validation methods, any updates to the object graph simply can't be >multithreaded. The only sensible use for multithreaded events I see is cross VM >notification. > >-dirk > > >



    This archive was generated by hypermail 2.0.0 : Mon Sep 08 2003 - 12:27:17 EDT