Craig McClanahan wrote:


On 4/4/06, *Richard Wallace* <[EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]>> wrote:

    Mike Kienenberger wrote:
    >> Mike Kienenberger wrote:
    >>
    >>> It is possible to simulate a custom required validator
    >>> (see
    http://wiki.apache.org/myfaces/OptionalValidationFramework), but
    >>> it isn't going to help you in any way
    >>>
    >
    > On 4/4/06, Richard Wallace < [EMAIL PROTECTED]
    <mailto:[EMAIL PROTECTED]>> wrote:
    >
    >> How so?
    >>
    >
    > No matter what you do, you're still going to have to write java code
    > that consolidates messages to display them.   It's just as easy to
    > consolidate FacesMessages as it is to consolidate some custom data
    > type that you'd conceivably generate in a custom required validator.
    > And the required validator controller component is slow due to the
    > fact that it has to walk the entire component tree a couple times in
    > order to fire the validation and then adjust the component
    validation
    > state.
    >
    I guess you're right about the FacesMessages.  The only thing I'm not
    sure about is how to differentiate the messages I would want to
    consolidate from messages that I want to display as is.


Note that your use cases for "consolidation" are probably on the 20% side of the 80/20 rule :-).

    Another thing that I find a little annoying is that you either have
    messages tied to a component or global to the page.  You can't have
    messages tied to a form.


Don't feel limited to using the standard message and messages components. If the messages themselves are tied to individual input components, writing a version of the <h:messages> renderer that picks out only the messages for components nested inside a particular form is pretty easy.

Well sure, for someone as familiar with it all as you are it's probably no big deal at all. Now that I've got the general approach from the description you give down below even I could probably handle it.

    And, of course, one of the biggest pains is customizing messages on a
    per component basis.  What I want is to be able to set the message
    to be
    displayed for a specific instance rather than for all types of that
    component across the application.

    I don't know, maybe the solution to my problem is to just have the
    validation done in my backing bean.  The thing is that that seems
    to be
    the solution to a lot of my validation use cases.  In fact, I don't
    think I've run into a single real world use case where the
    standard JSF
    validation works.


That (validation in the backing bean) seems like the right answer for *application* defined vaidations that cross multiple components, which includes the use case you are describing. JSF's validation framework is focused on single component sorts of validations.

Alright, that makes sense then. I was thinking that the validation framework in JSF was meant to be a general purpose, handle everything validation related framework.

    >>> Instead, you want to generate standard required validation
    messages,
    >>> then create a custom renderer for the messages component that
    >>> consolidates each of these messages into something else,
    probably by a
    >>> specific id pattern.    I also think you'd be better off
    extending the
    >>> existing messages renderer than creating it yourself.
    >>>
    >
    >
    >> Sounds like a hack to get around a poor validation system.
    >>
    >
    > In this case, it's not the validation system that's the
    problem.  It's
    > the displaying of validation errors.   The system logged them as
    > FacesMessages, so you simply need to change how they're displayed.
    > The messages component renderer is the place to change that.
    >
    >
    But how do you differentiate the messages to be consolidated from
    those
    that shouldn't be?


Here's a strategy for dealing with "all the errors related to components in a particular form":

* Build a variant of the standard <h:messages> component that takes some
  sort of reference to the containing form component.

* At rendering time for this component, start doing a recursive tree search of
  the form component's children.

* For each component that might have been a source of validation errors (simplest test is "instanceof EditableValueHolder" but you might have special cases too), call FacesContext.getMessages(String clientId) to grab any messages assigned
  to that client.

* Consolidate all the messages accumulated during this tree search in any manner
  that you desire.

That's a great run down. I'll give this a try sometime soon I think. The only thing I'm not sure about with that is how could you do global messages, form specific messages, and component specific messages. That's probably not a very likely scenario so it's no big deal if I can't have my cake and eat it too.
    >>  Is there any
    >> way to completely replace the JSF validation process with
    something more
    >> flexible?  I mean, honestly, this is a pretty simple use case
    that is
    >> extremely difficult to implement.
    >>
    >
    > Sure.  JSF is completely pluggable, so you could create your own
    > lifecycle factory and create a lifecycle that skips or replaces the
    > process validation phase.  However, coming up with something "more
    > flexible" is going to be a task.   You're also going to probably
    break
    > components that expect a processValidation phase to occur.   It'd be
    > interesting to hear what you have in mind.   I've yet to see any
    > decent validation implementations.   Before you get too far into
    it,
    > take a look at subforms (talked about more below) as they solve some
    > of the weaknesses of JSF validation.
    >
    >
    I'm not sure of exactly what I'd do.  At the moment I'm thinking that
    the three things that I'd really like to see are more customizable
    messages, required being a child element rather than a component
    attribute, and for messages tied to forms in addition to global and
    component messages.  I was probably being a little extreme when I said
    "completely replace".  I was just on a bit of a rant cause I've
    spent to
    much time banging my head against the wall trying to figure out
    the best
    way of doing things with JSF validation.



As an example of the flexibility JSF does provide (but doesn't deal directly with your particular issue), consider the fact that Shale lets you use Commons Validator to implement client side (as well as server side) validation on standard JSF components.
One of the big things that does really bother me is defining custom messages on a per component basis. With everything that I've learned from this thread I think I understand how to deal with the issues I've had up until now. But not being able to define per component validation messages just seems like a fundamental shortcoming. I'm glad it's being addressed in the tomahawk validators by adding a message attribute: http://issues.apache.org/jira/browse/TOMAHAWK-169?rc=1

Is the next step with that just extending the standard JSF validators to allow them to have the message attribute? I'm also wondering, can you set custom required messages if you use the tomahawk extensions?


    >> I have to wonder why the required
    >> attribute is treated as a special case as well.
    >>
    >
    > I think having the required attribute as a special case was an
    example
    > of an implementation detail influencing the spec.   I'm sure the
    idea
    > is that if there's no value, then there's no point in validating
    it.
    > But unfortunately, it's an ugly special-case that you have to
    > constantly work around since it's not treated as a "real" validator
> but is instead implemented separately as part of every component.

This was done primarily for usability reasons. The fundamental philosophy was "there is no point in firing validators when there is no data to validate" because a typical validator author would assume something would be there, and inadvertently trigger NPEs. We originally had the required validation as a standard Validator implementation, but dealing with this issue would have required some additional hack on the API that lets a validator say "not only is there an error here, but don't bother doing any more validations on it." Much cleaner to have a boolean flag that says whether this component is required or not.

Also, for any component that extends UIInput, you don't actually have to do anything to implement this check in your custom component -- it's all done for you in the base class.
    >
    >
    >> Validation in JSF seems
    >> to be just a mess.  I really like JSF overall, but anytime I start
    >> thinking about doing any validation I have to take a couple of
    shots of
    >> whiskey and bite down on something hard to try and forget about
    the pain.
    >>
    >
    > I agree :)   It's why I tried to write the
    OptionalValidationFramework :)
    >
    > However, I think using the MyFaces sandbox subform component or the
    > ADFFaces subform component is probably a better solution than OVF.
    > For one thing, OVF doesn't work well with vanilla JSF 1.1 (requires
    > facelets + 1.1 or requires 1.2).
    >
    > I don't think subform components will help with this specific
    > situation, but they'll be helpful in other partial validation
    > situations.
    >
    The subform components definitely look like a good step.  It's
    definitely one thing that I should have included in my list of
    wants for
    the JSF validation system.

    Rich


Craig


Reply via email to