[jsr-314-open] [NEW] <f:ajax> and <f:validateBean> - consistent wrapping solution needed?

Pete Muir pmuir at REDHAT.COM
Tue Mar 10 14:15:38 EDT 2009


Hi Andy,

We did previously discuss this somewhere in the archive... (around
30th Oct)

On 10 Mar 2009, at 14:32, Andy Schwartz wrote:

> Gang -
>
> In JSF 2.0 we are introducing two core tags that wrap/enhance
> component subtrees: f:ajax and f:validateBean.
>
> f:ajax is used to enable Ajax behavior for a subtree, eg:
>
>> <h:panelGroup>
>>  <!-- Turn on Ajax for the two input texts -->
>>  <f:ajax event="valueChange">
>>      <h:inputText value="foo"/>
>>      <h:inputText value="bar"/>
>>  </f:ajax>
>> </h:panelGroup>
>
>
> f:validateBean is used to enable bean validation for a subtree, eg:
>
>> <h:panelGroup>
>>  <!-- Turn on bean validation for the two input texts -->
>>  <f:validateBean validationGroups="Group1, Group2"/>
>>      <h:inputText value="foo"/>
>>      <h:inputText value="bar"/>
>>  </f:validateBean>
>> </h:panelGroup>

Actually, this isn't right. It would look like

<h:panelGroup>
  <!-- Turn on bean validation for the two input texts -->
      <f:validateBean validationGroups="Group1, Group2"/>
      <h:inputText value="foo"/>
      <h:inputText value="bar"/>
</h:panelGroup>

Which would enable validation for the whole panel group.

Having looked back at the previous messages, I think we went for the
nested element enables validation for the panel group on your advice
that this would unify us with f:ajax...

But this seems to be missing from the final Ajax design?

>>
>
> Of course, both tags can also be used in their nested form to enable
> Ajax/bean validation on a single component.



>
>
> We currently use different implementation strategies for the
> "wrapping" behavior.
>
> f:ajax uses a handler execution-time solution.  AjaxHandler
> maintains a stack that keeps track of the current nested state of
> <f:ajax> tags.  Before apply child handlers, AjaxHandler pushes the
> current Ajax-related info onto this stack.  When child/descendent
> handlers are applied, ComponentTagHandlerDelegateImpl checks this
> stack to get at the current Ajax-related state and performs the
> necessary work to wire up an AjaxBehavior to the component.
> Finally, after child handlers have been processed, AjaxHandler pops
> the stack, and we're done.
>
> The end result of the f:ajax solution is that once handlers have
> finished executing, we have a fully configured component tree.  No
> further processing is necessary to apply "inherited" Ajax behavior.
>
> f:validateBean uses a solution which is split between tag/handler
> execution-time, validation-time and render-time.
> BeanValidatorHandler/ValidatorTagHandlerDelegateImpl set up well
> known properties on the parent component's attribute map (eg.
> BeanValidator.VALIDATION_GROUPS_KEY,
> UIInput.DEFAULT_VALIDATOR_IDS_KEY).  These are used during later
> lifecycle phases (eg. BeanValidator.validate(), UIInput.encodeEnd())
> to determine which inherited validators to apply and how these
> validators should be configured (eg. what validation groups to use).
>
> The end result of the f:validateBean solution is that the handlers
> only do part of the job - we need to do additional work during later
> lifecycle phases to take advantage of the information that has been
> stored away by the handlers.
>
> While these two different strategies may at first seem like
> implementation details, and thus not especially significant, the
> choice of implementation does have impact on both our API and on
> spec'ed behavior (or, on behavior that should be defined by the spec).
>
> In terms of API, for f:validateBean the choice of implementation
> leaks through a bit into the API in the form of the property keys
> that are used to communicate between the handler implementations and
> the component/validator implementations.
>
> In terms of behavior, the different implementation strategies and up
> with subtly different results which may cause confusion.
>
> For example, in the following f:ajax case:
>
>> <h:panelGroup>
>>
>>  <!-- Turn Ajax on for this one -->
>>  <f:ajax event="valueChange">
>>      <h:inputText value="foo"/>
>>  </f:ajax>
>>
>>  <!-- But not for this one -->
>>  <h:inputText value="bar"/>
>>
>> </h:panelGroup>
>
>
> This should work as expected.  That is, Ajax should be enabled for
> the "foo" inputText, but not for the "bar" input text.
>
> In a similar f:validateBean case:
>
>> <h:panelGroup>
>>
>>  <!-- Turn bean validation on for this one -->
>>  <f:validateBean validationGroups="Group1, Group2"/>
>>      <h:inputText value="foor"/>
>>  </f:validateBean>
>>
>>  <!-- But not for this one -->
>>  <h:inputText value="bar"/>
>>
>> </h:panelGroup>
>
>
> Unless I am missing something in the spec/implementation, I believe
> that the validation-related properties are going to end up being
> attached to the parent panelGroup when the BeanValidatorHandler is
> applied.  Which, if I understand this correctly, means that the
> validation will be applied to both the "foo" and the "bar"
> inputText.  If this is the case, this is definitely not the desired
> behavior.
>
> I suspect that similar problems would arise when we've got multiple
> <f:validateBean> under a single parent, eg:
>
>> <h:panelGroup>
>>
>>  <!-- Turn on Group1 validation for this one -->
>>  <f:validateBean validationGroups="Group1"/>
>>      <h:inputText value="foo"/>
>>  </f:validateBean>
>>
>>  <!-- Turn on Group2 validation for this one -->
>>  <f:validateBean validationGroups="Group2"/>
>>      <h:inputText value="bar"/>
>>  <f:validateBean/>
>>
>> </h:panelGroup>
>
>
> Though I haven't had a chance to test this out - just based on code
> inspection seems like this would be a problem.  (Though our <f:ajax>
> implementation strategy handles this case just fine.)
>
> Since there may be other subtle inconsistencies, it would make sense
> to try to unify our implementation strategies across these two core
> tags.  Of course, I am biased towards the <f:ajax> approach.  Seems
> to have better behavior in terms of targeting only the wrapped
> subtrees, has less exposure in the public API, and also just seems
> cleaner to me to produce a fully configured component tree as a
> result of handler execution.
>
> Looking at the code, I didn't notice anything that would make it
> difficult to re-factor the <f:validateBean> code  to use a handler-
> time strategy like <f:ajax>.  I think our users would benefit from
> the consistency.  Any thoughts on whether we should/can go this
> route?  Did I miss anything in the <f:validteBean> behavior that
> would prevent us from using a handler-time solution?
>
> Andy

--
Pete Muir
http://www.seamframework.org
http://in.relation.to/Bloggers/Pete






More information about the jsr-314-open-mirror mailing list