I don't agree that most validation is on field level. Not in my case, nor in most of the projects I see here.

The pattern that I use a lot is that I create a new instance of an object on the first call, and then reuse that object through subsequent calls to that model. See wicket.contrib.data.model.hibernate.CachingHibernateObjectModel. For this case, or any case that you want to reuse your model objects/ don't depend on detachable objects, it is very convenient to have an easy rollback.

I implemented it as an alternative (non-default) validation strategy. I'll let it rest and keep it in the back of my head for a few days now.

Thanks for your reply,

Eelco


Phil Kulak wrote:

Another suggestion is to not even worry about it. Spring's validation
framework does a bind then validate, for example, and no one is up in
arms about that. Usually, you create a new object, validate it, and if
all is okay you send it to the database, otherwise you just let it get
garbage collected. Although, you do run into trouble with that in
wizards where state is held   in the session.

Since it's somewhat rare to actually care about rolling back the
binding (especially since most validation is single field), I would
prefer the callback method so that I only have to worry about it when
it's totally necessary. Then I also don't have to worry about Wicket
serializing my entire object graph.

-Phil

On 6/9/05, Eelco Hillenius <[EMAIL PROTECTED]> wrote:
Hmmm. I'm afraid I'm not there yet. What you (or at least I) usually
want to do is check the form's model object /after/ it is updated by the
form components. You generally want to check whether the new model
object is valid by comparing fields, checking against business rules,
etc. When the object is not valid, you want the updates to be rolled
back, so that you don't have an 'invalid' model object hanging around.
Now, here is where the fun starts. I am thinking about two possibilities
(both only executed when there are any form validators registered):

1. Automatic:
   a. clone the model
   b. update it
   c. execute form validation (on the updated model)
      i. validation succeeds: that's fine end validation and don't
update the model again
      ii. validation fails: roll back the model updates by setting the
cloned model back

2. Manual:
   Basically, this would mean introducing a few call back methods so
users can implement any strategy they want (btw they can anyway as they
allways can implement their own IFormValidationStrategy)
   a. before executing any formvalidator, call e.g. beforeUpdateModel.
Users can decide themselves whether they want to record the current model
   b. update the model
   c.execute form validation
      i. validation succeeds: call onValid
      ii. validation succeeds: call onInValid. Users can decide to
rollback to their recorded model

The advantage of 1. is that it hides a lot of details for you, and that
you don't have to write repetative code. The disadvantage is that there
will be cloning (using serialization) going on when you might not want that.

The advantage of 2. is that it is more flexible (allows for
optimalisations/ custom cloning). The disadvantage is that you have to
do more - allways - as a user, you have to know more about how the form
works internally, and there are two methods more added to the API.

So... dear readers, what do you want? Any other suggestions?

Eelco


Cameron Braid wrote:

This looks great.



-----Original Message-----
From: [EMAIL PROTECTED] [mailto:wicket-develop-
[EMAIL PROTECTED] On Behalf Of Eelco Hillenius
Sent: Thursday, 9 June 2005 11:04 PM
To: Wicket Develop List
Subject: [Wicket-develop] propose: add IFormValidator and
AbstractFormValidator

I would like to introduce IFormValidator and AbstractFormValidator
specific for validating Forms.

Currently we add multiple - reusable - validations to fields, but when
we have specific validations on a form level, we have to know about the
internals of the Form (which steps does it take in validation), and/ or
have to write a custom validation strategy (which certainly is not
straightforward to include form level validation). Because of the form
not supporting validation on a form level with an easy mechanism such as
there is for the form components, Wicket encourages to write
non-reusable, monolithic pieces of code, e.g. in the onSubmit method,
with all kinds of hacks like reversing the model updates and manually
setting error messages when something goes wrong. Note 'encourages'
here, as it *is* possible to do it neat, but that's just not what I see
in projects here, and it certainly isn't obvious how that should be done.

The way it must currently be done (though I just found a few bugs
preventing even this to work) using an example where I have a validate
method on object Product which returns a list of non-wicket validation
messages:

      public IFormValidationStrategy getValidationStrategy()
      {
          final IFormValidationStrategy defaultStategy =
super.getValidationStrategy();
          IFormValidationStrategy productStategy = new
IFormValidationStrategy()
          {
              public void validate(Form form)
              {
                  defaultStategy.validate(form);
                  Product product = (Product)getModelObject();
                  List msgs = product.validate();
                  if (msgs != null && (!msgs.isEmpty()))
                  {
                      for (Iterator i = msgs.iterator(); i.hasNext();)
                      {
                          ValidationMessage msg =
(ValidationMessage)i.next();
                          Localizer localizer = form.getLocalizer();
                          String message =
localizer.getString(msg.getMessageKeyKey(), form);
                          form.error(message);
                      }
                  }
              }
          };
          return productStategy;
      }

Where getValidationStrategy overrides the super method (which means that
in order to validate a form you allways have to subclass)

In the new way, this could be:

class ProductFormValidator extends AbstractFormValidator
{
  public void onValidate()
  {
      Product product = (Product)getForm().getModelObject();
      List msgs = product.validate();
      if (msgs != null && (!msgs.isEmpty()))
      {
          for (Iterator i = msgs.iterator(); i.hasNext();)
          {
              ValidationMessage msg = (ValidationMessage)i.next();
              error(msg.getMessageKeyKey());
          }
      }
  }
}

and just add(new ProductFormValidator()); to your form.

Not only is this shorter/ more obvious (same mechanism as FormFields) it
also supports reuse better.

Any objections? And should this be put in the 1.0 branch as well?

Eelco




-------------------------------------------------------
This SF.Net email is sponsored by: NEC IT Guy Games.  How far can you
shotput
a projector? How fast can you ride your desk chair down the office luge
track?
If you want to score the big prize, get to know the little guy.
Play to win an NEC 61" plasma display: http://www.necitguy.com/?r=20
_______________________________________________
Wicket-develop mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/wicket-develop



-------------------------------------------------------
This SF.Net email is sponsored by: NEC IT Guy Games.  How far can you shotput
a projector? How fast can you ride your desk chair down the office luge track?
If you want to score the big prize, get to know the little guy.
Play to win an NEC 61" plasma display: http://www.necitguy.com/?r=20
_______________________________________________
Wicket-develop mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/wicket-develop



-------------------------------------------------------
This SF.Net email is sponsored by: NEC IT Guy Games.  How far can you shotput
a projector? How fast can you ride your desk chair down the office luge track?
If you want to score the big prize, get to know the little guy.
Play to win an NEC 61" plasma display: http://www.necitguy.com/?r=20
_______________________________________________
Wicket-develop mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/wicket-develop



-------------------------------------------------------
This SF.Net email is sponsored by: NEC IT Guy Games.  How far can you shotput
a projector? How fast can you ride your desk chair down the office luge track?
If you want to score the big prize, get to know the little guy. Play to win an NEC 61" plasma display: http://www.necitguy.com/?r _______________________________________________
Wicket-develop mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/wicket-develop



-------------------------------------------------------
This SF.Net email is sponsored by: NEC IT Guy Games.  How far can you shotput
a projector? How fast can you ride your desk chair down the office luge track?
If you want to score the big prize, get to know the little guy. Play to win an NEC 61" plasma display: http://www.necitguy.com/?r=20
_______________________________________________
Wicket-develop mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/wicket-develop

Reply via email to