type=page
status=published
title=Creating Custom Constraints
next=bean-validation-advanced002.html
prev=bean-validation-advanced.html
~~~~~~
# Creating Custom Constraints


[[GKFGX]]

[[creating-custom-constraints]]
Creating Custom Constraints
---------------------------

Bean Validation defines annotations, interfaces, and classes to allow
developers to create custom constraints.

The following topics are addressed here:

* link:#GKAIA[Using the Built-In Constraints to Make a New Constraint]
* link:#CIHCICAI[Removing Ambiguity in Constraint Targets]
* link:#implementing-temporal-constraints-using-clockprovider[Implementing Temporal Constraints Using ClockProvider]
* link:#custom-constraints[Custom Constraints]

[[GKAIA]]

[[using-the-built-in-constraints-to-make-a-new-constraint]]
Using the Built-In Constraints to Make a New Constraint
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Bean Validation includes several built-in constraints that can be
combined to create new, reusable constraints. This can simplify
constraint definition by allowing developers to define a custom
constraint made up of several built-in constraints that may then be
applied to component attributes with a single annotation.

[[GKAJU]]

[source,oac_no_warn]
----
@Pattern.List({
  /* A number of format “+1-NNN-NNN-NNNN” */
@Pattern(regexp = “\\+1-\\d{3}-\\d{3}-\\d{4})

@Constraint(validatedBy = {})
@Documented
@Target({ElementType.METHOD,
    ElementType.FIELD,
    ElementType.ANNOTATION_TYPE,
    ElementType.CONSTRUCTOR,
    ElementType.PARAMETER
    ElementType.Type_Use})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(List.class)
public @interface USPhoneNumber {

String message() default "Not a valid US Phone Number";

Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};


  @Target({ElementType.METHOD,
     ElementType.FIELD,
     ElementType.ANNOTATION_TYPE,
     ElementType.CONSTRUCTOR,
     ElementType.PARAMETER
     ElementType.Type_Use })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@interface List {
USPhoneNumber[] value();

}

}
----

You can also implement a `Constraint Validator` to validate the constraint `@USPhoneNumber`. For more information about using `Constraint Validator`, see `javax.validation.ConstraintValidator`.

[source,oac_no_warn]
----
@USPhoneNumber
protected String phone;
----

[[CIHCICAI]]

[[removing-ambiguity-in-constraint-targets]]
Removing Ambiguity in Constraint Targets
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Custom constraints that can be applied to both return values and method
parameters require a `validationAppliesTo` element to identify the
target of the constraint.

[source,oac_no_warn]
----
@Constraint(validatedBy=MyConstraintValidator.class)
@Target({ METHOD, FIELD, TYPE, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
public @interface MyConstraint {
  String message() default "{com.example.constraint.MyConstraint.message}";
  Class<?>[] groups() default {};
  ConstraintTarget validationAppliesTo() default ConstraintTarget.PARAMETERS;
...
}
----

This constraint sets the `validationAppliesTo` target by default to the
method parameters.

[source,oac_no_warn]
----
@MyConstraint(validationAppliesTo=ConstraintTarget.RETURN_TYPE)
public String doSomething(String param1, String param2) { ... }
----

In the preceding example, the target is set to the return value of the
method.

## Implementing Temporal Constraints Using ClockProvider

[[implementing-temporal-constraints-using-clockprovider]]

In Bean Validation 2.0, a Clock instance is available for validator implementations to validate any temporal date or time based constraints.
[source,oac_no_warn]
----
ValidatorFactory validatorFactory = Validation.
	buildDefaultValidatorFactory();
ClockProvider clockProvider = validatorFactory.getClockProvider();
java.time.Clock Clock = clockProvider.getClock();
----
You can also register a custom `ClockProvider` with a `ValidatorFactory`:
[source,oac_no_warn]
----
//Register a custom clock provider implementation with validator factory
ValidatorFactory factory = Validation
       .byDefaultProvider().configure()
          .clockProvider( new CustomClockProvider() )
          .buildValidatorFactory();

//Retrieve and use the custom Clock Provider and Clock in the Validator implementation
public class CustomConstraintValidator implements ConstraintValidator<CustomConstraint, Object> {

    public boolean isValid(Object value, ConstraintValidatorContext context){
        java.time.Clock clock = context.getClockProvider().getClock();
        ...
        ...

    }
}
----
See ClockProvider in `https://javaee.github.io/javaee-spec/javadocs/`.

## Custom Constraints

[[custom-constraints]]
Consider an employee in a firm located in U.S.A. When you register the phone number of an employee or modify the phone number, the phone number needs to be validated to ensure that the phone number conforms to US phone number pattern.
[source,oac_no_warn]
----
public class Employee extends Person {

  @USPhoneNumber
  protected String phone;

  public Employee(String name, String phone, int age){
    super(name, age);
    this.phone = phone;
  }

  public String getPhone() {
    return phone;
  }

  public void setPhone(String phone) {
    this.phone = phone;
  }
----
The constraint definition `@USPhoneNumber` is define in the sample listed under link:bean-validation-advanced001.html#GKAIA[Using the Built-In Constraints to Make a New Constraint].
In the sample, another constraint `@Pattern` is used to validate the phone number.

###  Using In-Built Value Extractors in Custom Containers
[[using-in-built-value-extractors-in-custom-containers]]
Cascading validation:

Bean Validation supports cascading validation for various entities. You can specify `@Valid` on a member of the object that is validated to ensure that the member is also validated in a cascading fashion. You can validate type arguments, for example, parameterized types and its members if the members have the specified `@Valid` annotation.
[source,oac_no_warn]
----
public class Department {
    private List<@Valid Employee> employeesList;
}
----
By specifying `@Valid` on a parameterized type, when an instance of `Department` is validated, all elements such as `Employee` in the `employeesList` are also validated. In this example, each employee's "phone" is  validated against the constraint `@USPhoneNumber`.

For more information see `https://javaee.github.io/javaee-spec/javadocs/`

Value Extractor:

While validating the object or the object graph, it may be necessary to validate the constraints in the parameterized types of a container as well. To validate the elements of the container, the validator must extract the values of these elements in the container. For example, in order to validate the element values of `List` against one or more constraints such as `List<@NotOnVacation Employee>` or to apply cascading validation to `List<@Valid Employee>`, you need a value extractor for the container `List`.

Bean validation provides in-built value extractors for most commonly used container types such as List, Iterable, and others. However, it is also possible to implement and register value-extractor implementations for custom container types or override the in-built value-extractor implementations.

Consider a Statistics Calculator for a group of 'Person' entity and 'Employee' is one of the sub-type of the entity 'Person'.
[source,oac_no_warn]
----
public class StatsCalculator<T extends Person> {

  /* Cascading validation as well as @NotNull constraint */
  private List<@NotNull @Valid T> members = new ArrayList<T>();


  public void addMember(T member) {
    members.add(member);
  }

  public boolean removeMember(T member) {
    return members.remove(member);
  }

  public int getAverageAge() {

    if (members.size() == 0)
      return 0;

    short sum = 0;
    for (T member : members) {
      if(member != null) {
        sum += member.getAge();
      }
    }
    return sum / members.size();
  }

  public int getOldest() {
    int oldest = -1;

    for (T member : members) {
      if(member != null) {
        if (member.getAge() > oldest) {
          oldest = member.getAge();
        }
      }
    }
    return oldest;
  }
----
When the `StatsCalculator` is validated, the "members" field is also validated. The in-built value extractor for `List` is used to extract the values of `List` to validate the elements in `List`. In the case of an employee based List, each "Employee” element is validated. For example, an employee’s "phone" is validated using the `@USPhoneNumber` constraint.

In the following example, let us consider a `StatisticsPrinter` that prints the statistics or displays the statistics on screen.
[source,oac_no_warn]
----
public class StatisticsPrinter {
    private StatsCalculator<@Valid Employee> calculator;

    public StatisticsPrinter(StatsCalculator<Employee> statsCalculator){
      this.calculator = statsCalculator;
    }

    public void displayStatistics(){
      //Use StatsCalculator, get stats, format and display them.
    }

    public void printStatistics(){
      //Use StatsCalculator, get stats, format and print them.
    }

  }
----
The container `StatisticsPrinter` uses `StatisticsCalculator`. When `StatisticsPrinter` is validated, the `StatisticsCalculator` is also validated by using the cascading validation such as `@Valid` annotation. However, in order to retrieve the values of `StatsCalculator` container type, a value extractor is required. An implementation of `ValueExtractor` for `StatsCalculator` is as follows:
[source,oac_no_warn]
----
public class ExtractorForStatsCalculator implements ValueExtractor<StatsCalculator<@ExtractedValue ?>>{

    @Override
    public void extractValues(StatsCalculator<@ExtractedValue ?> statsCalculator,
        ValueReceiver valueReceiver) {
        /* Simple value retrieval is done here.
           It is possible to adapt or unwrap the value if required.*/
      valueReceiver.value("<extracted value>", statsCalculator);
    }
  }
----
There are multiple mechanisms to register the `ValueExtractor` with Bean Validation. See, “Registering ValueExtractor” implementations section in the Bean Validation specification `http://www.jcp.org/en/jsr/detail?id=380`. One of the mechanisms is to register the value extractor with Bean Validation Context.
[source,oac_no_warn]
----
ValidatorFactory validatorFactory = Validation
        .buildDefaultValidatorFactory();

    ValidatorContext context = validatorFactory.
        usingContext()
        .addValueExtractor(new ExtractorForStatsCalculator());


    Validator validator = context.getValidator();
----
Using this validator, `StatsisticsPrinter` is validated in the following sequence of operations:

1.	`StatisticsPrinter` is validated.
a.	The members of `StatisticsPrinter` that need cascading validation are validated.
b.	For container types, value extractor is determined. In the case of `StatsCalculator`, `ExtractorForStatsCalculator` is found and then values are retrieved for validation.
c.	`StatsCalculator` and its members such as `List` are validated.
i.	In-built `ValueExtractor` for `java.util.List` is  used to retrieve the values of elements of the list and the validated. In this case, Employee and the field "phone" that is annotated with `@USPhoneNumber` constraint is validated.
