<?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-gettingstarted">
    <title id="getting-started">Getting started</title>

    <para>This chapter will show you how to get started with Hibernate
        Validator, the reference implementation (RI) of Bean Validation. For the
        following quickstart you need:
    </para>

    <itemizedlist>
        <listitem>
            <para>A JDK &gt;= 6</para>
        </listitem>

        <listitem>
            <para>
                <ulink url="http://maven.apache.org/">Apache Maven</ulink>
            </para>
        </listitem>

        <listitem>
            <para>An Internet connection (Maven has to download all required
                libraries)
            </para>
        </listitem>
    </itemizedlist>

    <section id="validator-gettingstarted-createproject">
        <title>Project set up</title>

        <para>In order to use Hibernate Validator within a Maven project, simply
            add the following dependency to your <filename>pom.xml</filename>:
        </para>

        <example>
            <title>Hibernate Validator Maven dependency</title>

            <programlisting language="XML" role="XML">&lt;dependency&gt;
                &lt;groupId&gt;org.hibernate&lt;/groupId&gt;
                &lt;artifactId&gt;hibernate-validator&lt;/artifactId&gt;
                &lt;version&gt;&version;&lt;/version&gt;
                &lt;/dependency&gt;</programlisting>
        </example>

        <para>This transitively pulls in the dependency to the Bean Validation API
            (<literal>javax.validation:validation-api:&bvVersion;</literal>).
        </para>

        <section id="validator-gettingstarted-uel">
            <title>Unified EL</title>

            <para>Hibernate Validator requires an implementation of the Unified
                Expression Language (<ulink url="jcp.org/en/jsr/detail?id=341">JSR
                    341</ulink>) for evaluating dynamic expressions in constraint violation
                messages (see<xref linkend="section-message-interpolation"/>). When
                your application runs in a Java EE container such as JBoss AS, an EL
                implementation is already provided by the container. In a Java SE
                environment, however, you have to add an implementation as dependency to
                your POM file. For instance you can add the following two dependencies
                to use the JSR 341<ulink url="http://uel.java.net/">reference
                    implementation</ulink>:
            </para>

            <example>
                <title>Maven dependencies for Unified EL reference
                    implementation
                </title>

                <programlisting language="XML" role="XML">&lt;dependency&gt;
                    &lt;groupId&gt;javax.el&lt;/groupId&gt;
                    &lt;artifactId&gt;javax.el-api&lt;/artifactId&gt;
                    &lt;version&gt;2.2.4&lt;/version&gt;
                    &lt;/dependency&gt;
                    &lt;dependency&gt;
                    &lt;groupId&gt;org.glassfish.web&lt;/groupId&gt;
                    &lt;artifactId&gt;javax.el&lt;/artifactId&gt;
                    &lt;version&gt;2.2.4&lt;/version&gt;
                    &lt;/dependency&gt;</programlisting>
            </example>
        </section>

        <section id="section-getting-started-cdi">
            <title>CDI</title>

            <para>Bean Validation defines integration points with CDI (Contexts and
                Dependency Injection for Java
                <superscript>TM</superscript>
                EE,<ulink
                        url="http://jcp.org/en/jsr/detail?id=346">JSR 346</ulink>). If your
                application runs in an environment which does not provide this
                integration out of the box, you may use the Hibernate Validator CDI
                portable extension by adding the following Maven dependency to your
                POM:
            </para>

            <example>
                <title>Hibernate Validator CDI portable extension Maven
                    dependency
                </title>

                <programlisting language="XML" role="XML">&lt;dependency&gt;
                    &lt;groupId&gt;org.hibernate&lt;/groupId&gt;
                    &lt;artifactId&gt;hibernate-validator-cdi&lt;/artifactId&gt;
                    &lt;version&gt;&version;&lt;/version&gt;
                    &lt;/dependency&gt;</programlisting>
            </example>

            <para>Note that adding this dependency is usually not required for
                applications running on a Java EE application server. You can learn more
                about the integration of Bean Validation and CDI in<xref
                        linkend="section-integration-with-cdi"/>.
            </para>
        </section>
    </section>

    <section id="validator-gettingstarted-createmodel">
        <title>Applying constraints</title>

        <para>Lets dive directly into an example to see how to apply
            constraints.
        </para>

        <example id="example-class-car">
            <title>Class
                <classname>Car</classname>
                annotated with
                constraints
            </title>

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

                import javax.validation.constraints.Min;
                import javax.validation.constraints.NotNull;
                import javax.validation.constraints.Size;

                public class Car {

                @NotNull
                private String manufacturer;

                @NotNull
                @Size(min = 2, max = 14)
                private String licensePlate;

                @Min(2)
                private int seatCount;

                public Car(String manufacturer, String licencePlate, int seatCount) {
                this.manufacturer = manufacturer;
                this.licensePlate = licencePlate;
                this.seatCount = seatCount;
                }

                //getters and setters ...
                }
            </programlisting>
        </example>

        <para>The<classname>@NotNull</classname>,
            <classname>@Size</classname>
            and
            <classname>@Min</classname>
            annotations are used to declare the
            constraints which should be applied to the fields of a
            <classname>Car</classname>
            instance:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <property>manufacturer</property>
                    must never be
                    <literal>null</literal>
                </para>
            </listitem>

            <listitem>
                <para>
                    <property>licensePlate</property>
                    must never be
                    <literal>null</literal>
                    and must be between 2 and 14 characters
                    long
                </para>
            </listitem>

            <listitem>
                <para>
                    <property>seatCount</property>
                    must be at least 2
                </para>

                <tip>
                    <para>You can find the complete source code of all examples used in
                        this reference guide in the Hibernate Validator
                        <ulink
                                url="https://github.com/hibernate/hibernate-validator/tree/master/documentation/src/test">
                            source
                            repository
                        </ulink>
                        on GitHub.
                    </para>
                </tip>
            </listitem>
        </itemizedlist>
    </section>

    <section>
        <title>Validating constraints</title>

        <para>To perform a validation of these constraints, you use a
            <classname>Validator</classname>
            instance. Let's have a look at a unit
            test for<classname>Car</classname>:
        </para>

        <example>
            <title>Class
                <classname>CarTest</classname>
                showing validation
                examples
            </title>

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

                import java.util.Set;
                import javax.validation.ConstraintViolation;
                import javax.validation.Validation;
                import javax.validation.Validator;
                import javax.validation.ValidatorFactory;

                import org.junit.BeforeClass;
                import org.junit.Test;

                import static org.junit.Assert.assertEquals;

                public class CarTest {

                private static Validator validator;

                @BeforeClass
                public static void setUp() {
                ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
                validator = factory.getValidator();
                }

                @Test
                public void manufacturerIsNull() {
                Car car = new Car( null, "DD-AB-123", 4 );

                Set&lt;ConstraintViolation&lt;Car&gt;&gt; constraintViolations =
                validator.validate( car );

                assertEquals( 1, constraintViolations.size() );
                assertEquals( "may not be null", constraintViolations.iterator().next().getMessage() );
                }

                @Test
                public void licensePlateTooShort() {
                Car car = new Car( "Morris", "D", 4 );

                Set&lt;ConstraintViolation&lt;Car&gt;&gt; constraintViolations =
                validator.validate( car );

                assertEquals( 1, constraintViolations.size() );
                assertEquals(
                "size must be between 2 and 14",
                constraintViolations.iterator().next().getMessage()
                );
                }

                @Test
                public void seatCountTooLow() {
                Car car = new Car( "Morris", "DD-AB-123", 1 );

                Set&lt;ConstraintViolation&lt;Car&gt;&gt; constraintViolations =
                validator.validate( car );

                assertEquals( 1, constraintViolations.size() );
                assertEquals(
                "must be greater than or equal to 2",
                constraintViolations.iterator().next().getMessage()
                );
                }

                @Test
                public void carIsValid() {
                Car car = new Car( "Morris", "DD-AB-123", 2 );

                Set&lt;ConstraintViolation&lt;Car&gt;&gt; constraintViolations =
                validator.validate( car );

                assertEquals( 0, constraintViolations.size() );
                }
                }
            </programlisting>
        </example>

        <para>In the
            <methodname>setUp()</methodname>
            method a
            <classname>Validator</classname>
            object is retrieved from the
            <classname>ValidatorFactory</classname>. A
            <classname>Validator</classname>
            instance is thread-safe and may be reused
            multiple times. It thus can safely be stored in a static field and be used
            in the test methods to validate the different
            <classname>Car</classname>
            instances.
        </para>

        <para>The
            <methodname>validate()</methodname>
            method returns a set of
            <classname>ConstraintViolation</classname>
            instances, which you can
            iterate over in order to see which validation errors occurred. The first
            three test methods show some expected constraint violations:
        </para>

        <itemizedlist>
            <listitem>
                <para>The
                    <classname>@NotNull</classname>
                    constraint on manufacturer
                    is violated in
                    <methodname>manufacturerIsNull()</methodname>
                </para>
            </listitem>

            <listitem>
                <para>The
                    <classname>@Size</classname>
                    constraint on licensePlate is
                    violated in
                    <methodname>licensePlateTooShort()</methodname>
                </para>
            </listitem>

            <listitem>
                <para>The
                    <classname>@Min</classname>
                    constraint on seatCount is
                    violated in
                    <methodname>seatCountTooLow()</methodname>
                </para>
            </listitem>
        </itemizedlist>

        <para>If the object validates successfully,
            <methodname>validate()</methodname>
            returns an empty set as you can see in
            <methodname>carIsValid()</methodname>.
        </para>

        <para>Note that only classes from the package
            <package>javax.validation</package>
            are used. These are provided from the
            Bean Validation API. No classes from Hibernate Validator are directly
            referenced, resulting in portable code.
        </para>
    </section>

    <section id="validator-gettingstarted-whatsnext">
        <title>Where to go next?</title>

        <para>That concludes the 5 minute tour through the world of Hibernate
            Validator and Bean Validation. Continue exploring the code examples or
            look at further examples referenced in<xref
                    linkend="validator-further-reading"/>.
        </para>

        <para>To learn more about the validation of beans and properties, just
            continue reading<xref linkend="chapter-bean-constraints"/>. If you are
            interested in using Bean Validation for the validation of method pre- and
            postcondition refer to<xref linkend="chapter-method-constraints"/>. In
            case your application has specific validation requirements have a look at
            <xref linkend="validator-customconstraints"/>.
        </para>
    </section>
</chapter>
