Help

Until now, it was not possible or easy to reuse constraints to make more complex constraints.

The new specification draft introduces the notion of constraint composition. Composition is useful for three main things:

  • reuse more primitive constraints to build new constraints and avoid duplication
  • define fine grained error reports for a given constraint
  • expose how a constraint is composed and describe its primitive blocks

The last point is particularly interesting. Constraints implementations are black boxes answering yes or no to the question: Is this value valid or not?. When constraints need to be applied outside the Java world or applied on a different metadata model, black boxes do no good. There is no way to know that @OrderNumber actually apply some restriction on the length of the number as well as apply some CRC verification.

Composition helps to solve the problem by giving access to the primitive constituencies of a constraint. Let's first see how to define a composed constraint.

Defining a composed constraint

To define the list of constraints composing a main constraint, simply annotate the main constraint annotation with the composing constraint annotations.

@Numerical
@Size(min=5, max=5)
@ConstraintValidator(FrenchZipcodeValidator.class)
@Documented
@Target({ANNOTATION_TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface FrenchZipCode {
    String message() default "Wrong zipcode";
    String[] groups() default {};
}

When @FrenchZipCode is placed on a property, its value is validated against @Numerical, @Size(min=5, max=5) and the constraint implementation FrenchZipcodeValidator: all the composing constraints are validated as well as the logic of the main constraint. Note that a composing constraint can itself be composed of constraints.

Each failing constraint will generate an individual error report which is useful when you want do display fine grained reports to your user. But this might be quite confusing and a single error report is more appropriate in some situations. You can force Bean Validation to raise a single error report (the composed constraint error report) if any of its composing constraint fails by using the @ReportAsSingleInvalidConstraint annotation.

@Numerical
@Size(min=5, max=5)
@ReportAsSingleInvalidConstraint
@ConstraintValidator(FrenchZipcodeValidator.class)
@Documented
@Target({ANNOTATION_TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface FrenchZipCode {
    String message() default "Wrong zipcode";
    String[] groups() default {};
}

In the past two examples, none of the composing annotation parameters can be adjusted at declaration time. This is fine if the zip code is always of size 5. But what happens if the size can be adjusted depending on the property? The spec offers a way is a way to override a parameter from the composing annotation based on a parameter from the composied annotation using the @OverridesParameter annotation.

@Numerical
@Size //arbitrary parameter values
@ConstraintValidator(FrenchZipcodeValidator.class)
@Documented
@Target({ANNOTATION_TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface FrenchZipCode {
    String message() default "Wrong zipcode";
    String[] groups() default {};
    
    @OverridesParameters( {
        @OverridesParameter(constraint=Size.class, parameter="min")
        @OverridesParameter(constraint=Size.class, parameter="max") } )
    int size() default 5;

    @OverridesParameter(constraint=Size.class, parameter="message")
    String sizeMessage() default "{error.zipcode.size}";

    @OverridesParameter(constraint=Numerical.class, parameter="message")
    String numericalMessage() default "{error.zipcode.numerical}";
}

The following declaration

@FrenchZipcode(size=9, sizeMessage="Zipcode should be of size {value}")

is equivalent to the following definition / declaration combination

@Numerical
@Size(min=9, max=9, message="Zipcode should be of size {value}")
@ConstraintValidator(FrenchZipcodeValidator.class)
@Documented
@Target({ANNOTATION_TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface FrenchZipCode {
    String message() default "Wrong zipcode";
    String[] groups() default {};
}

Let's now see how a tool would use this extra information.

Exploring composed constraints with the metadata API

Using the metadata API, you can explore the list of constraints on a given object or property. Each constraint is described by a ConstraintDescriptor. It lists all the composing constraints and provides a ConstraintDescriptor object for each. The ConstraintDescriptor honors overridden parameters (ie using @OverridesParameter): the annotation and the parameter values returned contain the overridden value.

ElementDescriptor ed = addressValidator.getConstraintsForProperty("zipcode");
for ( processConstraintDescriptor cd : ed.getConstraintDescriptors() ) {
	processConstraintDescriptor(cd); //check all constraints on zip code
}

public void processConstraintDescriptor(processConstraintDescriptor cd) {
	//Size.class is understood by the tool
	if ( cd.getAnnotation().getAnnotationType().equals( Size.class ) ) {
		Size m = (Size) cd.getAnnotation();
		column.setLength( m.max() );  //read and use the metadata
	}
	for (ConstraintDescriptor composingCd : cd.getComposingConstraints() ) {
		processConstraintDescriptor(cd); //check composing constraints recursively
	}
}

When using the following declaration

@FrenchZipCode(size=10) public String zipCode;

the tool will set the zipCode column length to 10.

While the tool does not know what @FrenchZipCode and @Numerical means, it knows how to make use of @Max. Javascript generation libraries or persistence tools typically understand a core subset of constraints. If a complex constraint is composed of one or several of these core subset constraints, it can be partially understood and processed by Java Persistence for example.

This is one of the reasons why it is strongly recommended to build complex constraints on top of more primitive ones. The Bean Validation specification will come with a core of constraints tools will be able to rely upon.

Let us know what you think in our forum.

4 comments:
 
29. Oct 2008, 15:09 CET | Link
The new specification draft introduces the notion of constraint composition.

I checked out the reference implementation and I noticed quite a lot of API changes (of which I like some of them, while others seem no improvement for me at the moment, for example ConstraintDescriptor.getContstraintClass instead of former ConstraintDescriptor.getConstraintImplementation).

I also could have done without composed constraints, because I never had such a requirement and I am afraid of the annotation hell that this is introducing, especially what comes with OverridesParameter. I see the implementation already in the SVN-repository, but what I am really missing is the new specification draft as a download somewhere (preferrably on http://jcp.org/aboutJava/communityprocess/edr/jsr303/). Where is it? (I would need it to read something about the newly introduced javax.validation.Context etc.)

ReplyQuote
 
20. Jul 2014, 07:11 CET | Link
adeline | ddeeqz(AT)163.com

One thing is to hook your mind old-fashioned variety of chanel hadnbags. Issues the imminent chanel 2 . 5.55 bags and many other classical, stood the analysis, however it's still considered the best and most famous fashion bring. Let the bag? Hope that if a manufacturer for their place. Whatever happens, happens ralph lauren outlet are very wise, and any one 3 months, there greater level of complex ways of thinking. Initially all, there is a wise choice, then obviously the leather, there are much of planning and clever, walking previously plan. There is the bag in completed design, associated with support of hardware along with the cassette.

Every factor from its design, style, size and, most importantly, its material are all taken into consideration by the potential customer. Surprisingly, it's not just women chanel outlet online who pay focus detail due to comes to picking a hard-wearing, practical and stylish bags. Significantly if one takes into deliberation the wide range of brands and prices in today's market, the definition of an ideal bags will changes from person to person.

Another fine way locate vintage Juicy couture handbags is invest to garage, yard, and church product sales. Lots of times sufferers do not want to keep stuff around and rolex replica watches are clueless a vintage purse once they have a particular. Do a little research and will probably go the distance! One woman's garbage 1 other woman's resource!

Similarly, Burberry handbags are typically designed to use any involving outfit, you may be going to put them utilizing casual outfits of business attire, nonetheless replica hublot gives you that remarkable sophisticated, ageless look. That is definitely money spent well when opt for these two elegant can make.

 
29. Aug 2014, 06:26 CET | Link
obat herbal k-muricata

Now i'm actively working on an assignment and I have been exploring your website for a couple of hours. Thank you for your it proved worthwhile for me. obat herbal k-muricata

 
26. Sep 2014, 09:39 CET | Link
obat kanker paru paru

amazon Obat Tradisional Penyaki Kanker Paru-paru - obat kanker paru paru

Post Comment