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

Reply via email to