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

  <para>In <xref linkend="section-obtaining-validator"/> you already saw one
  way for creating a <classname>Validator</classname> instance - via
  <methodname>Validation#buildDefaultValidatorFactory()</methodname>. In this
  chapter you will learn how to use the other methods in
  <classname>javax.validation.Validation</classname> in order to bootstrap
  specifically configured validators.</para>

  <section id="section-retrieving-validator-factory-validator">
    <title>Retrieving <classname>ValidatorFactory</classname> and
    <classname>Validator</classname></title>

    <para>You obtain a <classname>Validator</classname> by retrieving a
    <classname>ValidatorFactory</classname> via one of the static methods on
    <classname>javax.validation.Validation</classname> and calling
    <classname>getValidator()</classname> on the factory instance.</para>

    <para><xref linkend="example-build-default-validator-factory"/> shows how
    to obtain a validator from the default validator factory:</para>

    <example id="example-build-default-validator-factory">
      <title>Bootstrapping default <classname>ValidatorFactory</classname> and
      <classname>Validator</classname></title>

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

    <tip>
      <para>The generated <classname>ValidatorFactory</classname> and
      <classname>Validator</classname> 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.</para>
    </tip>

    <para>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
    <methodname>buildDefaultValidatorFactory()</methodname>.</para>

    <para>In this case you can explicitly specify the provider to use via
    <methodname>Validation#byProvider()</methodname>, passing the provider's
    <classname>ValidationProvider</classname> class as shown in <xref
    linkend="example-using-specific-provider"/>.</para>

    <example id="example-using-specific-provider">
      <title>Bootstrapping <classname>ValidatorFactory</classname> and
      <classname>Validator</classname> using a specific provider</title>

      <programlisting language="JAVA" role="JAVA">ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
		.configure()
		.buildValidatorFactory();
Validator validator = validatorFactory.getValidator();</programlisting>
    </example>

    <para>Note that the configuration object returned by
    <methodname>configure()</methodname> allows to specifically customize the
    factory before calling <methodname>buildValidatorFactory()</methodname>.
    The available options are discussed later in this chapter.</para>

    <para>Similarly you can retrieve the default validator factory for
    configuration which is demonstrated in <xref
    linkend="example-configuring-default-provider"/>.</para>

    <example id="example-configuring-default-provider">
      <title>Retrieving the default <classname>ValidatorFactory</classname>
      for configuration</title>

      <programlisting language="JAVA" role="JAVA">ValidatorFactory validatorFactory = Validation.byDefaultProvider()
		.configure()
		.buildValidatorFactory();
Validator validator = validatorFactory.getValidator();</programlisting>
    </example>

    <note>
      <para>If a <classname>ValidatorFactory</classname> instance is no longer
      in use, it should be disposed by calling
      <methodname>ValidatorFactory#close()</methodname>. This will free any
      resources possibly allocated by the factory.</para>
    </note>

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

      <para>By default, available Bean Validation providers are discovered
      using the <ulink
      url="http://docs.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#Service%20Provider">Java
      Service Provider</ulink> mechanism.</para>

      <para>For that purpose, each provider includes the file
      <filename>META-INF/services/javax.validation.spi.ValidationProvider</filename>,
      containing the fully qualified classname of its
      <classname>ValidationProvider</classname> implementation. In the case of
      Hibernate Validator this is
      <classname>org.hibernate.validator.HibernateValidator</classname>.</para>

      <para>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
      <classname>ValidationProviderResolver</classname> implementation which
      performs the provider retrieval. An example is OSGi, where you could
      implement a provider resolver which uses OSGi services for provider
      discovery.</para>

      <para>To use a custom provider resolver pass it via
      <methodname>providerResolver()</methodname> as shown shown in <xref
      linkend="example-using-custom-validation-provider-resolver"/>.</para>

      <example id="example-using-custom-validation-provider-resolver">
        <title>Using a custom
        <classname>ValidationProviderResolver</classname></title>

        <programlisting language="JAVA" role="JAVA">package org.hibernate.validator.referenceguide.chapter08;

public class OsgiServiceDiscoverer implements ValidationProviderResolver {

	@Override
	public List&lt;ValidationProvider&lt;?&gt;&gt; getValidationProviders() {
		//...
	}
}</programlisting>

        <programlisting language="JAVA" role="JAVA">ValidatorFactory validatorFactory = Validation.byDefaultProvider()
		.providerResolver( new OsgiServiceDiscoverer() )
		.configure()
		.buildValidatorFactory();
Validator validator = validatorFactory.getValidator();</programlisting>
      </example>
    </section>
  </section>

  <section id="section-configuring-validator-factory">
    <title>Configuring a <classname>ValidatorFactory</classname></title>

    <para>By default validator factories retrieved from
    <classname>Validation</classname> and any validators they create are
    configured as per the XML descriptor
    <filename>META-INF/validation.xml</filename> (see <xref
    linkend="chapter-xml-configuration"/>), if present.</para>

    <para>If you want to disable the XML based configuration, you can do so by
    invoking
    <methodname>Configuration#ignoreXmlConfiguration()</methodname>.</para>

    <para>The different values of the XML configuration can be accessed via
    <methodname>Configuration#getBootstrapConfiguration()</methodname>. 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.</para>

    <para>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
    <classname>Configuration</classname> 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.</para>

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

      <para>Message interpolators are used by the validation engine to create
      user readable error messages from constraint message descriptors.</para>

      <para>In case the default message interpolation algorithm described in
      <xref linkend="chapter-message-interpolation"/> is not sufficient for
      your needs, you can pass in your own implementation of the
      <classname>MessageInterpolator</classname> interface via
      <classname>Configuration#messageInterpolator()</classname> as shown in
      <xref linkend="example-using-custom-message-interpolator"/>.</para>

      <example id="example-using-custom-message-interpolator">
        <title>Using a custom
        <classname>MessageInterpolator</classname></title>

        <programlisting language="JAVA" role="JAVA">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) {
		//...
	}
}</programlisting>

        <programlisting language="JAVA" role="JAVA">ValidatorFactory validatorFactory = Validation.byDefaultProvider()
		.configure()
		.messageInterpolator( new MyMessageInterpolator() )
		.buildValidatorFactory();
Validator validator = validatorFactory.getValidator();</programlisting>
      </example>
    </section>

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

      <para>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.</para>

      <para>Which properties can be accessed and which ones not is controlled
      by querying the <classname>TraversableResolver</classname> interface.
      <xref linkend="example-using-custom-traversable-resolver"/> shows how to
      use a custom traversable resolver implementation.</para>

      <example id="example-using-custom-traversable-resolver">
        <title>Using a custom
        <classname>TraversableResolver</classname></title>

        <programlisting language="JAVA" role="JAVA">package org.hibernate.validator.referenceguide.chapter08;

public class MyTraversableResolver implements TraversableResolver {

	@Override
	public boolean isReachable(
			Object traversableObject,
			Node traversableProperty,
			Class&lt;?&gt; rootBeanType,
			Path pathToTraversableObject,
			ElementType elementType) {
		//...
	}

	@Override
	public boolean isCascadable(
			Object traversableObject,
			Node traversableProperty,
			Class&lt;?&gt; rootBeanType,
			Path pathToTraversableObject,
			ElementType elementType) {
		//...
	}
}</programlisting>

        <programlisting language="JAVA" role="JAVA">ValidatorFactory validatorFactory = Validation.byDefaultProvider()
		.configure()
		.traversableResolver( new MyTraversableResolver() )
		.buildValidatorFactory();
Validator validator = validatorFactory.getValidator();</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
      <classname>DefaultTraversableResolver</classname> which will always
      return <literal>true</literal> for
      <methodname>isReachable()</methodname> and
      <methodname>isTraversable()</methodname>. The second is
      <classname>JPATraversableResolver</classname> which gets enabled when
      Hibernate Validator is used in combination with JPA 2.</para>
    </section>

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

      <para><classname>ConstraintValidatorFactory</classname> is the extension
      point for customizing how constraint validators are instantiated and
      released.</para>

      <para>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 validator
      implementations.</para>

      <para>To configure a custom constraint validator factory call
      <methodname>Configuration#constraintValidatorFactory()</methodname> (see
      <xref
      linkend="example-using-custom-constraint-validator-factory"/>.</para>

      <example id="example-using-custom-constraint-validator-factory">
        <title>Using a custom
        <classname>ConstraintValidatorFactory</classname></title>

        <programlisting language="JAVA" role="JAVA">package org.hibernate.validator.referenceguide.chapter08;

public class MyConstraintValidatorFactory implements ConstraintValidatorFactory {

	@Override
	public &lt;T extends ConstraintValidator&lt;?, ?&gt;&gt; T getInstance(Class&lt;T&gt; key) {
		//...
	}

	@Override
	public void releaseInstance(ConstraintValidator&lt;?, ?&gt; instance) {
		//...
	}
}</programlisting>

        <programlisting language="JAVA" role="JAVA">ValidatorFactory validatorFactory = Validation.byDefaultProvider()
		.configure()
		.constraintValidatorFactory( new MyConstraintValidatorFactory() )
		.buildValidatorFactory();
Validator validator = validatorFactory.getValidator();</programlisting>
      </example>

      <warning>
        <para>Any constraint implementations 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><classname>ConstraintValidatorFactory</classname>
        implementations should not cache validator instances as the state of
        each instance can be altered in the
        <methodname>initialize()</methodname> method.</para>
      </note>
    </section>

    <section id="section-parameter-name-provider">
      <title><classname>ParameterNameProvider</classname></title>

      <para>In case a method or constructor parameter constraint is violated,
      the <classname>ParameterNameProvider</classname> interface is used to
      retrieve the parameter's name and make it available to the user via the
      constraint violation's property path.</para>

      <para>The default implementation returns parameter names in the form
      <literal>arg0</literal>, <literal>arg1</literal> 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.</para>

      <para>Custom <classname>ParameterNameProvider</classname>
      implementations are used as demonstrated in <xref
      linkend="example-using-custom-parameter-name-provider"/>.</para>

      <example id="example-using-custom-parameter-name-provider">
        <title>Using a custom
        <classname>ParameterNameProvider</classname></title>

        <programlisting language="JAVA" role="JAVA">package org.hibernate.validator.referenceguide.chapter08;

public class MyParameterNameProvider implements ParameterNameProvider {

	@Override
	public List&lt;String&gt; getParameterNames(Constructor&lt;?&gt; constructor) {
		//...
	}

	@Override
	public List&lt;String&gt; getParameterNames(Method method) {
		//...
	}
}</programlisting>

        <programlisting language="JAVA" role="JAVA">ValidatorFactory validatorFactory = Validation.byDefaultProvider()
		.configure()
		.parameterNameProvider( new MyParameterNameProvider() )
		.buildValidatorFactory();
Validator validator = validatorFactory.getValidator();</programlisting>
      </example>

      <tip>
        <para>Hibernate Validator comes with a custom
        <classname>ParameterNameProvider</classname> implementation based on
        the <ulink url="http://paranamer.codehaus.org/">ParaNamer</ulink>
        library which provides several ways for obtaining parameter names at
        runtime. Refer to <xref
        linkend="section-paranamer-parameternameprovider"/> to learn more
        about this specific implementation.</para>
      </tip>
    </section>

    <section>
      <title>Adding mapping streams</title>

      <para>As discussed earlier you can configure the constraints applying
      for your Java beans using XML based constraint mappings.</para>

      <para>Besides the mapping files specified in
      <filename>META-INF/validation.xml</filename> you can add further
      mappings via <methodname>Configuration#addMapping()</methodname> (see
      <xref linkend="example-adding-mapping-streams"/>). Note that the passed
      input stream(s) must adhere to the XML schema for constraint mappings
      presented in <xref linkend="section-mapping-xml-constraints"/>.</para>

      <example id="example-adding-mapping-streams">
        <title>Adding constraint mapping streams</title>

        <programlisting language="JAVA" role="JAVA">InputStream constraintMapping1 = ...;
InputStream constraintMapping2 = ...;
ValidatorFactory validatorFactory = Validation.byDefaultProvider()
		.configure()
		.addMapping( constraintMapping1 )
		.addMapping( constraintMapping2 )
		.buildValidatorFactory();
Validator validator = validatorFactory.getValidator();</programlisting>
      </example>

      <para>You should close any passed input stream after the validator
      factory has been created.</para>
    </section>

    <section id="section-provider-specific-settings">
      <title>Provider-specific settings</title>

      <para>Via the configuration object returned by
      <methodname>Validation#byProvider()</methodname> provider specific
      options can be configured.</para>

      <para>In case of Hibernate Validator this e.g. allows you to enable the
      fail fast mode and pass one or more programmatic constraint mappings as
      demonstrated in <xref
      linkend="example-hibernate-validator-specific-options"/>.</para>

      <example id="example-hibernate-validator-specific-options">
        <title>Setting Hibernate Validator specific options</title>

        <programlisting language="JAVA" role="JAVA">ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
		.configure()
		.failFast( true )
		.addMapping( (ConstraintMapping) null )
		.buildValidatorFactory();
Validator validator = validatorFactory.getValidator();</programlisting>
      </example>

      <para>Alternatively, provider-specific options can be passed via
      <methodname>Configuration#addProperty()</methodname>. Hibernate
      Validator supports enabling the fail fast mode that way, too:</para>

      <example id="example-hibernate-validator-specific-option-via-addproperty">
        <title>Enabling a Hibernate Validator specific option via
        <methodname>addProperty()</methodname></title>

        <programlisting language="JAVA" role="JAVA">ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
		.configure()
		.addProperty( "hibernate.validator.fail_fast", "true" )
		.buildValidatorFactory();
Validator validator = validatorFactory.getValidator();</programlisting>
      </example>

      <para>Refer to <xref linkend="section-fail-fast"/> and <xref
      linkend="section-programmatic-api"/> to learn more about the fail fast
      mode and the constraint declaration API.</para>
    </section>
  </section>

  <section id="section-configuring-validator">
    <title>Configuring a <classname>Validator</classname></title>

    <para>When working with a configured validator factory it can occasionally
    be required to apply a different configuration to a single
    <classname>Validator</classname> instance. <xref
    linkend="example-using-context"/> shows how this can be achieved by
    calling <methodname>ValidatorFactory#usingContext()</methodname>.</para>

    <example id="example-using-context">
      <title>Configuring a <classname>Validator</classname> via
      <methodname>usingContext()</methodname></title>

      <programlisting language="JAVA" role="JAVA">ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();

Validator validator = validatorFactory.usingContext()
		.messageInterpolator( new MyMessageInterpolator() )
		.traversableResolver( new MyTraversableResolver() )
		.getValidator();</programlisting>
    </example>
  </section>
</chapter>
