From 3826741e8cc0df05099436b8e31b7df8ade3b00b Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Thu, 25 Apr 2013 21:36:35 +0200 Subject: [PATCH] HV-725 Updating bootstrapping chapter --- .../en-US/modules/bean-constraints.xml | 8 +- .../docbook/en-US/modules/bootstrapping.xml | 761 ++++++++++-------- .../docbook/en-US/modules/customoptions.xml | 4 +- .../docbook/en-US/modules/metadataapi.xml | 10 +- .../en-US/modules/xmlconfiguration.xml | 4 +- .../chapter08/BootstrappingTest.java | 110 +++ .../MyConstraintValidatorFactory.java | 18 + .../chapter08/MyMessageInterpolator.java | 19 + .../chapter08/MyParameterNameProvider.java | 21 + .../chapter08/MyTraversableResolver.java | 31 + .../chapter08/OsgiServiceDiscoverer.java | 14 + 11 files changed, 648 insertions(+), 352 deletions(-) create mode 100644 documentation/src/test/java/org/hibernate/validator/referenceguide/chapter08/BootstrappingTest.java create mode 100644 documentation/src/test/java/org/hibernate/validator/referenceguide/chapter08/MyConstraintValidatorFactory.java create mode 100644 documentation/src/test/java/org/hibernate/validator/referenceguide/chapter08/MyMessageInterpolator.java create mode 100644 documentation/src/test/java/org/hibernate/validator/referenceguide/chapter08/MyParameterNameProvider.java create mode 100644 documentation/src/test/java/org/hibernate/validator/referenceguide/chapter08/MyTraversableResolver.java create mode 100644 documentation/src/test/java/org/hibernate/validator/referenceguide/chapter08/OsgiServiceDiscoverer.java diff --git a/documentation/src/main/docbook/en-US/modules/bean-constraints.xml b/documentation/src/main/docbook/en-US/modules/bean-constraints.xml index 2cc4dd3050..82036fddc7 100644 --- a/documentation/src/main/docbook/en-US/modules/bean-constraints.xml +++ b/documentation/src/main/docbook/en-US/modules/bean-constraints.xml @@ -401,7 +401,7 @@ Validator validator = factory.getValidator(); For other ways of obtaining a Validator instance see . For now we just want to see how we + linkend="chapter-bootstrapping"/>. For now we just want to see how we can use the Validator instance to validate entity instances. @@ -1081,9 +1081,9 @@ assertEquals( "may not be null", constraintViolations.iterator().next().getMessa - @URL(protocol=, - host=, port= - regexp=, flags=) + @URL(protocol=, host=, + port= regexp=, + flags=) CharSequence diff --git a/documentation/src/main/docbook/en-US/modules/bootstrapping.xml b/documentation/src/main/docbook/en-US/modules/bootstrapping.xml index 4850b0a3cb..b1e0807bc4 100644 --- a/documentation/src/main/docbook/en-US/modules/bootstrapping.xml +++ b/documentation/src/main/docbook/en-US/modules/bootstrapping.xml @@ -20,384 +20,467 @@ %BOOK_ENTITIES; ]> - + Bootstrapping - We already seen in the - easiest way to create a Validator instance - - Validation.buildDefaultValidatorFactory. In this - chapter we have a look at the other methods in - javax.validation.Validation and how they allow to - configure several aspects of Bean Validation at bootstrapping time. - - The different bootstrapping options allow, amongst other things, to - bootstrap any Bean Validation implementation on the classpath. Generally, an - available provider is discovered by the Java - Service Provider mechanism. A Bean Validation implementation - includes the file - javax.validation.spi.ValidationProvider in - META-INF/services. This file contains the fully - qualified classname of the ValidationProvider of the - implementation. In the case of Hibernate Validator this is - org.hibernate.validator.HibernateValidator. - - - If there are more than one Bean Validation implementation providers - in the classpath and - Validation.buildDefaultValidatorFactory() is - used, there is no guarantee which provider will be chosen. To enforce the - provider Validation.byProvider() should be - used. - - -
- <classname>Configuration</classname> and - <classname>ValidatorFactory</classname> - - There are three different methods in the Validation class to create - a Validator instance. The easiest in shown in . + In you already saw one + way for creating a Validator instance — via + Validation#buildDefaultValidatorFactory(). In this + chapter you will learn how to use the other methods in + javax.validation.Validation in order to bootstrap + specifically configured validators. + +
+ Retrieving <classname>ValidatorFactory</classname> and + <classname>Validator</classname> + + You obtain a Validator by retrieving a + ValidatorFactory via one of the static methods on + javax.validation.Validation and calling + getValidator() on the factory instance. + + shows how + to obtain a validator from the default validator factory: - Validation.buildDefaultValidatorFactory() + Bootstrapping default <classname>ValidatorFactory</classname> and + <classname>Validator</classname> ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); Validator validator = factory.getValidator(); - You can also use the method - Validation.byDefaultProvider() which will allow - you to configure several aspects of the created Validator instance: + + The generated ValidatorFactory and + Validator instances are thread-safe and can be + cached. As Hibernate Validator uses the factory as context for caching + constraint metadata it is recommended to work with one factory instance + within an application. + + + Bean Validation supports working with several providers such as + Hibernate Validator within one application. If more than one provider is + present on the classpath, it is not guaranteed which one is chosen when + creating a factory via + buildDefaultValidatorFactory(). + + In this case you can explicitly specify the provider to use via + Validation#byProvider(), passing the provider's + ValidationProvider class as shown in . + + + Bootstrapping <classname>ValidatorFactory</classname> and + <classname>Validator</classname> using a specific provider + + ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class ) + .configure() + .buildValidatorFactory(); +Validator validator = validatorFactory.getValidator(); + + + Note that the configuration object returned by + configure() allows to specifically customize the + factory before calling buildValidatorFactory(). + The available options are discussed later in this chapter. - - Validation.byDefaultProvider() + Similarly you can retrieve the default validator factory for + configuration which is demonstrated in . - Configuration<?> config = Validation.byDefaultProvider().configure(); -config.messageInterpolator(new MyMessageInterpolator()) - .traversableResolver( new MyTraversableResolver()) - .constraintValidatorFactory(new MyConstraintValidatorFactory()); + + Retrieving the default <classname>ValidatorFactory</classname> + for configuration -ValidatorFactory factory = config.buildValidatorFactory(); -Validator validator = factory.getValidator(); - + ValidatorFactory validatorFactory = Validation.byDefaultProvider() + .configure() + .buildValidatorFactory(); +Validator validator = validatorFactory.getValidator(); - We will learn more about MessageInterpolator, - TraversableResolver and - ConstraintValidatorFactory in the following - sections. + + If a ValidatorFactory instance is no longer + in use, it should be disposed by calling + ValidatorFactory#close(). This will free any + resources possibly allocated by the factory. + - Last but not least you can ask for a Configuration object of a - specific Bean Validation provider. This is useful if you have more than - one Bean Validation provider in your classpath. In this situation you can - make an explicit choice about which implementation to use. In the case of - Hibernate Validator the Validator creation looks - like: +
+ <classname>ValidationProviderResolver</classname> + + By default, available Bean Validation providers are discovered + using the Java + Service Provider mechanism. + + For that purpose, each provider includes the file + META-INF/services/javax.validation.spi.ValidationProvider, + containing the fully qualified classname of its + ValidationProvider implementation. In the case of + Hibernate Validator this is + org.hibernate.validator.HibernateValidator. + + Depending on your environment and its classloading specifics, + provider discovery via the Java's service loader mechanism might not + work. In this case you can plug in a custom + ValidationProviderResolver implementation which + performs the provider retrieval. An example is OSGi, where you could + implement a provider resolver which uses OSGi services for provider + discovery. + + To use a custom provider resolver pass it via + providerResolver() as shown shown in . + + + Using a custom + <classname>ValidationProviderResolver</classname> + + package org.hibernate.validator.referenceguide.chapter08; + +public class OsgiServiceDiscoverer implements ValidationProviderResolver { + + @Override + public List<ValidationProvider<?>> getValidationProviders() { + //... + } +} + + ValidatorFactory validatorFactory = Validation.byDefaultProvider() + .providerResolver( new OsgiServiceDiscoverer() ) + .configure() + .buildValidatorFactory(); +Validator validator = validatorFactory.getValidator(); + +
+
- - Validation.byProvider( HibernateValidator.class ) +
+ Configuring a <classname>ValidatorFactory</classname> + + By default validator factories retrieved from + Validation and any validators they create are + configured as per the XML descriptor + META-INF/validation.xml (see ), if present. + + If you want to disable the XML based configuration, you can do so by + invoking + Configuration#ignoreXmlConfiguration(). + + The different values of the XML configuration can be accessed via + Configuration#getBootstrapConfiguration(). This + can for instance be helpful if you want to integrate Bean Validation into + a managed environment and want to create managed instances of the objects + configured via XML. + + Using the fluent configuration API, you can override one or more of + the settings when bootstrapping the factory. The following sections show + how to make use of the different options. Note that the + Configuration class exposes the default + implementations of the different extension points which can be useful if + you want to use these as delegates for your custom implementations. + +
+ <classname>MessageInterpolator</classname> + + Message interpolators are used by the validation engine to create + user readable error messages from constraint message descriptors. + + In case the default message interpolation algorithm described in + is not sufficient for + your needs, you can pass in your own implementation of the + MessageInterpolator interface via + Configuration#messageInterpolator() as shown in + . + + + Using a custom + <classname>MessageInterpolator</classname> + + package org.hibernate.validator.referenceguide.chapter08; + +public class MyMessageInterpolator implements MessageInterpolator { + + @Override + public String interpolate(String messageTemplate, Context context) { + //... + } + + @Override + public String interpolate(String messageTemplate, Context context, Locale locale) { + //... + } +} + + ValidatorFactory validatorFactory = Validation.byDefaultProvider() + .configure() + .messageInterpolator( new MyMessageInterpolator() ) + .buildValidatorFactory(); +Validator validator = validatorFactory.getValidator(); + +
- HibernateValidatorConfiguration config = Validation.byProvider( HibernateValidator.class ).configure(); -config.messageInterpolator(new MyMessageInterpolator()) - .traversableResolver( new MyTraversableResolver()) - .constraintValidatorFactory(new MyConstraintValidatorFactory()); +
+ <classname>TraversableResolver</classname> + + In some cases the validation engine should not access the state of + a bean property. The most obvious example for that is a lazily loaded + property or association of a JPA entity. Validating this lazy property + or association would mean that its state would have to be accessed, + triggering a load from the database. + + Which properties can be accessed and which ones not is controlled + by querying the TraversableResolver interface. + shows how to + use a custom traversable resolver implementation. + + + Using a custom + <classname>TraversableResolver</classname> + + package org.hibernate.validator.referenceguide.chapter08; + +public class MyTraversableResolver implements TraversableResolver { + + @Override + public boolean isReachable( + Object traversableObject, + Node traversableProperty, + Class<?> rootBeanType, + Path pathToTraversableObject, + ElementType elementType) { + //... + } + + @Override + public boolean isCascadable( + Object traversableObject, + Node traversableProperty, + Class<?> rootBeanType, + Path pathToTraversableObject, + ElementType elementType) { + //... + } +} + + ValidatorFactory validatorFactory = Validation.byDefaultProvider() + .configure() + .traversableResolver( new MyTraversableResolver() ) + .buildValidatorFactory(); +Validator validator = validatorFactory.getValidator(); + -ValidatorFactory factory = config.buildValidatorFactory(); -Validator validator = factory.getValidator(); - + Hibernate Validator provides two + TraversableResolvers out of the box which will be + enabled automatically depending on your environment. The first is + DefaultTraversableResolver which will always + return true for + isReachable() and + isTraversable(). The second is + JPATraversableResolver which gets enabled when + Hibernate Validator is used in combination with JPA 2. +
- - The generated Validator instance is - thread safe and can be cached. - -
+
+ <classname>ConstraintValidatorFactory</classname> + + ConstraintValidatorFactory is the extension + point for customizing how constraint validators are instantiated and + released. + + The default ConstraintValidatorFactory + provided by Hibernate Validator requires a public no-arg constructor to + instantiate ConstraintValidator instances (see + ). Using a custom + ConstraintValidatorFactory offers for example the + possibility to use dependency injection in constraint validator + implementations. + + To configure a custom constraint validator factory call + Configuration#constraintValidatorFactory() (see + . + + + Using a custom + <classname>ConstraintValidatorFactory</classname> + + package org.hibernate.validator.referenceguide.chapter08; + +public class MyConstraintValidatorFactory implements ConstraintValidatorFactory { + + @Override + public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) { + //... + } + + @Override + public void releaseInstance(ConstraintValidator<?, ?> instance) { + //... + } +} + + ValidatorFactory validatorFactory = Validation.byDefaultProvider() + .configure() + .constraintValidatorFactory( new MyConstraintValidatorFactory() ) + .buildValidatorFactory(); +Validator validator = validatorFactory.getValidator(); + -
- <classname>ValidationProviderResolver</classname> + + Any constraint implementations relying on + ConstraintValidatorFactory behaviors specific + to an implementation (dependency injection, no no-arg constructor and + so on) are not considered portable. + + + + ConstraintValidatorFactory + implementations should not cache validator instances as the state of + each instance can be altered in the + initialize() method. + +
- In the case that the Java Service Provider mechanism does not work - in your environment or you have a special classloader setup, you are able - to provide a custom ValidationProviderResolver. An - example in an OSGi environment you could plug your custom provider - resolver like seen in . +
+ <classname>ParameterNameProvider</classname> - - Providing a custom ValidationProviderResolver + In case a method or constructor parameter constraint is violated, + the ParameterNameProvider interface is used to + retrieve the parameter's name and make it available to the user via the + constraint violation's property path. - Configuration<?> config = Validation.byDefaultProvider() - .providerResolver( new OSGiServiceDiscoverer() ) - .configure(); + The default implementation returns parameter names in the form + arg0, arg1 etc., while custom + implementations could e.g. be based on parameter annotations, debug + symbols or a feature for retrieving parameter names at runtime possibly + provided by future Java versions. -ValidatorFactory factory = config.buildValidatorFactory(); -Validator validator = factory.getValidator(); - - + Custom ParameterNameProvider + implementations are used as demonstrated in . - Your OSGiServiceDiscoverer must in this case - implement the interface - ValidationProviderResolver: - - - ValidationProviderResolver interface - - public interface ValidationProviderResolver { - /** - * Returns a list of ValidationProviders available in the runtime environment. - * - * @return list of validation providers. - */ - List<ValidationProvider<?>> getValidationProviders(); -} - - -
+ + Using a custom + <classname>ParameterNameProvider</classname> -
- <classname>MessageInterpolator</classname> - - already discussed - the default message interpolation algorithm. If you have special - requirements for your message interpolation you can provide a custom - interpolator using - Configuration.messageInterpolator(). This message - interpolator will be shared by all validators generated by the - ValidatorFactory created from this - Configuration. shows an interpolator (available - in Hibernate Validator) which can interpolate the value being validated in - the constraint message. To refer to this value in the constraint message - you can use: - - ${validatedValue}: this will call String.valueOf - on the validated value. - - - - ${validatedValue:<format>}: provide your own format - string which will be passed to String.format together - with the validated value. Refer to the javadoc of - String.format for more information about the format - options. - - - - - Providing a custom MessageInterpolator - - Configuration<?> configuration = Validation.byDefaultProvider().configure(); -ValidatorFactory factory = configuration - .messageInterpolator(new ValueFormatterMessageInterpolator(configuration.getDefaultMessageInterpolator())) - .buildValidatorFactory(); - -Validator validator = factory.getValidator(); - - + package org.hibernate.validator.referenceguide.chapter08; - - It is recommended that MessageInterpolator - implementations delegate final interpolation to the Bean Validation - default MessageInterpolator to ensure standard - Bean Validation interpolation rules are followed. The default - implementation is accessible through - Configuration.getDefaultMessageInterpolator(). - +public class MyParameterNameProvider implements ParameterNameProvider { + + @Override + public List<String> getParameterNames(Constructor<?> constructor) { + //... + } + + @Override + public List<String> getParameterNames(Method method) { + //... + } +} + + ValidatorFactory validatorFactory = Validation.byDefaultProvider() + .configure() + .parameterNameProvider( new MyParameterNameProvider() ) + .buildValidatorFactory(); +Validator validator = validatorFactory.getValidator(); + +
-
- ResourceBundleLocator - - A common use case is the ability to specify your own resource - bundles for message interpolation. The default - MessageInterpolator implementation in Hibernate - Validator is called - ResourceBundleMessageInterpolator and per default - loads resource bundles via - ResourceBundle.getBundle. However, - ResourceBundleMessageInterpolator also allows you - to specify a custom implementation of - ResourceBundleLocator allowing you to provide - your own resource bundles. shows an example. In the - example - HibernateValidatorConfiguration.getDefaultResourceBundleLocator - is used to retrieve the default - ResourceBundleLocator which then can be passed to - the custom implementation in order implement delegation. - - - Providing a custom ResourceBundleLocator - - HibernateValidatorConfiguration configure = Validation.byProvider(HibernateValidator.class).configure(); - -ResourceBundleLocator defaultResourceBundleLocator = configure.getDefaultResourceBundleLocator(); -ResourceBundleLocator myResourceBundleLocator = new MyCustomResourceBundleLocator(defaultResourceBundleLocator); - -configure.messageInterpolator(new ResourceBundleMessageInterpolator(myResourceBundleLocator)); - +
+ Adding mapping streams + + As discussed earlier you can configure the constraints applying + for your Java beans using XML based constraint mappings. + + Besides the mapping files specified in + META-INF/validation.xml you can add further + mappings via Configuration#addMapping() (see + ). Note that the passed + input stream(s) must adhere to the XML schema for constraint mappings + presented in . + + + Adding constraint mapping streams + + InputStream constraintMapping1 = ...; +InputStream constraintMapping2 = ...; +ValidatorFactory validatorFactory = Validation.byDefaultProvider() + .configure() + .addMapping( constraintMapping1 ) + .addMapping( constraintMapping2 ) + .buildValidatorFactory(); +Validator validator = validatorFactory.getValidator(); - Hibernate Validator provides the following implementation of - ResourceBundleLocator - - PlatformResourceBundleLocator (the default) and - AggregateResourceBundleLocator. The latter can be - used to specify a list of resource bundle names which will get loaded - and merged into a single resource bundle. Refer to the JavaDoc - documentation for more information. + You should close any passed input stream after the validator + factory has been created.
-
-
- <classname>TraversableResolver</classname> - - The usage of the TraversableResolver has so - far not been discussed. The idea is that in some cases, the state of a - property should not be accessed. The most obvious example for that is a - lazy loaded property or association of a Java Persistence provider. - Validating this lazy property or association would mean that its state - would have to be accessed triggering a load from the database. Bean - Validation controls which property can and cannot be accessed via the - TraversableResolver interface (see ). In the example - HibernateValidatorConfiguration. - - - TraversableResolver interface - - /** - * Contract determining if a property can be accessed by the Bean Validation provider - * This contract is called for each property that is being either validated or cascaded. - * - * A traversable resolver implementation must be thread-safe. - * - */ -public interface TraversableResolver { - /** - * Determine if the Bean Validation provider is allowed to reach the property state - * - * @param traversableObject object hosting <code>traversableProperty</code> or null - * if validateValue is called - * @param traversableProperty the traversable property. - * @param rootBeanType type of the root object passed to the Validator. - * @param pathToTraversableObject path from the root object to - * <code>traversableObject</code> - * (using the path specification defined by Bean Validator). - * @param elementType either <code>FIELD</code> or <code>METHOD</code>. - * - * @return <code>true</code> if the Bean Validation provider is allowed to - * reach the property state, <code>false</code> otherwise. - */ - boolean isReachable(Object traversableObject, - Path.Node traversableProperty, - Class<?> rootBeanType, - Path pathToTraversableObject, - ElementType elementType); - - /** - * Determine if the Bean Validation provider is allowed to cascade validation on - * the bean instance returned by the property value - * marked as <code>@Valid</code>. - * Note that this method is called only if isReachable returns true for the same set of - * arguments and if the property is marked as <code>@Valid</code> - * - * @param traversableObject object hosting <code>traversableProperty</code> or null - * if validateValue is called - * @param traversableProperty the traversable property. - * @param rootBeanType type of the root object passed to the Validator. - * @param pathToTraversableObject path from the root object to - * <code>traversableObject</code> - * (using the path specification defined by Bean Validator). - * @param elementType either <code>FIELD</code> or <code>METHOD</code>. - * - * @return <code>true</code> if the Bean Validation provider is allowed to - * cascade validation, <code>false</code> otherwise. - */ - boolean isCascadable(Object traversableObject, - Path.Node traversableProperty, - Class<?> rootBeanType, - Path pathToTraversableObject, - ElementType elementType); -} - - +
+ Provider-specific settings - Hibernate Validator provides two - TraversableResolvers out of the box which will be - enabled automatically depending on your environment. The first is the - DefaultTraversableResolver which will always return - true for isReachable() and - isTraversable(). The second is the - JPATraversableResolver which gets enabled when - Hibernate Validator gets used in combination with JPA 2. In case you have - to provide your own resolver you can do so again using the - Configuration object as seen in . - - - Providing a custom TraversableResolver - - Configuration<?> configuration = Validation.byDefaultProvider().configure(); -ValidatorFactory factory = configuration - .traversableResolver(new MyTraversableResolver()) - .buildValidatorFactory(); - -Validator validator = factory.getValidator(); - - + Via the configuration object returned by + Validation#byProvider() provider specific + options can be configured. + + In case of Hibernate Validator this allows you to enable the fail + fast mode and pass one or more programmatic constraint mappings as + demonstrated in . + + + Setting Hibernate Validator specific options + + ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class ) + .configure() + .failFast( true ) + .addMapping( (ConstraintMapping) null ) + .buildValidatorFactory(); +Validator validator = validatorFactory.getValidator(); + + + Alternatively, provider-specific options can be passed via + Configuration#addProperty(). Hibernate + Validator supports enabling the fail fast mode that way, too: + + + Enabling a Hibernate Validator specific option via + <methodname>addProperty()</methodname> + + ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class ) + .configure() + .addProperty( "hibernate.validator.fail_fast", "true" ) + .buildValidatorFactory(); +Validator validator = validatorFactory.getValidator(); + + + Refer to and to learn more about the fail fast + mode and the constraint declaration API. +
- <classname>ConstraintValidatorFactory</classname> - - Last but not least, there is one more configuration option to - discuss, the ConstraintValidatorFactory. The - default ConstraintValidatorFactory provided by - Hibernate Validator requires a public no-arg constructor to instantiate - ConstraintValidator instances (see ). Using a custom - ConstraintValidatorFactory offers for example the - possibility to use dependency injection in constraint implementations. The - configuration of the custom factory is once more via the - Configuration (). - - - Providing a custom ConstraintValidatorFactory - - Configuration<?> configuration = Validation.byDefaultProvider().configure(); -ValidatorFactory factory = configuration - .constraintValidatorFactory(new IOCConstraintValidatorFactory()) - .buildValidatorFactory(); - -Validator validator = factory.getValidator(); - - - - The interface you have to implement is: + Configuring a <classname>Validator</classname> - - ConstraintValidatorFactory interface + When working with a configured validator factory it can occasionally + be required to apply a different configuration to a single + Validator instance. shows how this can be achieved by + calling ValidatorFactory#usingContext(). - public interface ConstraintValidatorFactory { - /** - * @param key The class of the constraint validator to instantiate. - * - * @return A constraint validator instance of the specified class. - */ - <T extends ConstraintValidator<?,?>> T getInstance(Class<T> key); -} - - + + Configuring a <classname>Validator</classname> via + <methodname>usingContext()</methodname> - - Any constraint implementation relying on - ConstraintValidatorFactory behaviors specific to - an implementation (dependency injection, no no-arg constructor and so - on) are not considered portable. - + ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory(); - - ConstraintValidatorFactory should not cache instances as the state - of each instance can be altered in the initialize method. - +Validator validator = validatorFactory.usingContext() + .messageInterpolator( new MyMessageInterpolator() ) + .traversableResolver( new MyTraversableResolver() ) + .getValidator(); +
diff --git a/documentation/src/main/docbook/en-US/modules/customoptions.xml b/documentation/src/main/docbook/en-US/modules/customoptions.xml index d8abee4817..0ae49b6fbd 100644 --- a/documentation/src/main/docbook/en-US/modules/customoptions.xml +++ b/documentation/src/main/docbook/en-US/modules/customoptions.xml @@ -221,8 +221,8 @@ validator = factory.unwrap( HibernateValidatorFactory.class )
-
- Programmatic constraint definition +
+ Programmatic constraint declaration Another addition to the Bean Validation specification is the ability to configure constraints via a fluent API. This API can be used diff --git a/documentation/src/main/docbook/en-US/modules/metadataapi.xml b/documentation/src/main/docbook/en-US/modules/metadataapi.xml index daf7e32555..60ee8285d6 100644 --- a/documentation/src/main/docbook/en-US/modules/metadataapi.xml +++ b/documentation/src/main/docbook/en-US/modules/metadataapi.xml @@ -293,11 +293,11 @@ assertEquals( 1, driverDescriptor.getGroupConversions().size() );Using getConstrainedDescriptors(), you can retrieve a set of ConstraintDescriptors providing more information on the individual constraints of a given property. The - method isCascaded() returns true, if the property - is marked for cascaded validation (either using the - @Valid annotation or via XML), false otherwise. Any - configured group conversions are returned by - getGroupConversions(). See isCascaded() returns + true, if the property is marked for cascaded validation + (either using the @Valid annotation or via XML), + false otherwise. Any configured group conversions are + returned by getGroupConversions(). See for more details on GroupConversionDescriptor.
diff --git a/documentation/src/main/docbook/en-US/modules/xmlconfiguration.xml b/documentation/src/main/docbook/en-US/modules/xmlconfiguration.xml index 7bc278fef1..4f186d3185 100644 --- a/documentation/src/main/docbook/en-US/modules/xmlconfiguration.xml +++ b/documentation/src/main/docbook/en-US/modules/xmlconfiguration.xml @@ -20,7 +20,7 @@ %BOOK_ENTITIES; ]> - + Configuring via XML So far we have used the default configuration source for Bean @@ -147,7 +147,7 @@ linkend="failfast"/>).
-
+
Mapping constraints via <property>constraint-mappings</property> diff --git a/documentation/src/test/java/org/hibernate/validator/referenceguide/chapter08/BootstrappingTest.java b/documentation/src/test/java/org/hibernate/validator/referenceguide/chapter08/BootstrappingTest.java new file mode 100644 index 0000000000..45a26973cc --- /dev/null +++ b/documentation/src/test/java/org/hibernate/validator/referenceguide/chapter08/BootstrappingTest.java @@ -0,0 +1,110 @@ +package org.hibernate.validator.referenceguide.chapter08; + +import java.io.InputStream; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; + +import org.hibernate.validator.HibernateValidator; +import org.hibernate.validator.cfg.ConstraintMapping; + +public class BootstrappingTest { + + public void buildDefaultValidatorFactory() { + ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory(); + Validator validator = validatorFactory.getValidator(); + } + + public void byProvider() { + ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class ) + .configure() + .buildValidatorFactory(); + Validator validator = validatorFactory.getValidator(); + } + + public void byDefaultProvider() { + ValidatorFactory validatorFactory = Validation.byDefaultProvider() + .configure() + .buildValidatorFactory(); + Validator validator = validatorFactory.getValidator(); + } + + public void providerResolver() { + ValidatorFactory validatorFactory = Validation.byDefaultProvider() + .providerResolver( new OsgiServiceDiscoverer() ) + .configure() + .buildValidatorFactory(); + Validator validator = validatorFactory.getValidator(); + } + + public void messageInterpolator() { + ValidatorFactory validatorFactory = Validation.byDefaultProvider() + .configure() + .messageInterpolator( new MyMessageInterpolator() ) + .buildValidatorFactory(); + Validator validator = validatorFactory.getValidator(); + } + + public void traversableResolver() { + ValidatorFactory validatorFactory = Validation.byDefaultProvider() + .configure() + .traversableResolver( new MyTraversableResolver() ) + .buildValidatorFactory(); + Validator validator = validatorFactory.getValidator(); + } + + public void constraintValidatorFactory() { + ValidatorFactory validatorFactory = Validation.byDefaultProvider() + .configure() + .constraintValidatorFactory( new MyConstraintValidatorFactory() ) + .buildValidatorFactory(); + Validator validator = validatorFactory.getValidator(); + } + + public void parameterNameProvider() { + ValidatorFactory validatorFactory = Validation.byDefaultProvider() + .configure() + .parameterNameProvider( new MyParameterNameProvider() ) + .buildValidatorFactory(); + Validator validator = validatorFactory.getValidator(); + } + + public void addMapping() { + InputStream constraintMapping1 = null; + InputStream constraintMapping2 = null; + ValidatorFactory validatorFactory = Validation.byDefaultProvider() + .configure() + .addMapping( constraintMapping1 ) + .addMapping( constraintMapping2 ) + .buildValidatorFactory(); + Validator validator = validatorFactory.getValidator(); + } + + public void providerSpecificOptions() { + ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class ) + .configure() + .failFast( true ) + .addMapping( (ConstraintMapping) null ) + .buildValidatorFactory(); + Validator validator = validatorFactory.getValidator(); + } + + public void providerSpecificOptionViaAddProperty() { + ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class ) + .configure() + .addProperty( "hibernate.validator.fail_fast", "true" ) + .buildValidatorFactory(); + Validator validator = validatorFactory.getValidator(); + } + + public void usingContext() { + ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory(); + + Validator validator = validatorFactory.usingContext() + .messageInterpolator( new MyMessageInterpolator() ) + .traversableResolver( + new MyTraversableResolver() + ) + .getValidator(); + } +} diff --git a/documentation/src/test/java/org/hibernate/validator/referenceguide/chapter08/MyConstraintValidatorFactory.java b/documentation/src/test/java/org/hibernate/validator/referenceguide/chapter08/MyConstraintValidatorFactory.java new file mode 100644 index 0000000000..fd7e936cf0 --- /dev/null +++ b/documentation/src/test/java/org/hibernate/validator/referenceguide/chapter08/MyConstraintValidatorFactory.java @@ -0,0 +1,18 @@ +package org.hibernate.validator.referenceguide.chapter08; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorFactory; + +public class MyConstraintValidatorFactory implements ConstraintValidatorFactory { + + @Override + public > T getInstance(Class key) { + //... + return null; + } + + @Override + public void releaseInstance(ConstraintValidator instance) { + //... + } +} diff --git a/documentation/src/test/java/org/hibernate/validator/referenceguide/chapter08/MyMessageInterpolator.java b/documentation/src/test/java/org/hibernate/validator/referenceguide/chapter08/MyMessageInterpolator.java new file mode 100644 index 0000000000..f40794d773 --- /dev/null +++ b/documentation/src/test/java/org/hibernate/validator/referenceguide/chapter08/MyMessageInterpolator.java @@ -0,0 +1,19 @@ +package org.hibernate.validator.referenceguide.chapter08; + +import java.util.Locale; +import javax.validation.MessageInterpolator; + +public class MyMessageInterpolator implements MessageInterpolator { + + @Override + public String interpolate(String messageTemplate, Context context) { + //... + return null; + } + + @Override + public String interpolate(String messageTemplate, Context context, Locale locale) { + //... + return null; + } +} diff --git a/documentation/src/test/java/org/hibernate/validator/referenceguide/chapter08/MyParameterNameProvider.java b/documentation/src/test/java/org/hibernate/validator/referenceguide/chapter08/MyParameterNameProvider.java new file mode 100644 index 0000000000..24b2113834 --- /dev/null +++ b/documentation/src/test/java/org/hibernate/validator/referenceguide/chapter08/MyParameterNameProvider.java @@ -0,0 +1,21 @@ +package org.hibernate.validator.referenceguide.chapter08; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.util.List; +import javax.validation.ParameterNameProvider; + +public class MyParameterNameProvider implements ParameterNameProvider { + + @Override + public List getParameterNames(Constructor constructor) { + //... + return null; + } + + @Override + public List getParameterNames(Method method) { + //... + return null; + } +} diff --git a/documentation/src/test/java/org/hibernate/validator/referenceguide/chapter08/MyTraversableResolver.java b/documentation/src/test/java/org/hibernate/validator/referenceguide/chapter08/MyTraversableResolver.java new file mode 100644 index 0000000000..9e3461282d --- /dev/null +++ b/documentation/src/test/java/org/hibernate/validator/referenceguide/chapter08/MyTraversableResolver.java @@ -0,0 +1,31 @@ +package org.hibernate.validator.referenceguide.chapter08; + +import java.lang.annotation.ElementType; +import javax.validation.Path; +import javax.validation.Path.Node; +import javax.validation.TraversableResolver; + +public class MyTraversableResolver implements TraversableResolver { + + @Override + public boolean isReachable( + Object traversableObject, + Node traversableProperty, + Class rootBeanType, + Path pathToTraversableObject, + ElementType elementType) { + //... + return false; + } + + @Override + public boolean isCascadable( + Object traversableObject, + Node traversableProperty, + Class rootBeanType, + Path pathToTraversableObject, + ElementType elementType) { + //... + return false; + } +} diff --git a/documentation/src/test/java/org/hibernate/validator/referenceguide/chapter08/OsgiServiceDiscoverer.java b/documentation/src/test/java/org/hibernate/validator/referenceguide/chapter08/OsgiServiceDiscoverer.java new file mode 100644 index 0000000000..eb3def0373 --- /dev/null +++ b/documentation/src/test/java/org/hibernate/validator/referenceguide/chapter08/OsgiServiceDiscoverer.java @@ -0,0 +1,14 @@ +package org.hibernate.validator.referenceguide.chapter08; + +import java.util.List; +import javax.validation.ValidationProviderResolver; +import javax.validation.spi.ValidationProvider; + +public class OsgiServiceDiscoverer implements ValidationProviderResolver { + + @Override + public List> getValidationProviders() { + //... + return null; + } +}