Hi Tom,

a little more explanation of the *"... and do the component initialization
of this EditableValueHolder"* .

When you have an outputLabel in the RendererInterceptor, the
EditableValueHolder that goes with it, (the component referenced in the for
attribute) isn't initialized by ExtVal yet.  So if you ask the Required
attribute of it, it will return false, no matter what annotations there are
placed on the property in the backing bean. (except of course when you have
set the required attribute in the screen).

So if you want to know if the input field is required at that time you must
analyze the annotations.  The method
ExtValUtils.configureComponentWithMetaData() does just that so you can look
at the required property of the UIInput after the method executed.

Why RendererInterceptor and component initialization ??
Well the  RendererInterceptor has more functionality then just intercepting
the rendering of the component.  It adds extra functionality for encode and
decode.  So the component initializer is made to add information from the
annotations to the UIComponent just before rendering.  But the interceptor
is also responsible for coordination of the validation after a decode is
done.

In your case, a label has nothing to decode so there is no need to have this
separation.

Hopes this clarifies a bit.

regards
Rudy.

On 27 April 2010 21:25, Tom M. <mynewsgro...@arcor.de> wrote:

> Hi Gerhard,
>
> what I had already used before asking in the mailing list was:
> - ExtVal Core
> - BeanValidation (using JSR-303 annotations)
> - PropertyValidation (using basic code for custom cross validation
> annotation and provided out-of-the-box annotations such as @RequiredIf)
> - I did not want to use Trinidad since other component libraries are to be
> used in the project.
> - I have absolutely no validation code in the html templates (no validator
> tags, no required attribute, nothing of that at all), only using
> annotations
> and in consequence separating page structure/layout from validation rules
> in
> the domain objects (also founded in the organization of the development
> teams).
>
> This combination works perfect so far: validating the data according to the
> annotations, transforming messages und even generating a html maxlength
> attribute for @Size.max (nice!).
>
> Since I found it quite hard to understand how ExtVal is working in detail
> (even with your hints and links stated), I found a very simple solution
> that
> is working for me:
> - I asked myself why do I need a renderer interceptor AND a component
> initializer? From my point of view adding the '*' to the label text is more
> a question of rendering the label's text. And I could not figure out what
> Rudy meant with "... and do the component initialization of this
> EditableValueHolder" or what to do since I want to change the label not the
> input component.
> - By obmitting the component initializer, there is no need for meta data
> and
> a transformer...
> - I used some code I found in ExtVal classes, especially from ExtValUtils.
>
> So this is my simple (non standard?) solution which works for the @NotNull
> annotation:
>
>   public class RequiredLabelRendererInterceptor extends
> AbstractRendererInterceptor {
>
>        public static final String REQUIRED_SYMBOL = "*";
>
>        @Override
>        public void beforeEncodeBegin(FacesContext facesContext, UIComponent
> uiComponent, Renderer wrapped) throws IOException {
>
>                if (uiComponent instanceof HtmlOutputLabel) {
>
>                        HtmlOutputLabel labelComp = (HtmlOutputLabel)
> uiComponent;
>                        UIComponent inputComp = ...; // find by label
> attribute 'for'
>
>                        MetaDataExtractor extractor =
> createMetaDataExtractor();
>                        for (MetaDataEntry entry :
> extractor.extract(facesContext, inputComp).getMetaDataEntries()) {
>                                 checkAndHandleRequiredAttribute(labelComp,
> entry.getKey());
>                        }
>                }
>        }
>
>        private MetaDataExtractor createMetaDataExtractor() {
>                return ExtValContext.getContext().getFactoryFinder()
>
> .getFactory(FactoryNames.COMPONENT_META_DATA_EXTRACTOR_FACTORY,
> ComponentMetaDataExtractorFactory.class)
>                        .create();
>        }
>
>        private void checkAndHandleRequiredAttribute(HtmlOutputLabel
> labelComp, String key) {
>
>                if (NotNull.class.getName().equals(key)) {
>                        String label = (String) labelComp.getValue();
>                        if (!label.startsWith(REQUIRED_SYMBOL)) {
>
> labelComp.setValue(REQUIRED_SYMBOL+labelComp.getValue());
>                         }
>                 }
>        }
>   }
>
> A question to:
> >> e.g.: instead of using coreOutputLabel at:
> >>  ExtValUtils.configureComponentWithMetaData(facesContext,
> >> coreOutputLabel, metaDataResult); you could use the targetComponent
> >> (= the input component). after this call you can check if the
> >> targetComponent is required.
>
> Does that mean after configuring the component's attribute 'required' would
> be set? I didn't try that. Is there really a need for the component
> initialize and initiating the call via
> ExtValUtils.configureComponentWithMetaData()?
>
> For my already mentioned @RequiredExactlyOneOf cross validation annotation
> (which works fine regarding validation), I managed to render all labels
> belonging to the specified attributes via the renderer interceptor. But
> this
> only works if the annotation is defined at the attribute that occurs first
> in the html in order to manipulate the labels that are rendered later on.
> Possibly there would be a better solution to avoid this tight coupling by
> really using ExtVal's infrastructure!?
>
> Tom
>
>
>
> > -----Ursprüngliche Nachricht-----
> > Von: Gerhard Petracek [mailto:gerhard.petra...@gmail.com]
> > Gesendet: Dienstag, 27. April 2010 00:45
> > An: MyFaces Discussion
> > Betreff: Re: ExtVal: Rendering component with visual indication for
> > required fields
> >
> > hi thomas,
> >
> > basically you have 3 possibilities with extval:
> >  - use simple but dynamic validation, jpa based validation and
> > cross-validation -> use extval-core + extval-property-validation (+
> > your
> > custom constraints)
> >  - use bean-validation + some advanced extval mechanisms for it -> use
> > extval-core + extval-bean-validation + an impl. of bv (+ custom
> > bv-constraints)
> >  - create your own validation module(s)/concepts -> use extval-core +
> > your
> > own mechanisms on top of it
> >
> > for sure you can combine all modules. you just have to take care that
> > you
> > don't mix different types of constraints and their concepts (esp. in
> > combination with extval add-ons). however, i would suggest that you
> > just use
> > one validation-module of extval. and as soon as you are using it for a
> > real
> > app, you should also think about tweaking it (e.g. see [1])
> >
> > two (simple) sample setups for extval + bv are available at [2] and
> > [3].
> > a nice intro is available at [4].
> >
> > regards,
> > gerhard
> >
> > [1] http://wiki.apache.org/myfaces/Extensions/Validator/JSR303/Advanced
> > [2]
> > https://svn.apache.org/repos/asf/myfaces/extensions/validator/trunk/exa
> > mples/hello_bean-validation/
> > [3]
> > https://svn.apache.org/repos/asf/myfaces/extensions/validator/trunk/exa
> > mples/feature-set_02/
> > [4]
> > http://people.apache.org/~gpetracek/myfaces/extval/extval_chapter.html<http://people.apache.org/%7Egpetracek/myfaces/extval/extval_chapter.html>
>
>

Reply via email to