<?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-bootstrapping">
  <title>Bootstrapping</title>

  <para>We already seen in <xref linkend="section-validator-instance"/> the
  easiest way to create a <classname>Validator</classname> instance -
  <methodname>Validation.buildDefaultValidatorFactory</methodname>. In this
  chapter we have a look at the other methods in
  <classname>javax.validation.Validation</classname> and how they allow to
  configure several aspects of Bean Validation at bootstrapping time.</para>

  <para>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 <ulink
  url="http://docs.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#Service%20Provider">Java
  Service Provider</ulink> mechanism. A Bean Validation implementation
  includes the file
  <filename>javax.validation.spi.ValidationProvider</filename> in
  <filename>META-INF/services</filename>. This file contains the fully
  qualified classname of the <classname>ValidationProvider</classname> of the
  implementation. In the case of Hibernate Validator this is
  <classname>org.hibernate.validator.HibernateValidator</classname>.</para>

  <note>
    <para>If there are more than one Bean Validation implementation providers
    in the classpath and
    <methodname>Validation.buildDefaultValidatorFactory()</methodname> is
    used, there is no guarantee which provider will be chosen. To enforce the
    provider <methodname>Validation.byProvider()</methodname> should be
    used.</para>
  </note>

  <section id="section-validator-instance">
    <title><classname>Configuration</classname> and
    <classname>ValidatorFactory</classname></title>

    <para>There are three different methods in the Validation class to create
    a Validator instance. The easiest in shown in <xref
    linkend="example-build-default-validator-factory"/>.</para>

    <example id="example-build-default-validator-factory">
      <title>Validation.buildDefaultValidatorFactory()</title>

      <programlisting language="JAVA" role="JAVA">ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();</programlisting>
    </example>

    <para>You can also use the method
    <methodname>Validation.byDefaultProvider()</methodname> which will allow
    you to configure several aspects of the created Validator instance:</para>

    <example>
      <title>Validation.byDefaultProvider()</title>

      <programlisting language="JAVA" role="JAVA">Configuration&lt;?&gt; config = Validation.byDefaultProvider().configure();
config.messageInterpolator(new MyMessageInterpolator())
    .traversableResolver( new MyTraversableResolver())
    .constraintValidatorFactory(new MyConstraintValidatorFactory());

ValidatorFactory factory = config.buildValidatorFactory();
Validator validator = factory.getValidator();
</programlisting>
    </example>

    <para>We will learn more about <classname>MessageInterpolator</classname>,
    <classname>TraversableResolver</classname> and
    <classname>ConstraintValidatorFactory</classname> in the following
    sections.</para>

    <para>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 <classname>Validator</classname> creation looks
    like:</para>

    <example>
      <title>Validation.byProvider( HibernateValidator.class )</title>

      <programlisting language="JAVA" role="JAVA">HibernateValidatorConfiguration config = Validation.byProvider( HibernateValidator.class ).configure();
config.messageInterpolator(new MyMessageInterpolator())
    .traversableResolver( new MyTraversableResolver())
    .constraintValidatorFactory(new MyConstraintValidatorFactory());

ValidatorFactory factory = config.buildValidatorFactory();
Validator validator = factory.getValidator();</programlisting>
    </example>

    <para><tip>
        <para>The generated <classname>Validator</classname> instance is
        thread safe and can be cached.</para>
      </tip></para>
  </section>

  <section id="section-validation-provider-resolver">
    <title><classname>ValidationProviderResolver</classname></title>

    <para>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 <classname>ValidationProviderResolver</classname>. An
    example in an OSGi environment you could plug your custom provider
    resolver like seen in <xref linkend="example-provider-resolver"/>.</para>

    <example id="example-provider-resolver">
      <title>Providing a custom ValidationProviderResolver</title>

      <programlisting language="JAVA" role="JAVA">Configuration&lt;?&gt; config = Validation.byDefaultProvider()
    .providerResolver( new OSGiServiceDiscoverer() )
    .configure();

ValidatorFactory factory = config.buildValidatorFactory();
Validator validator = factory.getValidator();
</programlisting>
    </example>

    <para>Your <classname>OSGiServiceDiscoverer</classname> must in this case
    implement the interface
    <classname>ValidationProviderResolver</classname>:</para>

    <example>
      <title>ValidationProviderResolver interface</title>

      <programlisting language="JAVA" role="JAVA">public interface ValidationProviderResolver {
    /**
     * Returns a list of ValidationProviders available in the runtime environment.
     *
     * @return list of validation providers.  
     */
    List&lt;ValidationProvider&lt;?&gt;&gt; getValidationProviders();
}
</programlisting>
    </example>
  </section>

  <section id="section-message-interpolator">
    <title><classname>MessageInterpolator</classname></title>

    <para><xref linkend="section-message-interpolation"/> already discussed
    the default message interpolation algorithm. If you have special
    requirements for your message interpolation you can provide a custom
    interpolator using
    <methodname>Configuration.messageInterpolator()</methodname>. This message
    interpolator will be shared by all validators generated by the
    <classname>ValidatorFactory</classname> created from this
    <classname>Configuration</classname>. <xref
    linkend="example-message-interpolator"/> 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: <itemizedlist>
        <listitem>
          <para>${validatedValue}: this will call <methodname>String.valueOf
          </methodname>on the validated value.</para>
        </listitem>

        <listitem>
          <para>${validatedValue:&lt;format&gt;}: provide your own format
          string which will be passed to <code>String.format</code> together
          with the validated value. Refer to the javadoc of
          <code>String.format</code> for more information about the format
          options.</para>
        </listitem>
      </itemizedlist></para>

    <example id="example-message-interpolator">
      <title>Providing a custom MessageInterpolator</title>

      <programlisting language="JAVA" role="JAVA">Configuration&lt;?&gt; configuration = Validation.byDefaultProvider().configure();
ValidatorFactory factory = configuration
    .messageInterpolator(new ValueFormatterMessageInterpolator(configuration.getDefaultMessageInterpolator()))
    .buildValidatorFactory();

Validator validator = factory.getValidator();
</programlisting>
    </example>

    <tip>
      <para>It is recommended that <classname>MessageInterpolator</classname>
      implementations delegate final interpolation to the Bean Validation
      default <classname>MessageInterpolator</classname> to ensure standard
      Bean Validation interpolation rules are followed. The default
      implementation is accessible through
      <methodname>Configuration.getDefaultMessageInterpolator()</methodname>.</para>
    </tip>

    <section id="section-resource-bundle-locator">
      <title>ResourceBundleLocator</title>

      <para>A common use case is the ability to specify your own resource
      bundles for message interpolation. The default
      <classname>MessageInterpolator</classname> implementation in Hibernate
      Validator is called
      <classname>ResourceBundleMessageInterpolator</classname> and per default
      loads resource bundles via
      <methodname>ResourceBundle.getBundle</methodname>. However,
      <classname>ResourceBundleMessageInterpolator</classname> also allows you
      to specify a custom implementation of
      <classname>ResourceBundleLocator</classname> allowing you to provide
      your own resource bundles. <xref
      linkend="example-resource-bundle-locator"/> shows an example. In the
      example<methodname>
      HibernateValidatorConfiguration.getDefaultResourceBundleLocator</methodname>
      is used to retrieve the default
      <classname>ResourceBundleLocator</classname> which then can be passed to
      the custom implementation in order implement delegation.</para>

      <example id="example-resource-bundle-locator">
        <title>Providing a custom ResourceBundleLocator</title>

        <programlisting language="JAVA" role="JAVA">HibernateValidatorConfiguration configure = Validation.byProvider(HibernateValidator.class).configure();

ResourceBundleLocator defaultResourceBundleLocator = configure.getDefaultResourceBundleLocator(); 
ResourceBundleLocator myResourceBundleLocator = new MyCustomResourceBundleLocator(defaultResourceBundleLocator);

configure.messageInterpolator(new ResourceBundleMessageInterpolator(myResourceBundleLocator));
</programlisting>
      </example>

      <para>Hibernate Validator provides the following implementation of
      <classname>ResourceBundleLocator</classname> -
      <classname>PlatformResourceBundleLocator</classname> (the default) and
      <classname>AggregateResourceBundleLocator</classname>. 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.</para>
    </section>
  </section>

  <section>
    <title><classname>TraversableResolver</classname></title>

    <para>The usage of the <classname>TraversableResolver</classname> 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
    <classname>TraversableResolver</classname> interface (see <xref
    linkend="example-traversable-resolver"/>). In the example
    HibernateValidatorConfiguration.</para>

    <example id="example-traversable-resolver">
      <title>TraversableResolver interface</title>

      <programlisting language="JAVA" role="JAVA">/**
 * 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 &lt;code&gt;traversableProperty&lt;/code&gt; 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
     *        &lt;code&gt;traversableObject&lt;/code&gt;
     *        (using the path specification defined by Bean Validator).
     * @param elementType either &lt;code&gt;FIELD&lt;/code&gt; or &lt;code&gt;METHOD&lt;/code&gt;.
     *
     * @return &lt;code&gt;true&lt;/code&gt; if the Bean Validation provider is allowed to
     *         reach the property state, &lt;code&gt;false&lt;/code&gt; otherwise.
     */
     boolean isReachable(Object traversableObject,
                         Path.Node traversableProperty,
                         Class&lt;?&gt; 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 &lt;code&gt;@Valid&lt;/code&gt;.
     * Note that this method is called only if isReachable returns true for the same set of
     * arguments and if the property is marked as &lt;code&gt;@Valid&lt;/code&gt;
     *
     * @param traversableObject object hosting &lt;code&gt;traversableProperty&lt;/code&gt; 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
     *        &lt;code&gt;traversableObject&lt;/code&gt;
     *        (using the path specification defined by Bean Validator).
     * @param elementType either &lt;code&gt;FIELD&lt;/code&gt; or &lt;code&gt;METHOD&lt;/code&gt;.
     *
     * @return &lt;code&gt;true&lt;/code&gt; if the Bean Validation provider is allowed to
     *         cascade validation, &lt;code&gt;false&lt;/code&gt; otherwise.
     */
     boolean isCascadable(Object traversableObject,
                          Path.Node traversableProperty,
                          Class&lt;?&gt; rootBeanType,
                          Path pathToTraversableObject,
                          ElementType elementType);
}
</programlisting>
    </example>

    <para>Hibernate Validator provides two
    <classname>TraversableResolver</classname>s out of the box which will be
    enabled automatically depending on your environment. The first is the
    <classname>DefaultTraversableResolver</classname> which will always return
    true for <methodname>isReachable()</methodname> and
    <methodname>isTraversable()</methodname>. The second is the
    <classname>JPATraversableResolver</classname> 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
    <classname>Configuration</classname> object as seen in <xref
    linkend="example-traversable-resolver-config"/>.</para>

    <example id="example-traversable-resolver-config">
      <title>Providing a custom TraversableResolver</title>

      <programlisting language="JAVA" role="JAVA">Configuration&lt;?&gt; configuration = Validation.byDefaultProvider().configure();
ValidatorFactory factory = configuration
    .traversableResolver(new MyTraversableResolver())
    .buildValidatorFactory();

Validator validator = factory.getValidator();
</programlisting>
    </example>
  </section>

  <section>
    <title><classname>ConstraintValidatorFactory</classname></title>

    <para>Last but not least, there is one more configuration option to
    discuss, the <classname>ConstraintValidatorFactory</classname>. The
    default <classname>ConstraintValidatorFactory</classname> provided by
    Hibernate Validator requires a public no-arg constructor to instantiate
    <classname>ConstraintValidator</classname> instances (see <xref
    linkend="section-constraint-validator"/>). Using a custom
    <classname>ConstraintValidatorFactory</classname> offers for example the
    possibility to use dependency injection in constraint implementations. The
    configuration of the custom factory is once more via the
    <classname>Configuration</classname> (<xref
    linkend="example-constraint-validator-factory"/>).</para>

    <example id="example-constraint-validator-factory">
      <title>Providing a custom ConstraintValidatorFactory</title>

      <programlisting language="JAVA" role="JAVA">Configuration&lt;?&gt; configuration = Validation.byDefaultProvider().configure();
ValidatorFactory factory = configuration
    .constraintValidatorFactory(new IOCConstraintValidatorFactory())
    .buildValidatorFactory();

Validator validator = factory.getValidator();
</programlisting>
    </example>

    <para>The interface you have to implement is:</para>

    <example>
      <title>ConstraintValidatorFactory interface</title>

      <programlisting language="JAVA" role="JAVA">public interface ConstraintValidatorFactory {
    /**
     * @param key The class of the constraint validator to instantiate.
     *
     * @return A constraint validator instance of the specified class.
     */
     &lt;T extends ConstraintValidator&lt;?,?&gt;&gt; T getInstance(Class&lt;T&gt; key);
}
</programlisting>
    </example>

    <warning>
      <para>Any constraint implementation relying on
      <classname>ConstraintValidatorFactory</classname> behaviors specific to
      an implementation (dependency injection, no no-arg constructor and so
      on) are not considered portable.</para>
    </warning>

    <note>
      <para>ConstraintValidatorFactory should not cache instances as the state
      of each instance can be altered in the initialize method.</para>
    </note>
  </section>
</chapter>
