2 Replies Latest reply on Mar 30, 2011 7:34 PM by ghilton

    graphValidator – cross field validation and payload

    ghilton

      It appears that all messages generated by the validation done by graphValidator are translated into FacesMessages and connected to the graphValidator component itself. Is there any plan to use the propertyPath found in a ConstraintViolation to attempt to connect the resulting FacesMessage to a more specific component(perhaps via the component id?)

       

      Example:

      //Inside a ConstraintValidator.isValid

      context.buildConstraintViolationWithTemplate( "SomeCross Field Message").addNode( "someField" ).addConstraintViolation()

       

      <rich:graphValidator value="#{someObject}">

          <h:inputText id="someField" value="#{someObject.someField}" />

      </rich:graphValidator>

       

      Also has any thought been put into translating Payload from inside a ConstraintViolation.ConstraintDescriptor into the Severity of a FacesMessage?

        • 1. graphValidator – cross field validation and payload
          alexsmirnov

          In the case above, per-field constrains sfould be fired by BeanValidator attached to the component, therefore it should have "someField" target. GraphValidator should only generate messages for constrains that weren't assignet to any input component, so the only way to change clientId for grathValidator is manual set it in the component, may be good idea for the next release.

          I don't have a plan to change severity level for bean validation - in JSF, validation message has to have "error' level. I only thought to use Payload to define custom client-side script.

          • 2. Re: graphValidator – cross field validation and payload
            ghilton

            Thanks for your response!

             

            The use case is: we need to use a class level constraint to have visibility into multiple fields.  When a violation occurs, I would want to display the message next to one or both of the fields that caused the violation.

             

            Perhaps a more robust example could shed some light.

             

            public enum Type {

                ROAD, RACE;

            }

             

            public class Driver {

                private String name;

                private Type licenseType;

            ...

            }

             

            @CarConstraint

            public class Car {

                @Valid

                private Driver driver;

                private Type carType;

                private String make;

                private String model;

            ...

            }

             

            public class CarConstraintValidator implements ConstraintValidator<CarConstraint, Car> {

                @Override

                public void initialize(CarConstraint constraintAnnotation) {}

             

                @Override

                public boolean isValid(Car value, ConstraintValidatorContext context) {

                    if(value == null) {return true;}

             

                    if(Type.RACE.equals(value.getCarType())

                            && !Type.RACE.equals(value.getDriver().getLicenseType())) {

             

                        context

                            .buildConstraintViolationWithTemplate("The driver of this car must have a racing license")

                            .addNode("driver")

                            .addNode("licenseType").addConstraintViolation();

             

                        return false;

                    }

             

                    return true;

                }

            }

             

            Picture a form where the information about the car and the driver are input.  If the Driver had a license type of ROAD and the Car had a car type of RACE, it'd be ideal to see a resulting validation message next to the the input for license type, since the message was added to that node using the fluent api of Bean Validation.

             

             

             

            Back to payload..

             

            I was thinking about using Payload like mentioned in the Tip in Section 3.1.1 of the Hibernate Validator Reference Guide. Then if the payload had a Severity of Warning, that would be translated into a FacesMessage where Severity = FacesMessage.SEVERITY_WARN. 

             

            Then ideally the user would get the chance to fix the inputs, or just attempt to save again and be allowed to if there was just that orginal Warning (obviously there are some hurdles here, since validation would have to bypassed or something the second time).  

             

            You mentioned:

            "validation message has to have "error' level"

            Is that because of how the JSF lifecycle works or for some other reason?