jsr 303: bean validation - edelivery.oracle.com

43
JSR 303: Bean Validation 1.0.Beta1 (Early Draft Review 1) 2008-03-04 Authors: Bean Validation Expert Group Emmanuel Bernard (Red Hat Middleware, LLC) Steve Peterson Copyright © 2007, 2008 Red Hat Middleware, LLC and Steve Peterson

Upload: others

Post on 14-Mar-2022

6 views

Category:

Documents


0 download

TRANSCRIPT

JSR 303: Bean Validation

1.0.Beta1 (Early Draft Review 1)2008-03-04

Authors:

Bean Validation Expert Group

Emmanuel Bernard (Red Hat Middleware, LLC)

Steve Peterson

Copyright © 2007, 2008 Red Hat Middleware, LLC and Steve Peterson

Table of ContentsDisclaimer ............................................................................................................................................iv1. Introduction ........................................................................................................................................1

1.1. Expert group ............................................................................................................................11.2. Specification goals ...................................................................................................................21.3. How this document is organized ................................................................................................21.4. How to comment ......................................................................................................................2

2. Constraint Definition ...........................................................................................................................32.1. Constraint annotation ...............................................................................................................3

2.1.1. Constraint definition properties ......................................................................................32.1.1.1. message .............................................................................................................32.1.1.2. groups ................................................................................................................42.1.1.3. Constraint specific parameter ..............................................................................4

2.1.2. Examples ......................................................................................................................42.2. Multi-valued constraints ...........................................................................................................52.3. Constraint validation implementation ........................................................................................62.4. The ConstraintFactory ..............................................................................................................7

2.4.1. Example .......................................................................................................................72.5. StandardConstraint description ..................................................................................................8

2.5.1. Standard Constraint metadata examples ..........................................................................93. Constraint declaration and validation process ......................................................................................11

3.1. Requirements on classes to be validated ...................................................................................113.1.1. Object validation .........................................................................................................113.1.2. Field and property validation ........................................................................................113.1.3. Graph validation ..........................................................................................................12

3.2. Constraint declaration .............................................................................................................123.3. Inheritance (interface and superclass) ......................................................................................123.4. Group and group sequence ......................................................................................................133.5. Validation routine ..................................................................................................................13

3.5.1. Object graph validation ................................................................................................143.6. Examples ...............................................................................................................................14

4. Validation APIs ................................................................................................................................214.1. Validator<T> API ..................................................................................................................21

4.1.1. Validation methods ......................................................................................................224.1.1.1. Examples .........................................................................................................22

4.1.2. groups ........................................................................................................................234.1.2.1. Examples .........................................................................................................23

4.2. InvalidConstraint ....................................................................................................................254.2.1. Example .....................................................................................................................26

4.3. Message resolution .................................................................................................................274.3.1. Default message resolution ..........................................................................................28

4.3.1.1. Algorithm ........................................................................................................284.3.2. Custom message resolution ..........................................................................................284.3.3. Examples ....................................................................................................................29

4.4. Bootstrapping ........................................................................................................................29

1.0.Beta1 (Early Draft Review 1) ii

5. Constraint metadata request APIs .......................................................................................................305.1. Validator<T> .........................................................................................................................305.2. ElementDescriptor .................................................................................................................315.3. ConstraintDescriptor ..............................................................................................................325.4. Example ................................................................................................................................33

6. Built-in Constraint definitions ............................................................................................................357. XML deployment descriptor ..............................................................................................................36

7.1. ..............................................................................................................................................36A. Terminology ....................................................................................................................................37B. Standard resolver messages ...............................................................................................................39

JSR 303: Bean Validation

1.0.Beta1 (Early Draft Review 1) iii

DisclaimerThis specification is a work in progress. The content of this specification is highly subject to change. Specific areascurrently at work include:

• StandardConstraint extension (feedback from presentation frameworks)

• Message resolution and localization

• Boostrap strategy (including validation provider resolution)

• Constraint metadata request API (feedback from consumer frameworks including presentation, tools and so on)

• Built-in constraint definitions

• XML deployment descriptor

• Extension for method parameters validation

The JSR 303 expert group is seeking for feedbacks from the community on this specification and will update it ac-cordingly. Direct feedbacks to [email protected].

1.0.Beta1 (Early Draft Review 1) iv

1Introduction

This document is the specification of the Java API for JavaBean validation in Java EE and Java SE. The technicalobjective of this work is to provide a class level constraint declaration and validation facility for the Java applica-tion developer, as well as a constraint metadata repository and query API.

1.1. Expert group

This work is being conducted as part of JSR-303 under the Java Community Process Program. This specification isthe result of the collaborative work of the members of the JSR 303 Expert Group. These include the followingpresent and former expert group members:

• Geert Bevin

• Emmanuel Bernard (Red Hat Middleware LLC)

• Uri Boness

• Erik Brakkee (Ericsson AB)

• Ed Burns (Sun Microsystems, Inc.)

• Jason Carreira

• Robert Clevenger

• Linda DeMichiel (Sun Microsystems, Inc.)

• Tim Fennel

• Romain Guy (Google Inc.)

• Robert Harrop

• Jacob J. Hookom

• Bob Lee (Google Inc.)

• Craig R. McClanahan

• Niall K. Pemberton

• Steve Peterson

1.0.Beta1 (Early Draft Review 1) 1

• Dhanji R. Prasanna

• Matt Raible

• Michael Nascimento Santos

• Jon Wetherbee (Oracle)

1.2. Specification goals

Validating data is a common task that occurs throughout an application, from the presentation layer to the persist-ence layer. Often the same validation logic is implemented in each layer, proving time consuming and error-prone.To avoid duplication of these validations in each layer, developers often bundle validation logic directly into thedomain model, cluttering domain classes with validation code that is, in fact, metadata about the class itself.

This JSR defines a metadata model and API for JavaBean validation. The default metadata source is annotations,with the ability to override and extend the meta-data through the use of XML validation descriptors.

The validation API developed by this JSR is not intended for use in any one tier or programming model. It is spe-cifically not tied to either the web tier or the persistence tier, and is available for both server-side application pro-gramming, as well as rich client Swing application developers. This API is seen as a general extension to the Java-Beans object model, and as such is expected to be used as a core component in other specifications. Ease of use andflexibility are influencing the design of this specification.

1.3. How this document is organized

This document describes each aspect of the bean validation specification in a separate chapter. One should remem-ber that the specification is a consistent whole.

Chapter 2 describes how constraints are defined.

Chapter 3 describes how a JavaBean class is decorated with annotations to describe constraints on the contents ofan instance of the class.

Chapter 4 describes how to programmatically validate a JavaBean.

Constraint metadata request API describes how the metadata query API works.

1.4. How to comment

The expert group is eager to receive feedbacks from readers. Feel free to email us at [email protected].

Introduction

1.0.Beta1 (Early Draft Review 1) 2

2Constraint Definition

Constraints are defined through a combination of a constraint annotation and a constraint validation implementa-tion. The constraint annotation is applied to a type, method, or field target.

Unless stated otherwise the default package name for the Bean Validation APIs is javax.validation.

2.1. Constraint annotation

A constraint on a JavaBean is expressed through one or more annotations. An annotation is considered a constraintdefinition if its retention policy contains RUNTIME and if the annotation itself is annotated withjavax.validation.ConstraintValidator.

/*** Link between an constraint annotation and its constraint validation implementation** A given constraint annotation should be annotated by a @ValidatorClass* annotation to refer to its constraint validation implementation**/

@Documented@Target({ANNOTATION_TYPE})@Retention(RUNTIME)public @interface ConstraintValidator {

/*** Constraint validation implementation*/Class<? extends Constraint> value();

}

Constraint annotations can be defined on FIELD, METHOD, or TYPE targets.

Since a given constraint definition applies to one or more specific types, the JavaDoc for the constraint annotationshould clearly state which types are supported. Applying a constraint annotation to an incompatible type is aruntime error.

2.1.1. Constraint definition properties

A constraint definition may have properties that can be specified at the time the constraint is applied to a JavaBean.The properties are mapped as annotation elements. The annotation element names message and groups are con-sidered reserved names; a constraint may use any other element name for its parameters.

2.1.1.1. message

Every constraint annotation must define a message element of type String.

1.0.Beta1 (Early Draft Review 1) 3

String message() default "{beancheck.myConstraintFailure}";

The message element value is used to create the error message. See Section 4.3 for a detailed explanation.

2.1.1.2. groups

groups is a required element that specifies which processing groups the constraint definition is associated with.

String[] groups() default {};

The default value must be an empty array.

When using the constraint declaration, if no group is specified, the default group is considered declared. The val-idation will be evaluated if

• no group was specified at validation time (which defaults to the default group) and the annotation is a memberof the default group

• or if one of the groups specified at validation time matches one of the groups specified on the constraint annota-tion declaration

See Section 4.1.2 for more informations. It is required that all constraint definitions support this element.

Groups are typically used to control the order of validator evaluation, or perform partial validation of a JavaBean.

2.1.1.3. Constraint specific parameter

The constraint annotation definitions may define additional elements needed to parameterize the constraint defini-tion. For example, a constraint that validates the length of a string can use an annotation element named length tospecify the maximum length at the time the constraint is declared.

2.1.2. Examples

Example 2.1. NotNull constraint definition

@Documented@ValidatorClass(NotNullConstraint.class)@Target({METHOD, FIELD})@Retention(RUNTIME)public @interface NotNull {

String message() default "{beancheck.notNull}";String[] groups() default {};

}

Defines a not null constraint with a specific default message. The constraint validator is implemented by Not-

NullConstraint.

Example 2.2. Length constraint definition

Constraint Definition

1.0.Beta1 (Early Draft Review 1) 4

@Documented@ValidatorClass(LengthConstraint.class)@Target({METHOD, FIELD})@Retention(RUNTIME)public @interface Length {

int min() default 0;int max() default Integer.MAX_VALUE;String message() default "{beancheck.length}";String[] groups() default {};

}

Defines a length constraint. The constraint definition includes two optional properties that may be specified whenthe constraint is applied.

Example 2.3. Min constraint definition

@Documented@ValidatorClass(MinConstraint.class)@Target({METHOD, FIELD})@Retention(RUNTIME)public @interface Min {

int value();String message() default "{beancheck.min}";String[] groups() default {};

}

Defines a min constraint with a constraint property that must be specified when the constraint is applied.

2.2. Multi-valued constraints

It is often useful to apply the same constraint more than once to the same target, with different properties. A com-mon example is the @Pattern constraint, which validates that its target matches a specified regular expression.

To support this, the bean validation provider treats annotations applied to a type, field or property with a value an-notation element with a return type of an array of constraint annotations and whose retention is RUNTIME as a list ofannotations that are processed by the Bean Validation implementation. This means that each constraint specified inthe value element is applied to the target.

Each constraint implementation should implement their corresponding multi-valued constraint.

@Documented@ConstraintValidator(PatternValidator.class)@Target({METHOD, FIELD})@Retention(RUNTIME)public @interface Pattern {

/** regular expression */String regex();

/** Flags parameter for Pattern.compile() */int flags() default 0;

String message() default "{validator.pattern}";String[] groups() default {};

}

Constraint Definition

1.0.Beta1 (Early Draft Review 1) 5

@Documented@Target({METHOD, FIELD})@Retention(RUNTIME)public @interface Patterns {

Pattern[] value();}

Example 2.4. Multi-valued constraint

public class Engine {@Patterns( {

@Pattern(regex = "^[A-Z0-9-]+$",message = "must contain alphabetical characters only"),

@Pattern(regex = "^....-....-....$", message="must match ....-....-....")} )

private String serialNumber;}

In this example, both constraints (^[A-Z0-9-]+$ and ^....-....-....$) will be applied on the serialNumber

field.

2.3. Constraint validation implementation

A constraint validation implementation performs the validation of a target class, field, or method. It is specified bythe value element of the ConstraintValidator annotation that decorates the constraint definition. The constaintvalidation implementation implements the Constraint interface.

/*** Define the logic to validate a given constraint*/

public interface Constraint<A extends Annotation> {/*** Initialize the constraint validator.** This method is guaranteed to be called once right after the constraint is retrieved* from the <code>ConstraintFactory</code> and before the Bean Validation provider* starts using it.** @param constraintAnnotation The constraint declaration*/void initialize(A constraintAnnotation);/*** Evaluates the constraint against a value. This method* must be thread safe.** @param value The object to validate* @return false if the value is not valid, true otherwise* @exception IllegalArgumentException The value's type isn't understood* by the constraint validator*/boolean isValid(Object value);}

The lifetime of a constraint validation implementation instance is undefined.

Constraint Definition

1.0.Beta1 (Early Draft Review 1) 6

initialize is called by the Bean validation provider prior to any use of the constraint implementation.

The isValid method is evaluated by the Bean Validation provider each time a given value is validated. It returnsfalse if the value is not valid, true otherwise. isValid implementations must be thread-safe.

Note

While not mandatory, it is considered a good practice to split the core constraint validation from the notnull constraint validation (for example, an @Email constraint will return true on a null object, i.e. will nottake care of the @NotNull validation)

If the value parameter references an object with an unanticipated type, an IllegalArgumentException should beraised.

2.4. The ConstraintFactory

Constraint validation implementation instances are created by a ConstraintFactory.

/*** This class manages the creation of constraint validators.*/

public interface ConstraintFactory {/*** Instantiate a Constraint.** @return Returns a new Constraint instance* The ConstraintFactory is <b>not</b> responsible for calling Constraint#initialize*/<T extends Constraint> T getInstance(Class<T> constraintClass);

}

The default ConstraintFactory provided by the bean provider implementation uses the public constraint no-argconstructor (it is recommended that all constraint implementation have a public no-arg constructor). A custom con-straint factory can be provided for example to benefit from a dependency injection control in constraint implement-ations.

2.4.1. Example

Example 2.5. Length constraint validator

/*** Check that a string length is between min and max**/

public class LengthConstraint implements Constraint<Length> {private int min;private int max;

/*** Configure the constraint validator based on the elements* specified at the time it was defined.* @param constraint the constraint definition*/

Constraint Definition

1.0.Beta1 (Early Draft Review 1) 7

public void initialize(Length constraint) {min = constraint.min();max = constraint.max();

}

/*** Validate a specified value.* returns false if the specified value does not conform to the definition* @exception IllegalArgumentException if the object is not of type String*/public boolean isValid(Object value) {

if ( value == null ) return true;if ( !( value instanceof String ) ) {

throw new IllegalArgumentException("Expected String type");}String string = (String) value;int length = string.length();return length >= min && length <= max;

}}

This constraint validator checks that the string's length is between min and max. It also demonstrates some bestpractices:

• raises an IllegalArgumentException in case of type mismatch

• returns true on a null parameter

2.5. StandardConstraint description

Constraint metadata can be consumed through the Constraint metadata request API. In addition to their Constraintimplementation, built-in and custom constraint definitions can describe the constraint through static and standarddimensions (such as nullability, length for a String etc). This metadata is particularly useful for third-partymetadata consumers like persistence frameworks generating database schemas (such as Java Persistence) orpresentation frameworks.

Any constraint definition can implement the StandardConstraint interface to expose this metadata.

/*** Indicates the availability of standard constraint metadata.**/

public interface StandardConstraint {/*** @return A StandardConstraintDescriptor containing metadata* for this constraint definition.*/StandardConstraintDescriptor getStandardConstraintDescriptor();

}

/*** Describe how the current constraint influences the standard constraints** @author Emmanuel Bernard*/

public class StandardConstraintDescriptor {

Constraint Definition

1.0.Beta1 (Early Draft Review 1) 8

/*** Defines the object nullability.* TRUE means the object is nullable,* FALSE means the object is not nullable,* NULL means does not apply.*/

public Boolean getNullability() {return null;

}

/*** Defines the precision if the validated object is a number.* NULL means does not apply.*/public Integer getPrecision() {

return null;}

/*** Defines the scale if the validated object is a number.* NULL means does not apply.*/public Integer getScale() {

return null;}

/*** Defines the length if the validated object is a string.* NULL means does not apply.*/public Integer getLength() {

return null;}

}

Clients can then access this information through the Constraint metadata request API and more specifically throughthe getConstraintImplementation method of ConstraintDescriptor.

2.5.1. Standard Constraint metadata examples

The following example extends Section 2.4.1.

Example 2.6. Standard constraint metadata

/*** Check that a string length is between min and max* and expose the information through the standard constraint model**/

public class LengthConstraint implements Constraint, StandardConstraint {private int min;private int max;

/*** retrieve parameters from the annotation for later use*/public void initialize(Length constraint) {

min = constraint.min();max = constraint.max();

Constraint Definition

1.0.Beta1 (Early Draft Review 1) 9

}

/*** return true if the object is null* returns false if the value object is out of boundaries* rause an IllegalArgumentException if the object is not of type String*/public boolean isValid(Object value) {

if ( value == null ) return true;if ( !( value instanceof String ) ) {

throw new IllegalArgumentException("Expected String type");}String string = (String) value;int length = string.length();return length >= min && length <= max;

}

/*** Returns the standard constraint descriptor in accordance with the max constraint*/public StandardConstraintDescriptor getStandardConstraints() {

return new StandardConstraintDescriptor() {public Integer getLength() {

if ( max == Integer.MAX_VALUE ) {return null;

}else {

return max;}

}};

}}

In this example, the only standard constraint metadata value provided by this constraint definition is length.

Constraint Definition

1.0.Beta1 (Early Draft Review 1) 10

3Constraint declaration and validation process

The Bean Validation specification defines a framework for declaring constraints on JavaBean classes, fields andproperties.

Constraints are declared for classes, and evaluated against instances or graphs of instances.

3.1. Requirements on classes to be validated

Objects that are to be validated must fulfill the following requirements.

Properties to be validated must follow the method signature conventions for JavaBeans read properties, as definedby the JavaBeans specification.

Constraints can be applied to interfaces and superclasses.

The target of an annotation definition can be a field, property, or type, provided that:

• the constraint definition supports the specified target

• the constraint validator supports the type of the target object

3.1.1. Object validation

Constraint declarations can be applied to a class or an interface. Applying a constraint to a class or interface ex-presses a validation over the state of the class or interface.

3.1.2. Field and property validation

Constraint declarations can be applied on both fields and properties for the same object type. The same constraintshould however not be duplicated between a field and its associated property (the constraint validation would beapplied twice). It is recommended for objects holding constraint declarations to adhere a single state access strategy(either annotated fields or properties).

When a field is annotated with a constraint declaration, field access strategy is used to access the state validated bysuch constraint.

When a property is annotated with a constraint declaration, property access strategy is used to access the state val-idated by such constraint.

When using field access strategy, the bean validation provider accesses the instance variable directly. When using

1.0.Beta1 (Early Draft Review 1) 11

the property access strategy, the bean validation provider accesses the state via the property accessor method. It isrequired that the class follow the method signature conventions for JavaBeans read properties (as defined by theJavaBeans Introspector class) for constrained properties when constrained properties are used. In this case, forevery constraint property of type T, there is a getter method, getProperty. For boolean properties, isProperty isan alternative name for the getter method. Specifically, if getX is the name of the getter method, where X is astring, the name of the persistent property is defined by the result of java.beans.Introspector.decapitalize(X).

The fields or methods visibility are not constrained.

3.1.3. Graph validation

In addition to supporting instance validation, validation of graphs of object is also supported. The result of graphvalidation is a unified list of invalid values.

Consider the situation where bean X contains a field of type Y. By annotating field Y with the @Valid annotation,the Validator will validate the contents of Y when X is validated.

Collection-valued or array-valued fields and properties may also be decorated with the @Valid annotation. Thiscauses the contents of the collection or array to be validated. The following types are supported:

• any array of object

• java.util.Collection

• java.util.Set

• java.util.List

• java.util.Map

The @Valid annotation is applied recursively. A conforming implementation avoids infinite loops by validating anobject the first time it is encountered in the graph, and ignores it if it is encountered through at different path.

3.2. Constraint declaration

Constraint declarations are placed on classes or interfaces primarily through annotations. A constraint annotation(see Section 2.1), can be applied to a type, on any of the type's fields or on any of the JavaBeans-compliant proper-ties.

When a constraint is defined on a type, the type instance being validated is passed to the constraint validator. Whena constraint is defined on a field, the value of the field is passed to the constraint validator. When a constraint isdefined on a getter, the result of the getter invocation is passed to the validation routine.

3.3. Inheritance (interface and superclass)

A constraint declaration can be placed on an interface. Constraint declarations held on superclasses as well as inter-faces are evaluated by the Validator.

Constraint declaration and validation process

1.0.Beta1 (Early Draft Review 1) 12

The effect of constraint declarations is cumulative. Constraints declared on a superclass getter will be validatealong with any constraints defined on an overridden version of the getter.

3.4. Group and group sequence

Groups are useful to define subsets of constraints for validation purposes. Assigning constraints to groups providesthe ability to do partial validation to the group. The groups element of the constraint annotation specifies thegroups in which the constraint participates. At validation time, an optional parameter can be specified that narrowsthe set of groups to be validated.

One important application for grouping is to control the order of evaluation of constraints. There are often scenari-os where a preliminary set of constraints should be evaluated prior to other constraints. This is useful in two scen-arios:

• the second group depends on a stable state to run properly

• the second group is a heavy consumer of time, CPU or memory and should be avoided if possible

To implements such ordering, one or more @GroupSequence annotations can be added.

@Target({TYPE})@Retention(RUNTIME)public @interface GroupSequence {

String name();String[] sequence();

}

@Target({TYPE})@Retention(RUNTIME)public @interface GroupSequences {

GroupSequence[] value();}

@GroupSequence and @GroupSequences are placed on the validated class they should be applied on.

Each group of a group sequence must be processed sequentially in the order defined by @GroupSequence.sequence

when the group @GroupSequence.name is requested ; processing a group is defined in Section 3.5 ; if one of thegroup process in the sequence leads to one or more validation failure, the groups following in the sequence mustnot be processed. Group sequences are recursively resolved: the user must make sure no circular graph is definedby the group sequence definitions. For a given class, the group sequences taken into account are the one placed onthe class itself as well as the ones on all its superclasses and all its interfaces. When an object graph is validated(through the use of @Valid), the children elements of the graph inherit the sequence definitions of their parent. Twogroup sequences must not share the same group name in a given object graph (including superclasses and inter-faces). Group sequences must not use constraint declaration group names as a name. In other words, constraintdefinition groups cannot contain one of the group sequence name.

Unless constrained by a group sequence, the order in which groups are validated is undefined.

3.5. Validation routine

Constraint declaration and validation process

1.0.Beta1 (Early Draft Review 1) 13

For a given group to validate, the validation routine applied in a given bean instance is expected to execute the con-straint validations:

• execute all field level validations (including the one expressed in interfaces and superclasses) matching the tar-geted group unless the given validation constraint has already been processed during this validation routine (aspart of a previous group match)

• execute all method level validations (including the one expressed in interfaces and superclasses) matching thetargeted group unless the given validation constraint has already been processed during this validation routine(as part of a previous group match)

• execute all bean level validations (including the one expressed in interfaces and superclasses) matching the tar-geted group unless the given validation constraint has already been processed during this validation routine (aspart of a previous group match)

• execute all cascading validations (see Section 3.5.1) including the one expressed in interfaces and superclasses

Note that it implies that a given validation constraint will not be processed more than once per validation.

The object validation routine is described as such. For each constraint declaration and in the previously defined or-der:

• execute the isValid operation (from the constraint validation implementation) on the appropriate data (see Sec-tion 2.3)

• if isValid returns true, continue to the next constraint,

• if isValid returns false, the Bean Validation provider populate an InvalidConstraint object and append it tothe list of returned values

3.5.1. Object graph validation

The @Valid annotation on a given association (i.e. object reference or collection / array of objects), dictates theBean Validator implementation to apply recursively the bean validation routine on (each of) the associated ob-ject(s). This mechanism is recursive: an associated object can itself contains cascaded references. The Bean Valida-tion implementation must ignore the cascading operation if the associated object instance has already been valid-ated by the current validation routine, thus preventing infinite loops.

The InvalidConstraint objects, built when a failing constraint on an associated object is found, reflects the pathto reach the object from the root validated object (See Section 4.2).

3.6. Examples

The first example demonstrate how bean, fields and getters are annotated to express some constraints.

@ZipCodeCityCoherenceCheckerpublic class Address {

@NotNull @Length(max=30)private String addressline1;

Constraint declaration and validation process

1.0.Beta1 (Early Draft Review 1) 14

@Length(max=30)private String addressline2;

private String zipCode;

private String city;

public String getAddressline1() {return addressline1;

}

public void setAddressline1(String addressline1) {this.addressline1 = addressline1;

}

public String getAddressline2() {return addressline2;

}

public void setAddressline2(String addressline2) {this.addressline2 = addressline2;

}

public String getZipCode() {return zipCode;

}

public void setZipCode(String zipCode) {this.zipCode = zipCode;

}

@Length(max=30) @NotNullpublic String getCity() {

return city;}

public void setCity(String city) {this.city = city;

}}

During the validation routine execution on an Address object,

• addressline1 field value is passed to the NotNull as well as Length constraint validation implementation.

• addressline2 field value is passed to the Length constraint validation implementations.

• getCity value is passed to the Length and NotNull constraint validation implementations

• ZipCodeCohereceChecker is a constraint whose validation implementation's isValid method receives the Ad-

dress object

The second example demonstrates object graph validation

public class Country {@NotNullprivate String name;@Length(max=2) private String ISO2Code;@Length(max=3) private String ISO3Code;

public String getName() {

Constraint declaration and validation process

1.0.Beta1 (Early Draft Review 1) 15

return name;}

public void setName(String name) {this.name = name;

}

public String getISO2Code() {return ISO2Code;

}

public void setISO2Code(String ISO2Code) {this.ISO2Code = ISO2Code;

}

public String getISO3Code() {return ISO3Code;

}

public void setISO3Code(String ISO3Code) {this.ISO3Code = ISO3Code;

}}

public class Address {@NotNull @Length(max=30)private String addressline1;@Length(max=30)private String addressline2;@Length(max=11)private String zipCode;@NotNull @Validprivate Country country;

private String city;

public String getAddressline1() {return addressline1;

}

public void setAddressline1(String addressline1) {this.addressline1 = addressline1;

}

public String getAddressline2() {return addressline2;

}

public void setAddressline2(String addressline2) {this.addressline2 = addressline2;

}

public String getZipCode() {return zipCode;

}

public void setZipCode(String zipCode) {this.zipCode = zipCode;

}

@Length(max=30) @NotNullpublic String getCity() {

return city;}

public void setCity(String city) {

Constraint declaration and validation process

1.0.Beta1 (Early Draft Review 1) 16

this.city = city;}

public Country getCountry() {return country;

}

public void setCountry(Country country) {this.country = country;

}}

During the validation routine execution on an Address object, constraints on addressLine1, addressLine2, zip-Code and country are processed as well as the validation of the Country object itself, more specifically coun-

try.name is checked for NotNull, ISO2Code and ISO3Code are checked for Length.

The third example demonstrates superclass and inheritance.

public interface Person {@NotEmptyString getFirstName();

String getMiddleName();

@NotEmptyString getLastName();

}

public class Customer implements Person {private String firstName;private String middleName;private String lastName;@NotNullprivate String customerId;@Password(robustness=5)private String password;

public String getFirstName() {return firstName;

}

public void setFirstName(String firstName) {this.firstName = firstName;

}

public String getMiddleName() {return middleName;

}

public void setMiddleName(String middleName) {this.middleName = middleName;

}

public String getLastName() {return lastName;

}

public void setLastName(String lastName) {this.lastName = lastName;

}

public String getCustomerId() {return customerId;

}

Constraint declaration and validation process

1.0.Beta1 (Early Draft Review 1) 17

public void setCustomerId(String customerId) {this.customerId = customerId;

}

public String getPassword() {return password;

}

public void setPassword(String password) {this.password = password;

}}

public class PreferredGuest extends Customer {@CreditCardprivate String guestCreditCardNumber;

public String getGuestCreditCardNumber() {return guestCreditCardNumber;

}

public void setGuestCreditCardNumber(String guestCreditCardNumber) {this.guestCreditCardNumber = guestCreditCardNumber;

}}

When validating a PreferredGuest the following constraints are processed:

• NotEmpty on firstName, NotEmpty on lastName

• NotNull on customerId, Password on password

• CreditCard on guestCreditCardNumber

The fourth example demonstrates the influence of group sequence.

public class Author {@NotEmpty(groups="last")private String firstName;

@NotEmpty(groups="first")private String lastName;

@Length(max=30, groups="last")private String company;

public String getFirstName() {return firstName;

}

public void setFirstName(String firstName) {this.firstName = firstName;

}

public String getLastName() {return lastName;

}

public void setLastName(String lastName) {this.lastName = lastName;

}

Constraint declaration and validation process

1.0.Beta1 (Early Draft Review 1) 18

public String getCompany() {return company;

}

public void setCompany(String company) {this.company = company;

}}

@GroupSequence(name="default", sequence={"first", "second", "last"})public class Book {

@NotEmpty(groups="first")private String title;

@Length(max=30, groups="second")private String subtitle;

@Valid@NotNull(groups="first")private Author author;

public String getTitle() {return title;

}

public void setTitle(String title) {this.title = title;

}

public String getSubtitle() {return subtitle;

}

public void setSubtitle(String subtitle) {this.subtitle = subtitle;

}

public Author getAuthor() {return author;

}

public void setAuthor(Author author) {this.author = author;

}}

Assuming the validation process of the following book instance:

Author author = new Author();author.setLastName( "Baudelaire" );author.setFirstName( "" );Book book = new Book();book.setAuthor( author );

the validation routine will return the following failure:

• NotEmpty failure on the title field

As both title and author.lastname are checked as part of the first group. If the instance is updated:

book.setTitle( "Les fleurs du mal" );author.setCompany("Some random publisher with a very very very long name");

Constraint declaration and validation process

1.0.Beta1 (Early Draft Review 1) 19

the validation routine will return the following failures:

• author.firstName fails to pass the NotEmpty constraint

• author.company fails to pass the Length constraint

As the first and second groups pass without failure, the last group is going through validation.

Constraint declaration and validation process

1.0.Beta1 (Early Draft Review 1) 20

4Validation APIs

The default package for the Bean Validation APIs is javax.validation

4.1. Validator<T> API

The main Bean Validation API is the javax.validation.Validator<T> interface. Besides implementing the Val-

idator<T> API, the Bean Validation provider implementation of Validator<T> must have a constructor Validat-or(Class<T>).

A Validator<T> instance is able to validate instances of T classes (and the associated objects if any). It is recom-mended to cache Validator<T> instances. The Bean Validation provider has to guarantee that concurrent, multi-threaded access to a Validator<T> implementation are safe.

/*** Validate a given object type** @author Emmanuel Bernard*/

public interface Validator<T> {/*** validate all constraints on object** @param object object to validate* @param groups group name(s) targeted for validation (default to <code>default</code>)* @return invalid constrains or an empty Set if none* @throws IllegalArgumentException e if object is null*/Set<InvalidConstraint<T>> validate(T object, String... groups);

/*** validate all constraints on <code>propertyName</code> property of object*** @param object object to validate* @param propertyName property to validate* @param groups group name(s) targeted for validation (default to <code>default</code>)* @return invalid constrains or an empty Set if none* @throws IllegalArgumentException e if object is null*/Set<InvalidConstraint<T>> validateProperty(T object,

String propertyName,String... groups);

/*** validate all constraints on <code>propertyName</code> property* if the property value is <code>value</code>** TODO express limitations of InvalidConstraint in this case** @param propertyName property to validate

1.0.Beta1 (Early Draft Review 1) 21

* @param value property value to validate* @param groups group name(s) targeted for validation (default to <code>default</code>)* @return invalid constrains or an empty Set if none*/Set<InvalidConstraint<T>> validateValue(String propertyName,

Object value,String... groups);

[...]

}

4.1.1. Validation methods

Set<InvalidConstraint> validate(T object, String... groups) is used to validate a given object of type T

from a Validator<T> instance. This method implements the logic described in Section 3.5. A Set containing allInvalidConstraint representing the failing constraints is returned, an empty Set is returned otherwise.

Set<InvalidConstraint> validateProperty(T object, String propertyName, String... groups) validatesa given field or property of an object. The property name is the JavaBeans property name (as defined by the Java-Beans Introspector class). This method implements the logic described in Section 3.5 and apply it only to the givenproperty. @Valid is not honored by this method. This method is useful for partial object validation.

Set<InvalidConstraint> validateValue(String propertyName, Object value, String... groups) valid-ates the property referenced by propertyName, if the property value were value. This method implements the logicdescribed in Section 3.5 and apply it only to the given property and the given value. @Valid is not honored by thismethod. This method is useful for ahead of time validation.

4.1.1.1. Examples

All the examples will be based on the following class definition, constraint declarations and address instance.

public class Address {@NotNull @Length(max=30)private String addressline1;

@Length(max=30)private String addressline2;

private String zipCode;

private String city;

public String getAddressline1() {return addressline1;

}

public void setAddressline1(String addressline1) {this.addressline1 = addressline1;

}

public String getAddressline2() {return addressline2;

}

public void setAddressline2(String addressline2) {this.addressline2 = addressline2;

Validation APIs

1.0.Beta1 (Early Draft Review 1) 22

}

public String getZipCode() {return zipCode;

}

public void setZipCode(String zipCode) {this.zipCode = zipCode;

}

@Length(max=30) @NotNullpublic String getCity() {

return city;}

public void setCity(String city) {this.city = city;

}}

Address address = new Address();address.setAddressline1( null );address.setAddressline2( null );address.setCity("Llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch");//town in North Wales

Assuming a Validator<Address>, the following code will return three InvalidConstraint. One for addressline1violating NotNull, one for addressline2 violating NotNull and one for city violating Length.

validator.validate(address).length == 3

The following code will return one InvalidConstraint since city violates Length and only city is validated.

validator.validateProperty(address, "city").length == 1

The following code will return no InvalidConstraint because the value Paris for city would not raise any con-straint failure.

validator.validateValue("city", "Paris").length == 0

4.1.2. groups

The (list of) group(s) restricts the set of constraints applied. Only the constraint declarations targeting (see Sec-tion 2.1.1.2) one or more of the group(s) passed as a parameter to the validate, validateProperty and validate-

Value methods will be applied during the Section 3.5. If no group is passed, the default group is assumed.

4.1.2.1. Examples

public class Address {@NotEmpty(groups = "minimal")@Length(max=50)private String street1;

@NotEmptyprivate String city;

@NotEmpty(groups = {"minimal", "default"})private String zipCode;

Validation APIs

1.0.Beta1 (Early Draft Review 1) 23

...}

In the previous example, @NotEmpty on street1 applies to the group minimal, @Length on street1 applies to thegroup default and @NotEmpty on zipCode applies to the groups default and minimal.

validator.validate(address);

applies @Length on street1, @NotEmpty on city, @NotEmpty on zipCode. Particularly, @NotEmpty on street1 isnot applied.

validator.validate(address, "minimal");

applies @NotEmpty on street1 and @NotEmpty on zipCode

validator.validate(address, "minimal", "default");

applies @NotEmpty and @Length on street1, @NotEmpty on city, @NotEmpty on zipCode. Note that if zipCode isindeed not empty, only one InvalidConstraint object will represent the failure and the not empty validation willonly be executed once.

Let's look at a more complex example involving group sequence.

@GroupSequence(name="total", sequence={"firststep", "secondstep"})public class Address {

@NotEmpty(groups = "minimal")@Length(max=50, groups="firststep")private String street1;

@NotEmpty(groups="secondstep")private String city;

@NotEmpty(groups = {"minimal", "secondstep"})private String zipCode;...

}

When running:

validator.validate(address, "minimal", "total");

the validation process will process NotEmpty and Length from street1 and NotEmpty from zipCode. If Length

from street1 does not generate a failure, then NotEmpty from city will be processed. Note that NotEmpty fromzipCode is not reprocessed as it has already been processed before.

When running:

validator.validate(address, "total", "secondstep");

NotEmpty from city and NotEmpty from zipCode will be processed even if Length from street1 fails: whilesecondstep is in the total group sequence and hence should not be triggered if firststep has a failure, it also hasbeen requested outside the sequence (in this case explicitly).

Validation APIs

1.0.Beta1 (Early Draft Review 1) 24

4.2. InvalidConstraint

InvalidConstraint is the class describing a single constraint failure. An array of InvalidConstraint is returnedfrom an object validation.

/*** Describe a constraint validation defect** TODO add pointers to the metadata?** @author Emmanuel Bernard*/

public interface InvalidConstraint<T> {

/*** Error message*/String getMessage();

/*** Root bean being validated validated*/ T getRootBean();

/*** Bean type being validated*/Class getBeanClass();

/*** The value failing to pass the constraint*/Object getValue();

/*** the property path to the value from <code>rootBean</code>* Null if the value is the rootBean itself*/String getPropertyPath();

/*** return the list of groups that the triggered constraint applies on and witch also are* within the list of groups requested for validation* (directly or through a group sequence)* TODO: considering removal, if you think it's important, speak up*/String[] getGroups();

}

message return the expanded (localized) message for the failing constraint (See Section 4.3 for more informationon message expansion).

rootBean returns the root object being validated that leaded to the failing constraint (i.e. the object the client codepassed to the Validator.validate method.

beanClass returns the type of the current bean being validated and leading to the failure.

value returns the value (field, property or validated object) being passed to isValid and returning false.

propertyPath is defined by the following rules:

Validation APIs

1.0.Beta1 (Early Draft Review 1) 25

• if the constraint is a class level constraint, then the empty string is used

• if the constraint is a field level constraint, the field name is the propertyPath

• if the constraint is a property, the JavaBeans property name (as defined by the JavaBeans Introspector class) isthe propertyPath

• if an associated object is validated, add the association field or JavaBeans property name and a dot ('.') as a pre-fix to the previous rules. This rule is recursive.

Note

From rootBean and propertyPath, it is possible to rebuild the context of the failure

groups returns the intersection of the groups the triggered constraint applies on and the groups requested for valida-tion.

4.2.1. Example

public class Author {private String firstName;

@NotEmpty(message="lastname must not be null")private String lastName;

@Length(max=30)private String company;

public String getFirstName() {return firstName;

}

public void setFirstName(String firstName) {this.firstName = firstName;

}

public String getLastName() {return lastName;

}

public void setLastName(String lastName) {this.lastName = lastName;

}

public String getCompany() {return company;

}

public void setCompany(String company) {this.company = company;

}}

public class Book {@NotEmpty(groups={"firstlevelcheck", "default"})private String title;

@Valid@NotNullprivate Author author;

Validation APIs

1.0.Beta1 (Early Draft Review 1) 26

public String getTitle() {return title;

}

public void setTitle(String title) {this.title = title;

}

public Author getAuthor() {return author;

}

public void setAuthor(Author author) {this.author = author;

}}

Author author = new Author();author.setCompany("ACME");Book book = new Book();book.setTitle("");book.setAuthor(author);

Set<InvalidConstraint> invalidConstraints = validator.validate(book);

invalidConstraints is a set of size 2. One of the entries represent the failure of NotEmpty on the title property.

The invalidConstraint object for this failure passes the following assertions:

//assuming an english locale, the interpolated message is returnedassert "may not be null or empty".equals( invalidConstraint.getMessage() );assert book == invalidConstraint.getRootBean();assert Book.class == invalidConstraint.getBeanClass();//the offending valueassert book.getTitle().equals( invalidConstraint.getValue() );//the offending propertyassert "title".equals( invalidConstraint.getPropertyPath() );assert invalidConstraint.getGroups().length == 1

List expectedGroups = new ArrayList(1);expectedGroups.add("default");for ( String group : invalidConstraint.getGroups() ) {

assert expectedGroups.contains(group);}

The second failure, NotEmpty on the author's lastname, will produce the following InvalidConstraint object:

assert "lastname must not be null".equals( invalidConstraint.getMessage() );assert book == invalidConstraint.getRootBean();assert Author.class == invalidConstraint.getBeanClass();//the offending valueassert book.getAuthor().getLastName() == invalidConstraint.getValue();//the offending propertyassert "author.lastName".equals( invalidConstraint.getPropertyPath() );assert invalidConstraint.getGroups().length == 0

4.3. Message resolution

Validation APIs

1.0.Beta1 (Early Draft Review 1) 27

4.3.1. Default message resolution

A conforming implementation includes a default message resolver. This message resolver shall use the algorithmdefined here to resolve message descriptors into human-readable messages.

Each constraint defines a message descriptor via its message property. Every constraint definition shall define a de-fault message descriptor for that constraint. A particular use of a constraint can override the default messagedescriptor of the constraint by setting the message property on the constraint.

The message descriptor is a string literal and may contain one or more message parameters. Message parametersare string literals enclosed in braces.

4.3.1.1. Algorithm

The default message resolver begins by retrieving the message descriptor from the constraint. Message parametersare then replaced by repeatedly executing the steps listed below until no replacements are performed.

1. A message parameter that matches the name of a property of the constraint declaration is replaced by the valueof that property.

2. The message parameter is used as a key to search the ResourceBundle name ValidationMessage (often ma-terialized as the property file /ValidationMessages.properties and it's locale variations). If a property isfound, the message parameter is replaced with the property.

3. The message parameter is used as a key to search the default message resolver's built-in message properties. Ifa property is found, the message parameter is replaced with the property.

4.3.2. Custom message resolution

A custom message resolver may be provided (e.g., to resolve contextual data, or to adjust the Locale used). A mes-sage resolver implements the MessageResolver interface.

/*** Interpolate a given validation message** @author Emmanuel Bernard*/public interface MessageResolver {

/*** Generate a display the message based on the constraint and its parameters.*/String interpolate(String message,

ConstraintDescriptor constraintDescriptor,Object value);

}

message is the message descriptor as seen in @Annotation.message

constraintDescriptor is the ConstraintDescriptor object representing the metadata of the failing constraint(see Constraint metadata request API).

value is the value being validated.

Validation APIs

1.0.Beta1 (Early Draft Review 1) 28

MessageResolver.interpolate() is invoked once for each constraint whose isValid() method returns false.

A message resolver implementation shall be threadsafe.

The message resolver is injected to the validator instance through validat-

or.setMessageResolver(MessageResolver).

4.3.3. Examples

These examples describe message interpolation based on the default message resolver's built-in messages (see Ap-pendix B), and the ValidationMessages.properties file shown in table . The current locale is assumed English.

//ValidationMessages.propertiesmyapp.creditcard.error=Your credit card number is not valid

Table 4.1. message interpolation

Failing constraint declaration interpolated message

@NotNull may not be null

@Max(30) must be less than or equal to 30

@Length(min=5, max=15, message="Key must havebetween {min} and {max} characters")

Key must have between 5 and 15 characters

@Range(min=4, max=40) must be between 4 and 40

@CreditCard(message={myapp.creditcard.error}) Your credit card number is not valid

4.4. Bootstrapping

To be defined, will include a description of the Validation Bean provider discovery model (most likely inspired bythe service discovery model used in the JDK) as well as the Validator object factory.

Validation APIs

1.0.Beta1 (Early Draft Review 1) 29

5Constraint metadata request APIs

The Bean Validation specification provides a way to query the constraint repository. This API is expected to beused for tooling support as well as integration with other frameworks, libraries and JSRs: the Bean Validation is ex-pected to be the main object oriented constraint declaration repository, whose metadata are consumed by all com-ponent oriented or domain model oriented frameworks avoiding duplication at the platform level (EE or SE).

5.1. Validator<T>

The main API to access all metadata related to a given object is Validator<T> (see XX for more information onhow to retrieve a Validator instance).

A Validator<T> instance is the metadata repository for T classes. It is recommended to cache Validator<T> in-stances. The Bean Validation provider has to guarantee that concurrent, multi-threaded access to a Validator<T>

implementation is safe.

/*** Validate a given object type** @author Emmanuel Bernard*/

public interface Validator<T> {

[...] //See 4.1

/*** return true if at least one constraint declaration is present for the given bean* or if one property is marked for validation cascade*/boolean hasConstraints();

/*** return the class level constraints*/ElementDescriptor getBeanConstraints();

/*** return the property level constraints for a given propertyName* or null if either the property does not exist or has no constraint*/ElementDescriptor getConstraintsForProperty(String propertyName);

/*** return the property names having at least a constraint defined*/Set<String> getValidatedProperties();

}

hasConstraints returns true if the given T class has at least one constraint declared.

1.0.Beta1 (Early Draft Review 1) 30

getBeanConstraints returns an ElementDescriptor object describing the bean level constraints (seeSection 3.1.1).

getConstraintsForProperty returns an ElementDescriptor object describing the property level constraints (SeeSection 3.1.2). The property is uniquely identified by its name as per the JavaBeans convention: field level and get-ter level constraints of the given name are all returned.

getValidatedProperties returns the names of the bean properties having at least one constraint or being cascaded(@Valid annotation).

5.2. ElementDescriptor

ElementDescriptor is the object used to describe the list of constraints for a given element (whether it be a field, amethod or a class).

/*** Describes a validated element (class, field or property)** @author Emmanuel Bernard*/

public interface ElementDescriptor {/*** Element type*/ElementType getElementType();

/*** statically defined returned type* //TODO should it be Type or even completly removed*/Class getReturnType();

/*** is the association cascaded*/boolean isCascaded();

/*** all the constraint descriptors for the given element*/Set<ConstraintDescriptor> getConstraintDescriptors();

/*** Property path from the root entity validated.* //FIXME there is a problem in describing cyclic dependencies*/String getPropertyPath();

}

getElementType returns the java.lang.annotations.ElementType the constraint is declared on. The expectedtypes for the current version of the Bean Validation specification are:

• TYPE

• FIELD

Constraint metadata request APIs

1.0.Beta1 (Early Draft Review 1) 31

• METHOD

getReturnType returns either the object type for a class, or the returned type for a property (TODO problem ofgenerics resolution).

is cascaded returns true of the property is marked with @Valid. Class level element descriptors always returnfalse.

getPropertyPath returns the property path as described in Section 4.2.

getConstraintDescriptors returns the ConstraintDescriptors (see Section 5.3), each ConstraintDescriptor

describing one of the constraints declared on the given element.

5.3. ConstraintDescriptor

A ConstraintDescriptor object describes a given constraint declaration (i.e. a constraint annotation).

/*** describes a single constraint** @author Emmanuel Bernard*/

public interface ConstraintDescriptor {/*** Constraint declaration annotation*/Annotation getAnnotation();

/*** constraint parameters*/Map<String, Object> getParameters();

/*** What are the groups the constraint is applied on*/Set<String> getGroups();

/*** Return the constraint implementation routine*/Constraint getConstraintImplementation();

}

getAnnotation returns the annotation instance (or an annotation instance representing the given constraint declara-tion)

getParameters returns a map containing the annotation parameter names as a key, and the annotation parametervalues as a value (this API is anticipated to be simpler to use by tools that reflection over the annotation instance).

getGroups returns the group names, the constraint is supposed to be applied upon.

getConstraintImplementation returns the initialized and ready to use javax.validator.Constraint implement-ation for the given constraint declaration. Specifically, the StandardConstraintDescriptor is available if the con-straint validator implements StandardConstraint (see Section 2.5).

Constraint metadata request APIs

1.0.Beta1 (Early Draft Review 1) 32

5.4. Example

public class Author {private String firstName;

@NotEmpty(message="lastname must not be null")private String lastName;

@Length(max=30)private String company;

public String getFirstName() {return firstName;

}

public void setFirstName(String firstName) {this.firstName = firstName;

}

public String getLastName() {return lastName;

}

public String getCompany() {return company;

}

public void setCompany(String company) {this.company = company;

}}

public class Book {private String title;private String description;

@Valid@NotNullprivate Author author;

@NotEmpty(groups={"firstlevelcheck", "default"})@Length(max=30)public String getTitle() {

return title;}

public void setTitle(String title) {this.title = title;

}

public Author getAuthor() {return author;

}

public void setAuthor(Author author) {this.author = author;

}

public String getDescription() {return description;

}

public void setAuthor(String description) {this.description = description;

}

Constraint metadata request APIs

1.0.Beta1 (Early Draft Review 1) 33

}

assert bookValidator.hasConstraints();

ElementDescriptor bookBeanDescriptor = bookValidator.getBeanConstraints();assert bookBeanDescriptor.getElementType() == ElementType.TYPE;assert bookBeanDescriptor.getConstraintDescriptors().size() == 0 //no constraintassert "".equals( bookBeanDescriptor.getPropertyPath() ); //root element

//more specifically "author" and "title"assert bookValidator.getValidatedProperties().size() == 2;

//not a propertyassert bookValidator.getConstraintsForProperty("doesNotExist") == null;//property with no constraintassert bookValidator.getConstraintsForProperty("description") == null;

ElementDescriptor propertyDescriptor = bookValidator.getConstraintsForProperty("title");assert propertyDescriptor.getElementType() == ElementType.METHOD;assert propertyDescriptor.getConstraintDescriptors().size() == 2assert "title".equals( propertyDescriptor.getPropertyPath() );

//assuming the implementation returns the NotEmpty constraint firstConstraintDescriptor constraintDescriptor = propertyDescriptor.getConstraintDescriptors()

.iterator().next();assert constraintDescriptor.getAnnotation().getAnnotationType().equals( NotEmpty.class );assert constraintDescriptor.getGroups().size() == 2; //"firstlevelcheck" and "default"assert constraintDescriptor.getConstraintImplementation() instanceof StandardConstraint;StandardConstraint standardConstraint =

(StandardConstraint) constraintDescriptor.getConstraintImplementation();//@NotEmpty cannot be nullassert ! standardConstraint.getStandardConstraints().getNullability();

//assuming the implementation returns the Length constraint secondconstraintDescriptor = bookBeanDescriptor.getConstraintDescriptors().iterator().next().next();assert constraintDescriptor.getAnnotation().getAnnotationType().equals( Length.class );assert constraintDescriptor.getParameters().get("max") == 30;assert constraintDescriptor.getGroups().length == 0;

propertyDescriptor = bookValidator.getConstraintsForProperty("author");assert propertyDescriptor.getConstraintDescriptors().size() == 1assert propertyDescriptor.isCascaded()

Constraint metadata request APIs

1.0.Beta1 (Early Draft Review 1) 34

6Built-in Constraint definitions

Some basic constraint definitions will be included later in the specification.

1.0.Beta1 (Early Draft Review 1) 35

7XML deployment descriptor

7.1.

1.0.Beta1 (Early Draft Review 1) 36

ATerminology

This appendix aims at giving an overview on the different specific terms used through this specification. There arenot to be considered formal definitions. Formal definitions are to be inferred from the core specification.

Table A.1. terminology

Term Definition

Constraint A restriction on a bean instance, the value of a fieldor the value of a JavaBean property

Constraint declaration Assignment of a constraint on a target (bean, field,property) for a specific class. Typically by declaringan annotation on the target but can also be donethrough a deployment descriptor in XML

Validation routineImplementation of the validation algorithm associatedto a given constraint

also means, sequence of operations executed by theBean Validation provider to validate a given object

Constraint definition Defines a type of constraint, it's attributes and the ac-tual constraint implementation. Usually done throughannotations, this definition can also be done throughXML

group Constraints can belong to one or more group or con-text. Useful to apply a subset of the constraints for agiven use case. By default, the default group is used.

group sequence Define a group ordering in the validation process. If agiven ordered group contains one or more failure, thefollowing ones in the sequence must be ignored.

Constraint validation constraint logic algorithm used to determine whethera given value pass a constraint or not.

Constraint validation implementation Class implementing the constraint logic and used todetermine whether a given value pass a constraint ornot.

Validation API Main API used to validate a given type of bean

Bean validation provider Implementation of the specification

1.0.Beta1 (Early Draft Review 1) 37

Term Definition

Message resolver Algorithm used to build the end user message associ-ated to a constraint failure. Typically useful for i18n

Constraint repository API API exposing the constraints applied to a given beantype. Also considered one of the integration pointswith other JSR or frameworks.

javax.validation.Constraint interface implemented by a constraint validation im-plementation

javax.validation.StandardConstraint optional interface implemented by a constraint valida-tion implementation. Used to express standard con-straint dimensions

javax.validation.Validator Main interface for the validation API

javax.validation.InvalidConstraint interface describing a given constraint failure on agiven bean

Terminology

1.0.Beta1 (Early Draft Review 1) 38

BStandard resolver messages

The properties listed below are resolved by the default message resolver.

beancheck.length=length must be between {min} and {max}beancheck.max=must be less than or equal to {value}beancheck.min=must be greater than or equal to {value}beancheck.notNull=may not be nullbeancheck.range=must be between {min} and {max}beancheck.size=size must be between {min} and {max}beancheck.email=not a well-formed email addressbeancheck.notEmpty=may not be null or emptybeancheck.creditCard=Invalid credit card number

1.0.Beta1 (Early Draft Review 1) 39