-
Notifications
You must be signed in to change notification settings - Fork 566
/
customoptions.xml
718 lines (581 loc) · 30.4 KB
/
customoptions.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ JBoss, Home of Professional Open Source
~ Copyright 2009, Red Hat, Inc. and/or its affiliates, and individual contributors
~ by the @authors tag. See the copyright.txt in the distribution for a
~ full listing of individual contributors.
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~ http://www.apache.org/licenses/LICENSE-2.0
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % BOOK_ENTITIES SYSTEM "../hv.ent">
%BOOK_ENTITIES;
]>
<chapter id="validator-specifics">
<title>Hibernate Validator Specifics</title>
<para>In the following sections we are having a closer look at some of the
Hibernate Validator specific features (features which are not part of the
Bean Validation specification). This includes the fail fast mode, the
programmatic constraint configuration API and boolean composition of
composing constraints.</para>
<note>
<para>The features described in the following sections are not portable
between Bean Validation providers/implementations.</para>
</note>
<section>
<title>Public API</title>
<para>Let's start, however, with a look at the public API of Hibernate
Validator. <xref linkend="validator-public-api" /> lists all packages
belonging to this API and describes their purpose.</para>
<para>Any packages not listed in that table are internal packages of
Hibernate Validator and are not intended to be accessed by clients. The
contents of these internal packages can change from release to release
without notice, thus possibly breaking any client code relying on
it.</para>
<note>
<para>In the following table, when a package is public its not
necessarily true for its nested packages.</para>
</note>
<table id="validator-public-api">
<title>Hibernate Validator public API</title>
<tgroup cols="2">
<thead>
<row>
<entry>Packages</entry>
<entry>Description</entry>
</row>
</thead>
<tbody valign="top">
<row>
<entry><package>org.hibernate.validator</package></entry>
<entry>This package contains the classes used by the Bean
Validation bootstrap mechanism (eg. validation provider,
configuration class). For more details see <xref
linkend="validator-bootstrapping" />.</entry>
</row>
<row>
<entry><package>org.hibernate.validator.cfg</package>,
<package>org.hibernate.validator.cfg.context</package>,
<package>org.hibernate.validator.cfg.defs</package></entry>
<entry>With Hibernate Validator you can define constraints via a
fluent API. These packages contain all classes needed to use this
feature. In the package
<package>org.hibernate.validator.cfg</package> you will find the
<classname>ConstraintMapping</classname> class and in package
<package>org.hibernate.validator.cfg.defs</package> all constraint
definitions. For more details see <xref
linkend="programmaticapi" />.</entry>
</row>
<row>
<entry><package>org.hibernate.validator.constraints</package></entry>
<entry>In addition to Bean Validation constraints, Hibernate
Validator provides some useful custom constraints. This package
contains all custom annotation classes. For more details see <xref
linkend="validator-defineconstraints-hv-constraints" />.</entry>
</row>
<row>
<entry><package>org.hibernate.validator.group</package></entry>
<entry>With Hibernate Validator you can define dynamic default
group sequences in function of the validated object state. This
package contains all classes needed to use this feature
(<classname>GroupSequenceProvider</classname> annotation and
<classname>DefaultGroupSequenceProvider</classname> contract). For
more details see <xref
linkend="section-default-group-class" />.</entry>
</row>
<row>
<entry><package>org.hibernate.validator.messageinterpolation</package>,
<package>org.hibernate.validator.resourceloading</package></entry>
<entry>These packages contain the classes related to constraint
message interpolation. The first package contains two
implementations of <classname>MessageInterpolator</classname>. The
first one,
<classname>ValueFormatterMessageInterpolator</classname> allows to
interpolate the validated value into the constraint message, see
<xref linkend="section-message-interpolator" />. The second
implementation named
<classname>ResourceBundleMessageInterpolator</classname> is the
implementation used by default by Hibernate Validator. This
implementation relies on a
<classname>ResourceBundleLocator</classname>, see <xref
linkend="section-resource-bundle-locator" />. Hibernate Validator
provides different <classname>ResourceBundleLocator</classname>
implementations located in the package
<package>org.hibernate.validator.resourceloading</package>.</entry>
</row>
<row>
<entry><package>org.hibernate.validator.method</package>,
<package>org.hibernate.validator.method.metadata</package></entry>
<entry>Hibernate Validator provides support for method-level
constraints based on appendix C of the Bean Validation
specification. The first package contains the
<classname>MethodValidator</classname> interface allowing you to
validate method return values and parameters. The second package
contains meta data for constraints hosted on parameters and
methods which can be retrieved via the
<classname>MethodValidator</classname>.</entry>
</row>
</tbody>
</tgroup>
</table>
</section>
<section>
<title>Fail fast mode</title>
<para>First off, the fail fast mode. Hibernate Validator allows to return
from the current validation as soon as the first constraint violation
occurs. This is called the <emphasis>fail fast mode</emphasis> and can be
useful for validation of large object graphs where one is only interested
whether there is a constraint violation or not. <xref
linkend="example-fail-fast-property" />, <xref
linkend="example-fail-fast-configuration" /> and <xref
linkend="example-fail-fast-factory" /> show multiple ways to enable the
fail fast mode.</para>
<example floatstyle="" id="example-fail-fast-property">
<title>Enabling <option>failFast</option> via a property</title>
<programlisting language="" role="">HibernateValidatorConfiguration configuration = Validation.byProvider( HibernateValidator.class ).configure();
ValidatorFactory factory = configuration.addProperty( "hibernate.validator.fail_fast", "true" ).buildValidatorFactory();
Validator validator = factory.getValidator();
// do some actual fail fast validation
...</programlisting>
</example>
<example id="example-fail-fast-configuration">
<title>Enabling <option>failFast</option> at the
<classname>Configuration</classname> level</title>
<programlisting lang="">HibernateValidatorConfiguration configuration = Validation.byProvider( HibernateValidator.class ).configure();
ValidatorFactory factory = configuration.failFast( true ).buildValidatorFactory();
Validator validator = factory.getValidator();
// do some actual fail fast validation
...</programlisting>
</example>
<example id="example-fail-fast-factory">
<title>Enabling <option>failFast</option> at the
<classname>ValidatorFactory</classname> level</title>
<programlisting language="" role="">HibernateValidatorConfiguration configuration = Validation.byProvider( HibernateValidator.class ).configure();
ValidatorFactory factory = configuration.buildValidatorFactory();
Validator validator = factory.getValidator();
// do some non fail fast validation
...
validator = factory.unwrap( HibernateValidatorFactory.class )
.usingContext()
.failFast( true )
.getValidator();
// do fail fast validation
...</programlisting>
</example>
</section>
<section id="validator-customoptions-methodvalidation">
<title>Method validation</title>
<para>The Bean Validation API allows to specify constraints for fields,
properties and types. Hibernate Validator goes one step further and allows
to place contraint annotations also on method parameters and method return
values, thus enabling a programming style known as "Programming by
Contract".</para>
<para>More specifically this means that Bean Validation constraints can be
used to specify</para>
<itemizedlist>
<listitem>
<para>the preconditions that must be met before a method invocation
(by annotating method parameters with constraints) and</para>
</listitem>
<listitem>
<para>the postconditions that are guaranteed after a method invocation
(by annotating methods)</para>
</listitem>
</itemizedlist>
<para>This approach has several advantages over traditional ways of
parameter and return value checking:</para>
<itemizedlist>
<listitem>
<para>The checks don't have to be performed manually (e.g. by throwing
<classname>IllegalArgumentExceptions</classname> or similar),
resulting in less code to write and maintain.</para>
</listitem>
<listitem>
<para>A method's pre- and postconditions don't have to be expressed
again in the method's JavaDoc, since the constraint annotations will
automatically be included in the generated JavaDoc. This avoids
redundancy and reduces the chance of inconsistencies between
implementation and documentation.</para>
</listitem>
</itemizedlist>
<note>
<para>Method validation was also considered to be included in the Bean
Validation API as defined by JSR 303, but it didn't become part of the
1.0 version. A basic draft is outlined in appendix C of the
specification, and the implementation in Hibernate Validator is largely
influenced by this draft. The feature is considered again for inclusion
in BV 1.1.</para>
</note>
<section>
<title>Defining method-level constraints</title>
<para><xref lang="" linkend="example-method-constraints" /> demonstrates
the definition of method-level constraints.<example
id="example-method-constraints">
<title>Using method-level constraints</title>
<programlisting language="" role="">public class RentalStation {
@NotNull
public Car rentCar(@NotNull Customer customer, @NotNull @Future Date startDate, @Min(1) int durationInDays) {
//...
}
}</programlisting>
</example></para>
<para>Here the following pre- and postconditions for the
<methodname>rentCar()</methodname> method are declared:</para>
<itemizedlist>
<listitem>
<para>The renting customer may not be null</para>
</listitem>
<listitem>
<para>The rental's start date must not be null and must be in the
future</para>
</listitem>
<listitem>
<para>The rental duration must be at least one day</para>
</listitem>
<listitem>
<para>The returned <classname>Car</classname> instance may not be
null</para>
</listitem>
</itemizedlist>
<para>Using the <classname>@Valid</classname> annotation it's also
possible to define that a cascaded validation of parameter or return
value objects shall be performed. An example can be found in <xref
lang="" linkend="example-cascaded-method-constraints" />.</para>
<example id="example-cascaded-method-constraints">
<title>Cascaded validation of method-level constraints</title>
<programlisting language="" role="">public class RentalStation {
@Valid
public Set<Rental> getRentalsByCustomer(@Valid Customer customer) {
//...
}
}</programlisting>
</example>
<para>Here all the constraints declared at the
<classname>Customer</classname> type will be evaluated when validating
the method parameter and all constraints declared at the returned
<classname>Rental</classname> objects will be evaluated when validating
the method's return value.</para>
<section>
<title>Using method constraints in type hierarchies</title>
<para>Special care must be taken when defining parameter constraints
in inheritance hierarchies.</para>
<para>When a method is overridden in sub-types method parameter
constraints can only be declared at the base type. The reason for this
restriction is that the preconditions to be fulfilled by a type's
client must not be strengthened in sub-types (which may not even be
known to the base type's client). Note that also if the base method
doesn't declare any parameter constraints at all, no parameter
constraints may be added in overriding methods.</para>
<para>The same restriction applies to interface methods: no parameter
constraints may be defined at the implementing method (or the same
method declared in sub-interfaces).</para>
<para>If a violation of this rule is detected by the validation
engine, a
<classname>javax.validation.ConstraintDeclarationException</classname>
will be thrown. In <xref lang=""
linkend="example-illegal-method-constraints" /> some examples for
illegal parameter constraints declarations are shown.</para>
<example id="example-illegal-method-constraints">
<title>Illegal parameter constraint declarations</title>
<programlisting>public class Car {
public void drive(Person driver) { ... }
}
public class RentalCar extends Car {
//not allowed, parameter constraint added in overriding method
public void drive(@NotNull Person driver) { ... }
}
public interface ICar {
void drive(Person driver);
}
public class CarImpl implements ICar {
//not allowed, parameter constraint added in implementation of interface method
public void drive(@NotNull Person driver) { ... }
}</programlisting>
</example>
<para>This rule only applies to parameter constraints, return value
constraints may be added in sub-types without any restrictions as it
is alright to strengthen the postconditions guaranteed to a type's
client.</para>
</section>
</section>
<section>
<title>Evaluating method-level constraints</title>
<para>To validate method-level constraints Hibernate Validator provides
the interface
<classname>org.hibernate.validator.method.MethodValidator</classname>.</para>
<para>As shown in <xref lang="" linkend="example-methodvalidator" />
this interface defines methods for the evaluation of parameter as well
as return value constraints and for retrieving an extended type
descriptor providing method constraint related meta data.</para>
<example id="example-methodvalidator">
<title>The <classname>MethodValidator</classname> interface</title>
<programlisting language="" role="">public interface MethodValidator {
<T> Set<MethodConstraintViolation<T>> validateParameter(T object, Method method, Object parameterValue, int parameterIndex, Class<?>... groups);
<T> Set<MethodConstraintViolation<T>> validateAllParameters(T object, Method method, Object[] parameterValues, Class<?>... groups);
<T> Set<MethodConstraintViolation<T>> validateReturnValue(T object, Method method, Object returnValue, Class<?>... groups);
TypeDescriptor getConstraintsForType(Class<?> clazz);
} </programlisting>
</example>
<para>To retrieve a method validator get hold of an instance of HV's
<classname>javax.validation.Validator</classname> implementation and
unwrap it to <classname>MethodValidator</classname> as shown in <xref
lang="" linkend="example-retrieving-methodvalidator" />.</para>
<example id="example-retrieving-methodvalidator">
<title>Retrieving a <classname>MethodValidator</classname>
instance</title>
<programlisting language="" role="">MethodValidator methodValidator = Validation.byProvider( HibernateValidator.class )
.configure()
.buildValidatorFactory()
.getValidator()
.unwrap( MethodValidator.class ); </programlisting>
</example>
<para>The validation methods defined on
<classname>MethodValidator</classname> each return a
<classname>Set<MethodConstraintViolation></classname>. The type
<classname>MethodConstraintViolation</classname> (see <xref lang=""
linkend="example-methodconstraintviolation" />) extends
<classname>javax.validation.ConstraintViolation</classname> and provides
additional method level validation specific information such as the
method and index of the parameter which caused the constraint
violation.</para>
<example id="example-methodconstraintviolation">
<title>The <classname>MethodConstraintViolation</classname>
type</title>
<programlisting language="" role="">public interface MethodConstraintViolation<T> extends ConstraintViolation<T> {
public static enum Kind { PARAMETER, RETURN_VALUE }
Method getMethod();
Integer getParameterIndex();
String getParameterName();
Kind getKind();
}</programlisting>
</example>
<note>
<para>The method <methodname>getParameterName()</methodname> currently
returns synthetic parameter identifiers such as "arg0", "arg1" etc. In
a future version of Hibernate Validator support for specifying
parameter identifiers might be added.</para>
</note>
<para>Typically the validation of method-level constraints is not
invoked manually but automatically upon method invocation by an
integration layer using AOP (aspect-oriented programming) or similar
method interception facilities such as the JDK's
<classname>java.lang.reflect.Proxy</classname> API or CDI ("JSR 299:
Contexts and Dependency Injection for the
Java<superscript>TM</superscript> EE platform").</para>
<para>If a parameter or return value constraint can't be validated
sucessfully such an integration layer typically will throw a
<classname>MethodConstraintViolationException</classname> which similar
to <classname>javax.validation.ConstraintViolationException</classname>
contains a set with the occurred constraint violations.</para>
<tip>
<para>If you are using CDI you might be interested in the <ulink
url="http://seamframework.org/Seam3/ValidationModule">Seam
Validation</ulink> project. This Seam module provides an interceptor
which integrates the method validation functionality with CDI.</para>
</tip>
</section>
<section>
<title>Retrieving method-level constraint meta data</title>
<para>As outlined in <xref lang="" linkend="validator-metadata-api" />
the Bean Validation API provides rich capabilities for retrieving
constraint related meta data. Hibernate Validator extends this API and
allows to retrieve constraint meta data also for method-level
constraints.</para>
<para><xref lang="" linkend="example-method-level-meta-data" /> shows
how to use this extended API to retrieve constraint meta data for the
<methodname>rentCar()</methodname> method from the
<classname>RentalStation</classname> type.</para>
<example id="example-method-level-meta-data">
<title>Retrieving meta data for method-level constraints</title>
<programlisting language="" role="">TypeDescriptor typeDescriptor = methodValidator.getConstraintsForType(RentalStation.class)
//retrieve a descriptor for the rentCar() method
MethodDescriptor rentCarMethod = typeDescriptor.getConstraintsForMethod("rentCar", Customer.class, Date.class, int.class);
assertEquals(rentCarMethod.getMethodName(), "rentCar");
assertTrue(rentCarMethod.hasConstraints());
assertFalse(rentCarMethod.isCascaded());
//retrieve constraints from the return value
Set<ConstraintDescriptor<?>> returnValueConstraints = rentCarMethod.findConstraints().getConstraintDescriptors();
assertEquals(returnValueConstraints.size(), 1);
assertEquals(returnValueConstraints.iterator().next().getAnnotation().annotationType(), NotNull.class);
List<ParameterDescriptor> allParameters = rentCarMethod.getParameterDescriptors();
assertEquals(allParameters.size(), 3);
//retrieve a descriptor for the startDate parameter
ParameterDescriptor startDateParameter = allParameters.get(1);
assertEquals(startDateParameter.getIndex(), 1);
assertFalse(startDateParameter.isCascaded());
assertEquals(startDateParameter.findConstraints().getConstraintDescriptors().size(), 2);</programlisting>
</example>
<para>Refer to the <ulink
url="http://docs.jboss.org/hibernate/validator/4.2/api/index.html?org/hibernate/validator/method/metadata/package-summary.html">JavaDoc</ulink>
of the package
<classname>org.hibernate.validator.method.metadata</classname> for more
details on the extended meta data API.</para>
</section>
</section>
<section id="programmaticapi">
<title>Programmatic constraint definition</title>
<para>Another addition to the Bean Validation specification is the ability
to configure constraints via a fluent API. This API can be used
exclusively or in combination with annotations and xml. If used in
combination programmatic constraints are additive to constraints
configured via the standard configuration capabilities.</para>
<para>The API is centered around the
<classname>ConstraintMapping</classname> class which can be found in the
package<package> org.hibernate.validator.cfg</package>. Starting with the
instantiation of a new <classname>ConstraintMapping</classname>,
constraints can be defined in a fluent manner as shown in <xref lang=""
linkend="example-constraint-mapping" />.</para>
<para><example id="example-constraint-mapping">
<title>Programmatic constraint definition</title>
<programlisting language="" role="">ConstraintMapping mapping = new ConstraintMapping();
mapping.type( Car.class )
.property( "manufacturer", FIELD )
.constraint( new NotNullDef() )
.property( "licensePlate", FIELD )
.constraint( new NotNullDef() )
.constraint( new SizeDef().min( 2 ).max( 14 ) )
.property( "seatCount", FIELD )
.constraint( new MinDef()value ( 2 ) )
.type( RentalCar.class )
.property( "rentalStation", METHOD )
.constraint( new NotNullDef() ); </programlisting>
</example></para>
<para>As you can see constraints can be configured on multiple classes and
properties using method chaining. The constraint definition classes
<classname>NotNullDef</classname>, <classname>SizeDef</classname> and
<classname>MinDef</classname> are helper classes which allow to configure
constraint parameters in a type-safe fashion. Definition classes exist for
all built-in constraints in the
<classname>org.hibernate.validator.cfg.defs</classname> package.</para>
<para>For custom constraints you can either create your own definition
classes extending <classname>ConstraintDef</classname> or you can use
<classname>GenericConstraintDef</classname> as seen in <xref
linkend="example-generic-constraint-mapping" />.</para>
<para><example id="example-generic-constraint-mapping">
<title>Programmatic constraint definition using
<methodname>createGeneric()</methodname></title>
<programlisting language="" role="">ConstraintMapping mapping = new ConstraintMapping();
mapping.type( Car.class )
.property( "licensePlate", FIELD )
.constraint( new GenericConstraintDef<CheckCase.class>( CheckCase.class ).param( "value", CaseMode.UPPER ) ); </programlisting>
</example></para>
<para>Not only standard class- and property-level constraints but also
method constraints can be configured using the API. As shown in <xref
lang="" linkend="example-method-constraint-mapping" /> methods are
identified by their name and their parameters (if there are any). Having
selected a method, constraints can be placed on the method's parameters
and/or return value.</para>
<example id="example-method-constraint-mapping">
<title>Programmatic definition of method constraints</title>
<programlisting language="" role="">ConstraintMapping mapping = new ConstraintMapping();
mapping.type( Car.class )
.method( "drive", String.class, Integer.class )
.parameter( 0 )
.constraint( new NotNullDef() )
.constraint( new MinDef().value ( 1 ) )
.parameter( 1 )
.constraint( new NotNullDef() )
.returnValue()
.constraint( new NotNullDef() )
.method( "check" )
.returnValue()
.constraint( new NotNullDef() ); </programlisting>
</example>
<para>Using the API it's also possible to mark properties, method
parameters and method return values as cascading (equivalent to annotating
them with <classname>@Valid</classname>). An example can be found in <xref
lang="" linkend="example-cascading-constraints" />.</para>
<para><example id="example-cascading-constraints">
<title>Marking constraints for cascaded validation</title>
<programlisting language="" role="">ConstraintMapping mapping = new ConstraintMapping();
mapping.type( Car.class )
.property( "manufacturer", FIELD )
.valid()
.property( "licensePlate", METHOD )
.valid()
.method( "drive", String.class, Integer.class )
.parameter( 0 )
.valid()
.parameter( 1 )
.valid()
.returnValue()
.valid()
.type( RentalCar.class )
.property( "rentalStation", METHOD )
.valid();</programlisting>
</example></para>
<para>Last but not least you can configure the default group sequence or
the default group sequence provider of a type as shown in <xref lang=""
linkend="example-sequences" />.<example id="example-sequences">
<title>Configuration of default group sequence and default group
sequence provider</title>
<programlisting language="" role="">ConstraintMapping mapping = new ConstraintMapping();
mapping.type( Car.class )
.defaultGroupSequence( Car.class, CarChecks.class )
.type( RentalCar.class )
.defaultGroupSequenceProvider( RentalCarGroupSequenceProvider.class ); </programlisting>
</example></para>
<para>Once a <classname>ConstraintMapping</classname> is set up it has to
be passed to the configuration. Since the programmatic API is not part of
the official Bean Validation specification you need to get hold of a
<classname>HibernateValidatorConfiguration</classname> instance as shown
in <xref linkend="example-hibernate-specific-config" />.</para>
<para><example id="example-hibernate-specific-config">
<title>Creating a Hibernate Validator specific configuration</title>
<programlisting lang="" language="" role="">ConstraintMapping mapping = new ConstraintMapping();
// configure mapping instance
HibernateValidatorConfiguration config = Validation.byProvider( HibernateValidator.class ).configure();
config.addMapping( mapping );
ValidatorFactory factory = config.buildValidatorFactory();
Validator validator = factory.getValidator();</programlisting>
</example></para>
</section>
<section>
<title>Boolean composition for constraint composition</title>
<para>As per Bean Validation specification the constraints of a composed
constraint (see <xref linkend="section-constraint-composition" />) are all
combined via a logical <emphasis>AND</emphasis>. This means all of the
composing constraints need to return <constant>true</constant> in order
for an overall successful validation. Hibernate Validator offers an
extension to this logical <emphasis>AND</emphasis> combination which
allows you to compose constraints via a logical <emphasis>OR</emphasis> or
<emphasis>NOT</emphasis>. To do so you have to use the
<classname>ConstraintComposition</classname> annotation and the enum
<classname>CompositionType</classname> with its values
<emphasis>AND</emphasis>, <emphasis>OR</emphasis> and
<emphasis>ALL_FALSE</emphasis>. <xref
linkend="example-boolean-constraint-composition" /> shows how to build a
composing constraint where only one of the constraints has to be
successful in order to pass the validation. Either the validated string is
all lowercased or it is between two and three characters long.</para>
<example id="example-boolean-constraint-composition">
<title>OR composition of constraints</title>
<programlisting language="JAVA" role="JAVA"><emphasis role="bold">@ConstraintComposition(OR)</emphasis>
@Pattern(regexp = "[a-z]")
@Size(min = 2, max = 3)
@ReportAsSingleViolation
@Target({ METHOD, FIELD })
@Retention(RUNTIME)
@Constraint(validatedBy = { })
public @interface PatternOrSize {
public abstract String message() default "{PatternOrSize.message}";
public abstract Class<?>[] groups() default { };
public abstract Class<? extends Payload>[] payload() default { };
}</programlisting>
</example>
<tip>
<para>Using <emphasis>ALL_FALSE</emphasis> as composition type
implicitly enforces that only a single violation will get reported in
case validation of the constraint composition fails.</para>
</tip>
</section>
</chapter>