Dan, I think that would be sensible - this discussion is hard to read
and a bit confusing in places.
I think this is an important topic going forward, and this looks like
it could form the starting point for a discussion.
On 15 Jul 2009, at 00:56, Dan Allen wrote:
>From the jsr-314-comments mailbox comes this discussion between
myself and Mathias Werliz about inter-component validation.
Unfortunately the discussion progressed outside of the mailinglist,
so the post below is the aggregate of the individual messages. If
there is confusion we can summarize the discussion up to this point
and continue the discussion on each individual point.
---------- Forwarded message ----------
From: Dan Allen <dan.j.allen(a)gmail.com>
Date: Thu, Jul 9, 2009 at 2:09 PM
Subject: Re: inter-component and form-level validation
To: "Werlitz, Mathias" <werlitz(a)adesso.de>
Cc: jsr-314-comments(a)jcp.org
On Thu, Jul 9, 2009 at 11:36 AM, Werlitz, Mathias
<werlitz(a)adesso.de> wrote:
Sorry for the late response. I’m very busy on a customer project at
the moment, analysing JSF 1.2 (view state) and Facelets memory
consumption on IBM Portal 6.1.
I agree that there are two basic approaches to solve multiple-
field / form-validation:
1. model based validation after the update model phase and
2. validating the converted values of multiple components
In both cases there should be an easy way to assign the proper
validation message to the originating input component or group of
input components. With complex forms including inputs within naming
containers like <h:dataTable> this may become quite complicated.
Flattening the properties of the object graph for JSR-303 model
validation does not seem to be a good idea in this case.
I realize that JSR-303 isn't going cover every case. I must admit to
still being the fence on how to best handle the situation you are
citing...meaning can I do it comfortably with JSR-303 or not? I
think a solid use case would help us test the limits.
Well I simplified a test case – I’m unsure that this is easily done
with JSR-303. Image a form with a master date and several additional
dates. The number of the additional dates is dynamic – will be
configured by the user (added and removed) or determined by the
server.
For simplicity there is only one multi-field validation rule: all
additional dates must be after the master date. The view would look
something like this (note: the list of additional dates is a list of
a custom bean that stores the date and maybe additional data for
every entry):
<h:input id=”masterDate” value=”mybean.masterDate” />
<h:datatable value=”mybean.myAdditionalDates” var=”item” >
<h:input id=”addtionalDate” value=”item.additionalDate” />
</h:datatable>
This could be done with JSR-303. You can have a validation
annotation on the array (or List) property holding the "after" dates
and say that they must come after the master date property. But
again, the limitation is that it has to happen after update model
values.
Earlier when I said you have to flatted your model, I didn't mean
you couldn't use collections. You just can't easily validate a
property on one class against a property on another.
But pointing that aside, you could still accomplish w/ a regular JSF
validator if all conversions happened before the validation phase.
Then you just do something like:
<h:input id="additionalDate" value="#{item.additionalDate}">
<x:validateAfter id="masterDate"/>
</h:input>
One downside of the model based validation is that the whole
validation process is split up into two phases. That means the user
may get the error messages in two bunches: first the errors of the
validation phase and later the model errors. This can be quite
confusing.
The reality is, there are two validation phases in input-based
applications. You simply cannot test some business validations if
you don't have correct data to start with. I think the real point is
to make sure that all input validation is handled together...and
that business validation is really business validation. Having one
date before another I agree is likely an input validation, not a
business validation.
Yes, that’s the point. At the moment JSF does make it very hard to
do the input validation altogether.
There will likely always be two steps. The question is, can we get
those two steps right?
To emphasize why there must be two validation phases, consider this
case. You walk into an ice cream store and the employee asks you
which flavor of ice cream you want. You say you want pizza. They
say, "Sir, we don't have pizza, you have to pick and ice cream."
Then you say that you want Heath ice cream. The employee says,
sorry, we don't have that in stock. So the first is an input
validation, the second is business. The employee couldn't have told
you they don't have Heath ice cream in stock because the employee
doesn't know what you want. It's not really that confusing.
I agree with you, but in fact there are three steps where messages
could be associated with an input field (convert, validation,
business rules) and every step depends on the previous one.
Well, one common requirement of our customers is: Display error
messages as early as possible. Separating the validation into two
phases makes this hard. Using good old Struts this example is no
problem at all.
That's because Struts effectively updated the model and then
validated, moving all validation to the later phase. In JSF there is
an understanding that values won't get assigned to the model unless
they are valid syntax or type. You could throw that out the window
and do all your validations after the update model values phase and
get the same result. So we are questioning the fundamental guarantee
of JSF (which, by the way, may need to be questioned).
Well I think you got me wrong. The point is that in Struts you are
able to store all the form data (as strings) in a form bean. You are
responsible to make your own conversation. But because of that you
are able to validate all input data including multi-field
validation. On success you proceed to assign the values on your own
to the real model.
That’s not perfect. The only problem with JSF is that you don’t have
this intermediate view on the form data where all converted values
of the form is available altogether before deciding to move on to
the update model phase.
I think we are saying the same thing. JSF applies the values
directly to the model by attempting to convert each value. Now, you
could copy all properties to a model with string properties and
essentially coerce JSF into skipping validation so that you can
handle it yourself, but that really defeats a large goal of JSF.
I like your idea of dividing converting and validation. I think
JSR-303 model based validation is not sufficient. In the discussion
with my college we had a similar idea as a workaround for JSF 1.2:
We thought about a special custom validator added to all relevant
input components that collects all converted input data from the
components and the corresponding client ids/component instances.
This also works fine with <h:dataTable>. The data could be collected
with a Map or special validation-model bean. At the end of the
validation phase another special form/multi-field validator
(possible phase listener) is called with the collected data and
invokes the validation logic. This way you get all converted data,
components/client ids, the real model data is not touched at all and
the whole validation is processed in one phase.
It seems blatantly obvious to me that all conversion should happen
before any validation occurs. I think the current situation is
ridiculous and it's the root of why multi-field validation is so
screwed up to begin with.
See my previous comment… The question is: when this will change. JSF
2.0 would be the right version. But I guess it’s already too late
for such a fundamental change in the lifecycle – separating
conversation and validation.
It won't be JSF 2.0. Hopefully JSF 2.1 or sooner.
-Dan
--
Dan Allen
Senior Software Engineer, Red Hat | Author of Seam in Action
http://mojavelinux.com
http://mojavelinux.com/seaminaction
http://in.relation.to/Bloggers/Dan
NOTE: While I make a strong effort to keep up with my email on a daily
basis, personal or other work matters can sometimes keep me away
from my email. If you contact me, but don't hear back for more than
a week,
it is very likely that I am excessively backlogged or the message was
caught in the spam filters. Please don't hesitate to resend a
message if
you feel that it did not reach my attention.
--
Dan Allen
Senior Software Engineer, Red Hat | Author of Seam in Action
Registered Linux User #231597
http://mojavelinux.com
http://mojavelinux.com/seaminaction
http://in.relation.to/Bloggers/Dan