[[chapter-xml-configuration]]
== Configuring via XML

So far we have used the default configuration source for Bean Validation, namely annotations.
However, there also exist two kinds of XML descriptors allowing configuration via XML. The first
descriptor describes general Bean Validation behaviour and is provided as _META-INF/validation.xml_.
The second one describes constraint declarations and closely matches the constraint declaration
approach via annotations. Let's have a look at these two document types.

[NOTE]
====
The XSD files are available via
http://www.jboss.org/xml/ns/javax/validation/configuration/[http://www.jboss.org/xml/ns/javax/validation/configuration] and
http://www.jboss.org/xml/ns/javax/validation/mapping[http://www.jboss.org/xml/ns/javax/validation/mapping].
====

[[section-configuration-validation-xml]]
=== Configuring the validator factory in _validation.xml_

The key to enable XML configuration for Hibernate Validator is the file _META-INF/validation.xml_.
If this file exists on the classpath its configuration will be applied when the `ValidatorFactory`
gets created. <<image-validation-configuration>> shows a model view of the XML schema to which
_validation.xml_ has to adhere.

[[image-validation-configuration]]
.Validation configuration schema
image::validation-configuration-1.1.png[validation-configuration-1.1.xsd]

<<example-validation-xml>>
shows the several configuration options of _validation.xml_. All settings are optional and the same
configuration options are also available programmatically through `javax.validation.Configuration`. In
fact the XML configuration will be overridden by values explicitly specified via the programmatic
API. It is even possible to ignore the XML configuration completely via
`Configuration#ignoreXmlConfiguration()`. See also <<section-configuring-validator-factory>>.

[[example-validation-xml]]
.`validation.xml`
====
[source, XML]
----
<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">

    <default-provider>com.acme.ValidationProvider</default-provider>

    <message-interpolator>com.acme.MessageInterpolator</message-interpolator>
    <traversable-resolver>com.acme.TraversableResolver</traversable-resolver>
    <constraint-validator-factory>
        com.acme.ConstraintValidatorFactory
    </constraint-validator-factory>
    <parameter-name-provider>com.acme.ParameterNameProvider</parameter-name-provider>

    <executable-validation enabled="true">
        <default-validated-executable-types>
            <executable-type>CONSTRUCTORS</executable-type>
            <executable-type>NON_GETTER_METHODS</executable-type>
            <executable-type>GETTER_METHODS</executable-type>
        </default-validated-executable-types>
    </executable-validation>

    <constraint-mapping>META-INF/validation/constraints-car.xml</constraint-mapping>

    <property name="hibernate.validator.fail_fast">false</property>
</validation-config>
----
====

[WARNING]
====
There must only be one file named _META-INF/validation.xml_ on the classpath. If more than one is
found an exception is thrown.
====

The node `default-provider` allows to choose the Bean Validation provider. This is useful if there is
more than one provider on the classpath. `message-interpolator`, `traversable-resolver`,
`constraint-validator-factory` and `parameter-name-provider` allow to customize the used
implementations for the interfaces `MessageInterpolator`, `TraversableResolver`,
`ConstraintValidatorFactory` and `ParameterNameProvider` defined in the `javax.validation` package.
See the sub-sections of <<section-configuring-validator-factory>> for more information about these
interfaces.

`executable-validation` and its subnodes define defaults for method validation. The Bean Validation
specification defines constructor and non getter methods as defaults. The enabled attribute acts as
global switch to turn method validation on and off (see also <<chapter-method-constraints>>).

Via the `constraint-mapping` element you can list an arbitrary number of additional XML files
containing the actual constraint configuration. Mapping file names must be specified using their
fully-qualified name on the classpath. Details on writing mapping files can be found in the next
section.

Last but not least, you can specify provider specific properties via the `property` nodes. In the
example we are using the Hibernate Validator specific `hibernate.validator.fail_fast` property (see
<<section-fail-fast>>).

[[section-mapping-xml-constraints]]
=== Mapping constraints via `constraint-mappings`

Expressing constraints in XML is possible via files adhering to the schema seen in
<<image-mapping-configuration>>. Note that these mapping files are only processed if listed via
constraint-mapping in _validation.xml_.

[[image-mapping-configuration]]
.Validation mapping schema
image::validation-mapping-1.1.png[validation-mapping-1.1.xsd]

<<example-constraints-car>> shows how the classes +Car+ and +RentalCar+ from <<example-car>> resp.
<<example-rental-car>> could be mapped in XML.

[[example-constraints-car]]
.Bean constraints configured via XML
====
[source, XML]
----
<constraint-mappings
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.1.xsd"
    xmlns="http://jboss.org/xml/ns/javax/validation/mapping" version="1.1">

    <default-package>org.hibernate.validator.referenceguide.chapter05</default-package>
    <bean class="Car" ignore-annotations="true">
        <field name="manufacturer">
            <constraint annotation="javax.validation.constraints.NotNull"/>
        </field>
        <field name="licensePlate">
            <constraint annotation="javax.validation.constraints.NotNull"/>
        </field>
        <field name="seatCount">
            <constraint annotation="javax.validation.constraints.Min">
                <element name="value">2</element>
            </constraint>
        </field>
        <field name="driver">
            <valid/>
        </field>
        <getter name="passedVehicleInspection" ignore-annotations="true">
            <constraint annotation="javax.validation.constraints.AssertTrue">
                <message>The car has to pass the vehicle inspection first</message>
                <groups>
                    <value>CarChecks</value>
                </groups>
                <element name="max">10</element>
            </constraint>
        </getter>
    </bean>
    <bean class="RentalCar" ignore-annotations="true">
        <class ignore-annotations="true">
            <group-sequence>
                <value>RentalCar</value>
                <value>CarChecks</value>
            </group-sequence>
        </class>
    </bean>
    <constraint-definition annotation="org.mycompany.CheckCase">
        <validated-by include-existing-validators="false">
            <value>org.mycompany.CheckCaseValidator</value>
        </validated-by>
    </constraint-definition>
</constraint-mappings>
----
====

<<example-rental-station-xml>> shows how the constraints from
<<example-declaring-parameter-constraints>>, <<example-declaring-return-value-constraints>>
and <<example-specifying-constraint-target>> can be expressed in XML.

[[example-rental-station-xml]]
.Method constraints configured via XML
====
[source, XML]
----
<constraint-mappings
        xmlns="http://jboss.org/xml/ns/javax/validation/mapping"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation=
                "http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.1.xsd" version="1.1">

    <default-package>org.hibernate.validator.referenceguide.chapter07</default-package>

    <bean class="RentalStation" ignore-annotations="true">
        <constructor>
            <return-value>
                <constraint annotation="ValidRentalStation"/>
            </return-value>
        </constructor>

        <constructor>
            <parameter type="java.lang.String">
                <constraint annotation="javax.validation.constraints.NotNull"/>
            </parameter>
        </constructor>

        <method name="getCustomers">
            <return-value>
                <constraint annotation="javax.validation.constraints.NotNull"/>
                <constraint annotation="javax.validation.constraints.Size">
                    <element name="min">1</element>
                </constraint>
            </return-value>
        </method>

        <method name="rentCar">
            <parameter type="Customer">
                <constraint annotation="javax.validation.constraints.NotNull"/>
            </parameter>
            <parameter type="java.util.Date">
                <constraint annotation="javax.validation.constraints.NotNull"/>
                <constraint annotation="javax.validation.constraints.Future"/>
            </parameter>
            <parameter type="int">
                <constraint annotation="javax.validation.constraints.Min">
                    <element name="value">1</element>
                </constraint>
            </parameter>
        </method>
    </bean>

    <bean class="Garage" ignore-annotations="true">
        <method name="buildCar">
            <parameter type="java.util.List"/>
            <cross-parameter>
                <constraint annotation="ELAssert">
                    <element name="expression">...</element>
                    <element name="validationAppliesTo">PARAMETERS</element>
                </constraint>
            </cross-parameter>
        </method>
        <method name="paintCar">
            <parameter type="int"/>
            <return-value>
                <constraint annotation="ELAssert">
                    <element name="expression">...</element>
                    <element name="validationAppliesTo">RETURN_VALUE</element>
                </constraint>
            </return-value>
        </method>
    </bean>

</constraint-mappings>
----
====

The XML configuration is closely mirroring the programmatic API. For this reason it should suffice
to just add some comments. `default-package` is used for all fields where a class name is expected. If
the specified class is not fully qualified the configured default package will be used. Every
mapping file can then have several bean nodes, each describing the constraints on the entity with
the specified class name.

[WARNING]
====
A given class can only be configured once across all configuration files. The same applies for
constraint definitions for a given constraint annotation. It can only occur in one mapping file. If
these rules are violated a `ValidationException` is thrown.
====

Setting `ignore-annotations` to `true` means that constraint annotations placed on the configured bean
are ignored. The default for this value is true. `ignore-annotations` is also available for the nodes
`class`, `fields`, `getter`, `constructor`, `method`, `parameter`, `cross-parameter` and `return-value`.
If not explicitly specified on these levels the configured bean value applies.

The nodes `class`, `field`, `getter`, `constructor` and `method` (and its sub node parameter) determine on
which level the constraint gets placed. The `constraint` node is then used to add a constraint on the
corresponding level. Each constraint definition must define the class via the `annotation` attribute.
The constraint attributes required by the Bean Validation specification (`message`, `groups` and
`payload`) have dedicated nodes. All other constraint specific attributes are configured using the
`element` node.

The `class` node also allows to reconfigure the default group sequence (see
<<section-default-group-class>>) via the `group-sequence` node. Not shown in the example is the use
of `convert-group` to
specify group conversions (see <<section-group-conversion>>). This node is available on `field`,
`getter`, `parameter` and `return-value` and specifies a from and to attribute to specify the groups.

Last but not least, the list of `ConstraintValidator` instances associated to a given constraint
can be altered via the `constraint-definition` node. The annotation attribute represents the constraint
annotation being altered. The `validated-by` element represent the (ordered) list of `ConstraintValidator`
implementations associated to the constraint. If `include-existing-validator` is set to `false`,
validators defined on the constraint annotation are ignored. If set to `true`, the list of constraint
validators described in XML is concatenated to the list of validators specified on the annotation.

[TIP]
====
One use case for constraint-definition is to change the default constraint definition for `@URL`.
Historically, Hibernate Validator's default constraint validator for this constraint uses the
`java.net.URL` constructor to verify that an URL is valid.
However, there is also a purely regular expression based version available which can be configured using
XML:

.Using XML to register a regular expression based constraint definition for `@URL`
[source, XML]
----
<constraint-definition annotation="org.hibernate.validator.constraints.URL">
  <validated-by include-existing-validators="false">
    <value>org.hibernate.validator.constraintvalidators.RegexpURLValidator</value>
  </validated-by>
</constraint-definition>
----
====



