[hibernate-dev] [Bean Validation] XML Configuration
Emmanuel Bernard
emmanuel at hibernate.org
Sat Jan 31 01:50:30 EST 2009
The last big missing piece of the spec was the ability do configure
Bean Validation via XML. An META-INF/validation.xml file can
optionally be used for that:
- choose the default provider
- choose MessageInterpolator and the other integration point
- list XML Mapping files
- list provider specific properties
Here is an attempt to formalize that. Note that I did change the
Configuration object a bit (see the API below (section 4.4.3) and its
role in the bootstrap process. It is know responsible for parsing
valiation.xml and merge metadata from the programmatic calls and from
XML. You can also force BV to ignore validation.xml (especially useful
for containers that want to parse such resources themselves).
Th proposal is still rough on the edges. Let me know what is confusing.
4.4.6. XML Configuration: META-INF/validation.xml
Unless explicitly ignored by calling
Configuration.ignoreXMLConfiguration(), a ValidatorFactory takes into
account the configuration available in META-INF/validation.xml. This
configuration file is optional but can be used by application to
refine some of the Bean Validation behavior.
Unless stated otherwise, XML based configuration settings are
overridden by values explicitly set via the Configuration API. For
example, the MessageInterpolator defined
viaConfiguration.messageInterpolator(MessageInterpolator) has priority
over the message-interpolator definition.
default-provider: represents the class name of the provider specific
Configuration sub-interface. If defined, the provider suitable for
this interface is used (unless a specific provider has been chosen via
the programmatic approach).
message-interpolator: represents the fully qualified class name of the
MessageInterpolator implementation. This implementation must have a
public no-arg constructor. This element is optional.
traversable-resolver: represents the fully qualified class name of the
TravedrsableResolver implementation. This implementation must have a
public no-arg constructor. This element is optional.
constraint-validator-factory: represents the fully qualified class
name of the ConstraintValidatorFactory implementation. This
implementation must have a public no-arg constructor. This element is
optional.
constraint-mapping: represents the resource path of an XML mapping
file. More than one constraint-mapping element can be present.
Mappings provided viaConfiguration.addMapping(InputString) are added
to the list of mappings described via constraint-mapping.
property: represents a key/value pair property providing room to
provider specific configuration. Vendors should use vendor namespaces
for properties (e.g.,com.acme.validation.logging). Entries that make
use of the namespace javax.validation and its subnamespaces must not
be used for vendor-specific information. The namespacejavax.validation
is reserved for use by this specification. Properties defined via
Configuration.addProperty(String, String) are added to the properties
defined via property. If a property with the same name are defined in
both XML and via the programmatic API, the value provided via
programmatic API has priority.
Example 4.23. META-INF/validation.xml file
<?xml version="1.0" encoding="UTF-8"?>
<validation-config
xmlns="http://jboss.org/xml/ns/javax/validation/configuration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/configuration
validation-configuration-1.0.xsd">
<default-provider>com.acme.ACMEValidatorConfiguration</default-
provider>
<message-interpolator>com.acme.ACMEAwareMessageInterpolator</
message-interpolator>
<constraint-mapping>META-INF/validation/order-constraints.xml</
constraint-mapping>
<constraint-mapping>META-INF/validation/catalog-constraints.xml</
constraint-mapping>
<constraint-mapping>META-INF/validation/customer-constraints.xml</
constraint-mapping>
<property name="com.acme.validation.logging">WARN</property>
<property name="com.acme.validation.safetyChecking">failOnError</
property>
</validation-config>
The XML schema is described in Section 7.2, “Configuration schema”.
7.2. Configuration schema
XML Configuration is set in META-INF/validation.xml. The file is
optional. The XML schema followed by the configuration file is as
followed.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified"
elementFormDefault="qualified"
targetNamespace="http://jboss.org/xml/ns/javax/validation/configuration
"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="1.0">
<xs:element name="validation-config" type="validation-configType"/>
<xs:complexType name="validation-configType">
<xs:sequence>
<xs:element type="xs:string" name="default-provider"
minOccurs="0"/>
<xs:element type="xs:string" name="message-interpolator"
minOccurs="0"/>
<xs:element type="xs:string" name="traversable-resolver"
minOccurs="0"/>
<xs:element type="xs:string" name="constraint-validator-
factory" minOccurs="0"/>
<xs:element type="xs:string" name="constraint-mapping"
maxOccurs="unbounded" minOccurs="0"/>
<xs:element type="propertyType" name="property"
maxOccurs="unbounded" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="propertyType">
<xs:attribute name="name" use="required" type="xs:string"/>
</xs:complexType>
</xs:schema>
See Section 4.4.6, “XML Configuration: META-INF/validation.xml” for
more information on XML based configuration.
4.4.3. Configuration
Configuration collects configuration informations, determines the
correct provider implementation and delegates it the ValidatorFactory
creation. This class lets you define:
the message interpolator strategy instance
the traversable resolver strategy instance
the constraint validator factory instance
XML constraint mappings
provider specific properties
whether or not META-INF/validation.xml is considered.
A Configuration does provide a MessageInterpolator implementation
following the default Bean Validation MessageInterpolator rules as
defined in Section 4.3.1, “Default message interpolation” by calling
getDefaultMessageInterpolator(). Such an implementation is useful to
let a custom MessageInterpolator delegates to the standard
MessageInterpolator(see Section 4.3.2, “Custom message interpolation”
and an example making use of getDefaultMessageInterpolator() in
Example 4.3, “Contextual container possible MessageInterpolator
implementation”).
Clients call Configuration.buildValidatorFactory() to retrieve the
initialized ValidatorFactory instance.
Example 4.12. Configuration interface
/**
* Receives configuration information, selects the appropriate
* Bean Validation provider and build the appropriate
* ValidatorFactory.
* <p/>
* Usage:
* <pre>
* Configuration<?> configuration = //provided by one of the
Validation bootstrap methods
* ValidatorFactory = configuration
* .messageInterpolator( new CustomMessageInterpolator() )
* .buildValidatorFactory();
* </pre>
* <p/>
*
* By default, the configuration information is retrieved from
* META-INF/validation.xml
* It is possible to override the configuration retrieved from the
XML file
* by using one or more of the Configuration methods.
*
* The ValidationProviderResolver is specified at Configuration time
* (see {@link javax.validation.spi.ValidationProvider}).
* If none is explicitely requested, the default
ValidationProviderResolver is used.
* <p/>
* The provider is selected in the following way:
* - if a specific Configuration subclass is requested
programmatically using
* Validation.byProvider(Class), find the first provider matching it
* - if a specific Configuration subclass is defined in META-INF/
validation.xml,
* find the first provider matching it
* - otherwise, use the first provider returned by the
ValidationProviderResolver
* <p/>
* Implementations are not meant to be thread-safe
*
* @author Emmanuel Bernard
*/
public interface Configuration<T extends Configuration<T>> {
/**
* Ignore data from the META-INF/validation.xml file if this
* method is called.
* This method is typically useful for containers that parse
* META-INF/validation.xml themselves and pass the information
* via the Configuration methods.
*/
T ignoreXmlConfiguration();
/**
* Defines the message interpolator used. Has priority over the
configuration
* based message interpolator.
*
* @param interpolator message interpolator implementation.
*
* @return <code>this</code> following the chaining method pattern.
*/
T messageInterpolator(MessageInterpolator interpolator);
/**
* Defines the traversable resolver used. Has priority over the
configuration
* based traversable resolver.
*
* @param resolver traversable resolver implementation.
*
* @return <code>this</code> following the chaining method pattern.
*/
T traversableResolver(TraversableResolver resolver);
/**
* Defines the constraint validator factory. Has priority over
the configuration
* based constraint factory.
*
* @param constraintValidatorFactory constraint factory
inmplementation.
*
* @return <code>this</code> following the chaining method pattern.
*/
T constraintValidatorFactory(ConstraintValidatorFactory
constraintValidatorFactory);
/**
* Add a stream describing constaint mapping in the Bean Validation
* XML format.
* <p/>
* The stream should be closed by the client API after the
* ValidatorFactory has been built. The Bean Validation provider
* must not close the stream.
*
* @param stream XML mapping stream.
*
* @return <code>this</code> following the chaining method pattern.
*/
T addMapping(InputStream stream);
/**
* Add a provider specific property. This property is equivalent to
* XML Configuration properties.
* If the underlying provider does not know how to handle the
property,
* it must silently ignore it.
*
* Note: Using this non type-safe method is generally not
recommended.
*
* It is more appropriate to use, if available, the type-safe
equivalent provided
* by a specific provider in its Configuration subclass.
* <code>ValidatorFactory factory =
Validation.byProvider(ACMEConfiguration.class)
* .configure()
* .providerSpecificProperty(ACMEState.FAST)
* .buildValidatorFactory();
* </code>
* This method is typically used by containers parsing META-INF/
validation.xml
* themselves and injecting the state to the Configuration object.
*
* If a property with a given name is defined both via this
method and in the
* XML configuration, the value set programmatically has priority.
*/
T addProperty(String name, String value);
/**
* Return an implementation of the MessageInterpolator interface
following the
* default MessageInterpolator defined in the specification:
* - use the ValidationMessages resource bundle to load keys
* - use Locale.getDefault()
*
* @return default MessageInterpolator implementation compliant
with the specification
*/
MessageInterpolator getDefaultMessageInterpolator();
/**
* Build a ValidatorFactory implementation.
*
* @return ValidatorFactory
*/
ValidatorFactory buildValidatorFactory();
}
A Bean Validation provider must define a sub interface of
Configuration uniquely identifying the provider. The isSuitable()
method of its ValidationProvider implementation must return true when
this sub interface type is passed as a parameter, false otherwise. The
Configuration sub interface typically hosts provider specific
configuration methods.
To facilitate the use of provider specific configuration methods,
Configuration uses generics: Configuration<T extends
Configuration<T>> ; the generic return type T is returned by chaining
methods. The provider specific sub interface must resolve the generic
T as itself as shown in the following example.
Example 4.13. Example of provider specific Configuration sub interface
/**
* Unique identifier of the ACME provider
* also host some provider specific configuration methods
*/
public interface ACMEConfiguration
extends Configuration<ACMEonfiguration> {
/**
* Enables contraints implementation dynamic reloading when using
ACME
* default to false
*/
Configuration enableDynamicReloading(boolean);
}
When Configuration.buildValidatorFactory() is called, the initialized
ValidatorFactory is returned. More specifically, the requested Bean
Validation provider is determined and the result of
validationProvider.buildValidatorFactory(ConfigurationState) is
returned. ConfigurationState gives access to the configuration
artifacts defined in META-INF/validation.xml (unless XML configuration
is ignored) and provided programmatically to Configuration. Generally
speaking, programmatically defined elements have priority over XML
defined configuration elements (read the Configuration JavaDoc and see
Section 4.4.6, “XML Configuration: META-INF/validation.xml” for more
information). A typical implementation ofConfiguration also implements
ConfigurationState, hence this can be passed to
buildValidatorFactory(ConfigurationState).
Streams represented in the XML configuration and opened by the
Configuration implementation must be closed by the Configuration
implementation after the ValidatorFactorycreation (or if an exception
occurs). Streams provided programmatically are the responsibility of
the application.
Example 4.14. ConfigurationState interface
/**
* Contract between a <code>Configuration</code> and a
* </code>ValidatorProvider</code> to create a
<code>ValidatorFactory</code>.
* The configuration artifacts defined in the XML configuration and
provided to the
* <code>Configuration</code> are merged and passed along via
ConfigurationState.
*
* @author Emmanuel Bernard
* @author Hardy Ferentschik
*/
public interface ConfigurationState {
/**
* returns true if Configuration.ignoreXMLConfiguration() has
been called
* In this case, the ValiatorFactory must ignore META-INF/
validation.xml
* @return true if META-INF/validation.xml should be ignored
*/
boolean isIgnoreXmlConfiguration();
/**
* Message interpolator as defined in the following decresing
priority:
* - set via the Configuration programmatic API
* - defined in META-INF/validation.xml provided that
ignoredXmlConfiguration
* is false. In this case the instance is created via its no-arg
constructor.
* - null if undefined.
*
* @return message provider instance or null if not defined
*/
MessageInterpolator getMessageInterpolator();
/**
* Returns a set of stream corresponding to:
* - mapping XML streams passed programmatically in Configuration
* - mapping XML stream located in the resources defined in
* META-INF/validation.xml (constraint-mapping element)
*
* Streams represented in the XML configuration and opened by the
* configuration implementation must be closed by the configuration
* implementation after the ValidatorFactory creation (or if an
exception
* occurs).
*
* @return set of input stream
*/
Set<InputStream> getMappingStreams();
/**
* ConstraintValidatorFactory implementation as defined in the
following
* decreasing priority:
* - set via the Configuration programmatic API
* - defined in META-INF/validation.xml provided that
ignoredXmlConfiguration
* is false. In this case the instance is created via its no-arg
constructor.
* - null if undefined.
*
* @return factory instance or null if not defined
*/
ConstraintValidatorFactory getConstraintValidatorFactory();
/**
* TraversableResolver as defined in the following decresing
priority:
* - set via the Configuration programmatic API
* - defined in META-INF/validation.xml provided that
ignoredXmlConfiguration
* is false. In this case the instance is created via its no-arg
constructor.
* - null if undefined.
*
* @return traversable provider instance or null if not defined
*/
TraversableResolver getTraversableResolver();
/**
* return non type-safe properties defined via:
* - Configuration.addProperty(String, String)
* - META-INF/validation.xml provided that ignoredXmlConfiguration
* is false.
*
* If a property is defined both programmatically and in XML,
* the value defined programmatically has priority
*
* @return Map whose key is the property key and the value the
property value
*/
Map<String, String> getProperties();
}
The requested provider implementation is resolved according to the
following rules in the following order:
Use the provider implementation requested if Configuration has been
created from Validation.byProvider(Class).
Use the provider implementation associated with the Configuration
implementation described in the XML configuration (under
validation.provider) if defined: the value of this element is the
fully qualified class name of the Configuration sub interface uniquely
identifying the provider.
Use the first provider implementation returned by
validationProviderResolver.getValidationProviders().
The ValidationProviderResolver is specified when Configuration
instances are created (see ValidationProvider). If no
ValidationProviderResolver instance has been specified, the default
ValidationProviderResolver is used.
Configuration instances are provided to the Bean Validation client
through the Validation methods. Configuration instances are created by
ValidationProvider.
Here is an example of Configuration use.
Example 4.15. Use Configuration
Configuration configuration = ...
ValidatorFactory factory = configuration
.messageInterpolator( new WBMessageInterpolator() )
.traversableResolver( new JPAAwareTraversableResolver() )
.buildValidatorFactory();
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/hibernate-dev/attachments/20090131/2db3f54f/attachment.html
More information about the hibernate-dev
mailing list