3 Replies Latest reply on Apr 18, 2010 3:01 PM by Arbi Sookazian

    Custom Component Validation

    Ben  Smythn Newbie

      Hi,
      I'm creating a custom component with facelets like this




      public class MyTextComponent extends UIInput {
      
      public void decode(FacesContext context) {
      ...
      }
      
      public void encodeEnd(FacesContext ctx) throws IOException {
      ...
      }
      }



      This should render a text box, my problem here is to validate the value that a user inputs, using a hibernate validator annotation. I'm stuck here because I haven't seen any example that uses hibernate validators, the ones that i've seen always implement a validator class that is added in the constructor of the custom component with the method addValidator().


      Can someone give me some tips on how should I solve this.



        • 1. Re: Custom Component Validation
          Arbi Sookazian Master

          I haven't created any custom components that extend UIInput but you can see an example of using Hibernate Validator in the Seam hotel booking example.


          e.g., the Hotel entity class uses the following HV annotations:


          org.hibernate.validator.Length;


          org.hibernate.validator.NotNull;

          • 2. Re: Custom Component Validation
            Ben  Smythn Newbie

            thanks for the reply , but i know how to use hibernate validators in beans fields, my problem is how to apply those annotations to the value field of a custom component.


            In this example there is a label field, I want to know if it is possible to use the @NotNull annotation like in the code below. I've tried but I didn't get any results with that.


            public class MyTextComponent extends UIInput {
            
            @NotNull
            private String Label;
            
            //Setters and getters down here
            
            public void decode(FacesContext context) {
            ...
            }
            
            public void encodeEnd(FacesContext ctx) throws IOException {
            ...
            }
            }



            • 3. Re: Custom Component Validation
              Arbi Sookazian Master

              I was under the impression that Hibernate Validator annotations could only be used for entity classes but at least with Hibernate Validator 4 that's not true.



              Out of the box, Hibernate Annotations will translate the constraints you have defined for your entities into mapping metadata. For example, if a property of your entity is annotated @NotNull, its columns will be declared as not null in the DDL schema generated by Hibernate.

              http://docs.jboss.org/hibernate/validator/3.x/reference/en/html/validator-checkconstraints.html


              The following code was generated by following these instructions:
              http://docs.jboss.org/hibernate/stable/validator/reference/en/html_single/#validator-gettingstarted-createproject


              Note that I modified the original Car class by extending the UIInput class.  All unit tests passed.  Note that the comment states an example entity class but there is no @Entity annotation although it's possible the metadata is in an xml somewhere?


              import javax.faces.component.UIInput;
              import javax.validation.Valid;
              import javax.validation.constraints.AssertTrue;
              import javax.validation.constraints.Min;
              import javax.validation.constraints.NotNull;
              import javax.validation.constraints.Size;
              
              /**
               * An example entity class enriched with constraint annotations from
               * the Bean Validation API (<a href="http://jcp.org/en/jsr/detail?id=303">JSR
               * 303</a>). Have a look at {@link com.mycompany.CarTest} to learn, how the Bean Validation
               * API can be used to validate {@code Car} instances.
               *
               * @author Gunnar Morling
               * @author Hardy Ferentschik
               */
              public class Car extends UIInput {
              
                   /**
                    * By annotating the field with @NotNull we specify, that null is not a valid
                    * value.
                    */
                   @NotNull
                   private String manufacturer;
              
                   /**
                    * This String field shall not only not allowed to be null, it shall also between
                    * 2 and 14 characters long.
                    */
                   @NotNull
                   @Size(min = 2, max = 14)
                   private String licensePlate;
              
                   /**
                    * This int field shall have a value of at least 2.
                    */
                   @Min(2)
                   private int seatCount;
              
                   @AssertTrue(message = "The car has to pass the vehicle inspection first", groups = CarChecks.class)
                   private boolean passedVehicleInspection;
              
                   @Valid
                   private Driver driver;
              
                   public Car(String manufacturer, String licencePlate, int seatCount) {
                        this.manufacturer = manufacturer;
                        this.licensePlate = licencePlate;
                        this.seatCount = seatCount;
                   }
              
                   public String getManufacturer() {
                        return manufacturer;
                   }
              
                   public void setManufacturer(String manufacturer) {
                        this.manufacturer = manufacturer;
                   }
              
                   public String getLicensePlate() {
                        return licensePlate;
                   }
              
                   public void setLicensePlate(String licensePlate) {
                        this.licensePlate = licensePlate;
                   }
              
                   public int getSeatCount() {
                        return seatCount;
                   }
              
                   public void setSeatCount(int seatCount) {
                        this.seatCount = seatCount;
                   }
              
                   public boolean getPassedVehicleInspection() {
                        return passedVehicleInspection;
                   }
              
                   public void setPassedVehicleInspection(boolean passed) {
                        this.passedVehicleInspection = passed;
                   }
              
                   public Driver getDriver() {
                        return driver;
                   }
              
                   public void setDriver(Driver driver) {
                        this.driver = driver;
                   }
              }
              



              import java.util.Set;
              import javax.validation.ConstraintViolation;
              import javax.validation.Validation;
              import javax.validation.Validator;
              import javax.validation.ValidatorFactory;
              
              import static org.junit.Assert.assertEquals;
              import org.junit.BeforeClass;
              import org.junit.Test;
              
              /**
               * <p>
               * A module test that shows how to use the Bean Validation (BV) API to validate
               * the constraint annotations at the exemplary {@link Car} model class.
               * </p>
               * <p>
               * The interface {@link Validator} is the main entry point the BV API. The
               * test makes use of the <code>validate()</code> method of that interface, which
               * returns a set of <code>ConstraintViolation</code>s, that describe the
               * problems occurred during validation.
               * </p>
               * <p>
               * In case the object in question could be validated successfully this set will
               * be empty.
               * </p>
               *
               * @author Gunnar Morling
               * @author Hardy Ferentschik
               */
              public class CarTest {
              
                   /**
                    * The validator to be used for object validation. Will be retrieved once
                    * for all test methods.
                    */
                   private static Validator validator;
              
                   /**
                    * Retrieves the validator instance.
                    */
                   @BeforeClass
                   public static void setUp() {
                        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
                        validator = factory.getValidator();
                   }
              
                   /**
                    * One constraint violation due to the manufacturer field being null
                    * expected.
                    */
                   @Test
                   public void manufacturerIsNull() {
                        Car car = new Car( null, "DD-AB-123", 4 );
              
                        Set<ConstraintViolation<Car>> constraintViolations = validator.validate( car );
              
                        assertEquals( 1, constraintViolations.size() );
                        assertEquals( "may not be null", constraintViolations.iterator().next().getMessage() );
                   }
              
                   /**
                    * One constraint violation due to the licensePlate field being too short
                    * expected.
                    */
                   @Test
                   public void licensePlateTooShort() {
                        Car car = new Car( "Morris", "D", 4 );
              
                        Set<ConstraintViolation<Car>> constraintViolations = validator.validate( car );
              
                        assertEquals( 1, constraintViolations.size() );
                        assertEquals( "size must be between 2 and 14", constraintViolations.iterator().next().getMessage() );
                   }
              
                   /**
                    * One constraint violation due to the seatCount field being too low
                    * expected.
                    */
                   @Test
                   public void seatCountTooLow() {
                        Car car = new Car( "Morris", "DD-AB-123", 1 );
              
                        Set<ConstraintViolation<Car>> constraintViolations = validator.validate( car );
              
                        assertEquals( 1, constraintViolations.size() );
                        assertEquals( "must be greater than or equal to 2", constraintViolations.iterator().next().getMessage() );
                   }
              
                   /**
                    * No constraint violation expected, as all fields of the validated Car
                    * instance have proper values.
                    */
                   @Test
                   public void carIsValid() {
                        Car car = new Car( "Morris", "DD-AB-123", 2 );
              
                        Set<ConstraintViolation<Car>> constraintViolations = validator.validate( car );
              
                        assertEquals( 0, constraintViolations.size() );
                   }
              }