[hibernate-commits] Hibernate SVN: r15907 - in validator/trunk/hibernate-validator: src/main and 9 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Thu Feb 5 12:43:34 EST 2009


Author: hardy.ferentschik
Date: 2009-02-05 12:43:34 -0500 (Thu, 05 Feb 2009)
New Revision: 15907

Added:
   validator/trunk/hibernate-validator/src/main/docbook/
   validator/trunk/hibernate-validator/src/main/docbook/en-US/
   validator/trunk/hibernate-validator/src/main/docbook/en-US/images/
   validator/trunk/hibernate-validator/src/main/docbook/en-US/images/hibernate_logo_a.png
   validator/trunk/hibernate-validator/src/main/docbook/en-US/master.xml
   validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/
   validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/checkconstraints.xml
   validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/defineconstraints.xml
   validator/trunk/hibernate-validator/src/test/resources/org/
   validator/trunk/hibernate-validator/src/test/resources/org/hibernate/
   validator/trunk/hibernate-validator/src/test/resources/org/hibernate/validation/
   validator/trunk/hibernate-validator/src/test/resources/org/hibernate/validation/ValidationMessages_de.properties
Modified:
   validator/trunk/hibernate-validator/pom.xml
   validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ResourceBundleMessageInterpolator.java
Log:
Checked in a shell for the new documentation and added it to the build cycle

Modified: validator/trunk/hibernate-validator/pom.xml
===================================================================
--- validator/trunk/hibernate-validator/pom.xml	2009-02-05 17:41:58 UTC (rev 15906)
+++ validator/trunk/hibernate-validator/pom.xml	2009-02-05 17:43:34 UTC (rev 15907)
@@ -66,6 +66,62 @@
                     <testOutputDirectory>${project.build.directory}/site</testOutputDirectory>
                 </configuration>
             </plugin>
+            <plugin>
+                <groupId>org.jboss.maven.plugins</groupId>
+                <artifactId>maven-jdocbook-plugin</artifactId>
+                <version>2.1.0</version>
+                <extensions>true</extensions>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.hibernate</groupId>
+                        <artifactId>hibernate-jdocbook-style</artifactId>
+                        <version>1.0.2</version>
+                        <type>jdocbook-style</type>
+                    </dependency>
+                </dependencies>
+                <configuration>
+                    <sourceDocumentName>master.xml</sourceDocumentName>
+                    <sourceDirectory>${basedir}/src/main/docbook/en-US</sourceDirectory>
+                    <masterTranslation>en-US</masterTranslation>
+                    <imageResource>
+                        <directory>${basedir}/src/main/docbook/en-US/images</directory>
+                    </imageResource>
+                    <formats>
+                        <format>
+                            <formatName>pdf</formatName>
+                            <stylesheetResource>classpath:/xslt/hibernate/pdf/main-pdf.xsl</stylesheetResource>
+                            <finalName>hibernate-validator-guide.pdf</finalName>
+                        </format>
+                        <format>
+                            <formatName>html_single</formatName>
+                            <stylesheetResource>classpath:/xslt/hibernate/html/main-single.xsl
+                            </stylesheetResource>
+                            <finalName>index.html</finalName>
+                        </format>
+                        <format>
+                            <formatName>html</formatName>
+                            <stylesheetResource>classpath:/xslt/hibernate/html/main-chunk.xsl
+                            </stylesheetResource>
+                            <finalName>index.html</finalName>
+                        </format>
+                    </formats>
+                    <options>
+                        <xincludeSupported>true</xincludeSupported>
+                        <localeSeparator>-</localeSeparator>
+                        <useRelativeImageUris>true</useRelativeImageUris>
+                    </options>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>make-doc</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>resources</goal>
+                            <goal>generate</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
         </plugins>
     </build>
     <reporting>

Added: validator/trunk/hibernate-validator/src/main/docbook/en-US/images/hibernate_logo_a.png
===================================================================
(Binary files differ)


Property changes on: validator/trunk/hibernate-validator/src/main/docbook/en-US/images/hibernate_logo_a.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: validator/trunk/hibernate-validator/src/main/docbook/en-US/master.xml
===================================================================
--- validator/trunk/hibernate-validator/src/main/docbook/en-US/master.xml	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/main/docbook/en-US/master.xml	2009-02-05 17:43:34 UTC (rev 15907)
@@ -0,0 +1,92 @@
+<?xml version='1.0' encoding="UTF-8"?>
+<!--
+  ~ Hibernate, Relational Persistence for Idiomatic Java
+  ~
+  ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+  ~ indicated by the @author tags or express copyright attribution
+  ~ statements applied by the authors.  All third-party contributions are
+  ~ distributed under license by Red Hat Middleware LLC.
+  ~
+  ~ This copyrighted material is made available to anyone wishing to use, modify,
+  ~ copy, or redistribute it subject to the terms and conditions of the GNU
+  ~ Lesser General Public License, as published by the Free Software Foundation.
+  ~
+  ~ This program is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+  ~ or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+  ~ for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public License
+  ~ along with this distribution; if not, write to:
+  ~ Free Software Foundation, Inc.
+  ~ 51 Franklin Street, Fifth Floor
+  ~ Boston, MA  02110-1301  USA
+  -->
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+        <!ENTITY versionNumber "4.0.0.Alpha1">
+        <!ENTITY copyrightYear "2004">
+        <!ENTITY copyrightHolder "Red Hat Middleware, LLC.">
+]>
+
+<book lang="en">
+    <bookinfo>
+        <title>Hibernate Validator</title>
+        <subtitle>Reference Guide</subtitle>
+        <releaseinfo>&versionNumber;</releaseinfo>
+        <productnumber>&versionNumber;</productnumber>
+        <issuenum>1</issuenum>
+        <mediaobject>
+          <imageobject>
+            <imagedata fileref="images/hibernate_logo_a.png" format="png" />
+          </imageobject>
+        </mediaobject> 
+        <copyright>
+            <year>&copyrightYear;</year>
+            <holder>&copyrightHolder;</holder>
+        </copyright>
+        <!-- include translators... -->
+    </bookinfo>
+
+  <toc/>
+
+  <preface id="preface" revision="2">
+    <title>Preface</title>
+
+    <para>Annotations are a very convenient and elegant way to specify
+    invariant constraints for a domain model. You can, for example, express
+    that a property should never be null, that the account balance should be
+    strictly positive, etc. These domain model constraints are declared in the
+    bean itself by annotating its properties. A validator can then read them
+    and check for constraint violations. The validation mechanism can be
+    executed in different layers in your application without having to
+    duplicate any of these rules (presentation layer, data access layer).
+    Following the DRY principle, Hibernate Validator has been designed for
+    that purpose.</para>
+
+    <para>Hibernate Validator works at two levels. First, it is able to check
+    in-memory instances of a class for constraint violations. Second, it can
+    apply the constraints to the Hibernate metamodel and incorporate them into
+    the generated database schema.</para>
+
+    <para>Each constraint annotation is associated to a validator
+    implementation responsible for checking the constraint on the entity
+    instance. A validator can also (optionally) apply the constraint to the
+    Hibernate metamodel, allowing Hibernate to generate DDL that expresses the
+    constraint. With the appropriate event listener, you can execute the
+    checking operation on inserts and updates done by Hibernate. Hibernate
+    Validator is not limited to use with Hibernate. You can easily use it
+    anywhere in your application as well as with any Java Persistence provider
+    (entity listener provided).</para>
+
+    <para>When checking instances at runtime, Hibernate Validator returns
+    information about constraint violations in an array of
+    <classname>InvalidValue</classname> s. Among other information, the
+    <classname>InvalidValue</classname> contains an error description message
+    that can embed the parameter values bundle with the annotation (eg. length
+    limit), and message strings that may be externalized to a
+    <classname>ResourceBundle</classname> .</para>
+  </preface>
+
+  <xi:include href="modules/defineconstraints.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+  <xi:include href="modules/checkconstraints.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+</book>
\ No newline at end of file

Added: validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/checkconstraints.xml
===================================================================
--- validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/checkconstraints.xml	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/checkconstraints.xml	2009-02-05 17:43:34 UTC (rev 15907)
@@ -0,0 +1,235 @@
+<?xml version='1.0' encoding="UTF-8"?>
+<!--
+  ~ Hibernate, Relational Persistence for Idiomatic Java
+  ~
+  ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+  ~ indicated by the @author tags or express copyright attribution
+  ~ statements applied by the authors.  All third-party contributions are
+  ~ distributed under license by Red Hat Middleware LLC.
+  ~
+  ~ This copyrighted material is made available to anyone wishing to use, modify,
+  ~ copy, or redistribute it subject to the terms and conditions of the GNU
+  ~ Lesser General Public License, as published by the Free Software Foundation.
+  ~
+  ~ This program is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+  ~ or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+  ~ for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public License
+  ~ along with this distribution; if not, write to:
+  ~ Free Software Foundation, Inc.
+  ~ 51 Franklin Street, Fifth Floor
+  ~ Boston, MA  02110-1301  USA
+  -->
+
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+
+<chapter id="validator-checkconstraints">
+  <title>Using the Validator framework</title>
+
+  <para>Hibernate Validator is intended to be used to implement multi-layered
+  data validation, where constraints are expressed in a single place (the
+  annotated domain model) and checked in various different layers of the
+  application.</para>
+
+  <para>This chapter will cover Hibernate Validator usage for different
+  layers</para>
+
+  <section id="validator-checkconstraints-db" revision="2">
+    <title>Database schema-level validation</title>
+
+    <para>Out of the box, Hibernate Annotations will translate the constraints
+    you have defined for your entities into mapping metadata. For example, if
+    a property of your entity is annotated <literal>@NotNull</literal>, its
+    columns will be declared as <literal>not null</literal> in the DDL schema
+    generated by Hibernate.</para>
+
+    <para>Using hbm2ddl, domain model constraints will be expressed into the
+    database schema.</para>
+
+    <para>If, for some reason, the feature needs to be disabled, set
+    <literal>hibernate.validator.apply_to_ddl</literal> to
+    <literal>false</literal>.</para>
+  </section>
+
+  <section id="validator-checkconstraints-orm">
+    <title>ORM integration</title>
+
+    <para>Hibernate Validator integrates with both Hibernate and all pure Java
+    Persistence providers</para>
+
+    <section id="validator-checkconstraints-orm-hibernateevent" revision="1">
+      <title>Hibernate event-based validation</title>
+
+      <para>Hibernate Validator has two built-in Hibernate event listeners.
+      Whenever a <literal>PreInsertEvent</literal> or
+      <literal>PreUpdateEvent</literal> occurs, the listeners will verify all
+      constraints of the entity instance and throw an exception if any
+      constraint is violated. Basically, objects will be checked before any
+      inserts and before any updates made by Hibernate. This includes changes
+      applied by cascade! This is the most convenient and the easiest way to
+      activate the validation process. On constraint violation, the event will
+      raise a runtime <classname>InvalidStateException</classname> which
+      contains an array of <literal>InvalidValue</literal>s describing each
+      failure.</para>
+
+      <para>If Hibernate Validator is present in the classpath, Hibernate
+      Annotations (or Hibernate EntityManager) will use it transparently. If,
+      for some reason, you want to disable this integration, set
+      <literal>hibernate.validator.autoregister_listeners</literal> to
+      false</para>
+
+      <para><note>
+          <para>If the beans are not annotated with validation annotations,
+          there is no runtime performance cost.</para>
+        </note></para>
+
+      <para>In case you need to manually set the event listeners for Hibernate
+      Core, use the following configuration in
+      <literal>hibernate.cfg.xml</literal>:</para>
+
+      <programlisting>&lt;hibernate-configuration&gt;
+    ...
+    &lt;event type="pre-update"&gt;
+        &lt;listener 
+          class="org.hibernate.validator.event.ValidateEventListener"/&gt;
+    &lt;/event&gt;
+    &lt;event type="pre-insert"&gt;
+        &lt;listener 
+          class="org.hibernate.validator.event.ValidateEventListener"/&gt;
+    &lt;/event&gt;
+&lt;/hibernate-configuration&gt;</programlisting>
+    </section>
+
+    <section id="validator-checkconstraints-orm-jpaevent">
+      <title>Java Persistence event-based validation</title>
+
+      <para>Hibernate Validator is not tied to Hibernate for event based
+      validation: a Java Persistence entity listener is available. Whenever an
+      listened entity is persisted or updated, Hibernate Validator will verify
+      all constraints of the entity instance and throw an exception if any
+      constraint is violated. Basically, objects will be checked before any
+      inserts and before any updates made by the Java Persistence provider.
+      This includes changes applied by cascade! On constraint violation, the
+      event will raise a runtime <classname>InvalidStateException</classname>
+      which contains an array of <literal>InvalidValue</literal>s describing
+      each failure.</para>
+
+      <para>Here is how to make a class validatable:</para>
+
+      <programlisting>@Entity
+ at EntityListeners( JPAValidateListener.class )
+public class Submarine {
+    ...
+}</programlisting>
+
+      <para><note>
+          <para>Compared to the Hibernate event, the Java Persistence listener
+          has two drawbacks. You need to define the entity listener on every
+          validatable entity. The DDL generated by your provider will not
+          reflect the constraints.</para>
+        </note></para>
+    </section>
+  </section>
+
+  <section>
+    <title>Application-level validation</title>
+
+    <para>Hibernate Validator can be applied anywhere in your application
+    code.</para>
+
+    <programlisting>ClassValidator personValidator = new ClassValidator( Person.class );
+ClassValidator addressValidator = new ClassValidator( Address.class, ResourceBundle.getBundle("messages", Locale.ENGLISH) );
+
+InvalidValue[] validationMessages = addressValidator.getInvalidValues(address);</programlisting>
+
+    <para>The first two lines prepare the Hibernate Validator for class
+    checking. The first one relies upon the error messages embedded in
+    Hibernate Validator (see <xref
+    linkend="validator-defineconstraints-error" />), the second one uses a
+    resource bundle for these messages. It is considered a good practice to
+    execute these lines once and cache the validator instances.</para>
+
+    <para>The third line actually validates the <literal>Address</literal>
+    instance and returns an array of <literal>InvalidValue</literal>s. Your
+    application logic will then be able to react to the failure.</para>
+
+    <para>You can also check a particular property instead of the whole bean.
+    This might be useful for property per property user interaction</para>
+
+    <programlisting>ClassValidator addressValidator = new ClassValidator( Address.class, ResourceBundle.getBundle("messages", Locale.ENGLISH) );
+
+//only get city property invalid values
+InvalidValue[] validationMessages = addressValidator.getInvalidValues(address, "city");
+
+//only get potential city property invalid values
+InvalidValue[] validationMessages = addressValidator.getPotentialInvalidValues("city", "Paris")</programlisting>
+  </section>
+
+  <section>
+    <title>Presentation layer validation</title>
+
+    <para>When working with JSF and <productname>JBoss Seam</productname>, one
+    can triggers the validation process at the presentation layer using Seam's
+    JSF tags <literal>&lt;s:validate&gt;</literal> and
+    <literal>&lt;s:validateAll/&gt;</literal>, letting the constraints be
+    expressed on the model, and the violations presented in the view</para>
+
+    <programlisting>&lt;h:form&gt;
+    &lt;div&gt;
+        &lt;h:messages/&gt;
+    &lt;/div&gt;
+    <emphasis role="bold">&lt;s:validateAll&gt;</emphasis>
+        &lt;div&gt;
+            Country:
+            &lt;h:inputText value="#{location.country}" required="true"/&gt;
+        &lt;/div&gt;
+        &lt;div&gt;
+            Zip code:
+            &lt;h:inputText value="#{location.zip}" required="true"/&gt;
+        &lt;/div&gt;
+        &lt;div&gt;
+            &lt;h:commandButton/&gt;
+        &lt;/div&gt;
+    <emphasis role="bold">&lt;/s:validateAll&gt;</emphasis>
+&lt;/h:form&gt;</programlisting>
+
+    <para>Going even further, and adding <productname>Ajax4JSF</productname>
+    to the loop will bring client side validation with just a couple of
+    additional JSF tags, again without validation definition
+    duplication.</para>
+
+    <para>Check the <ulink url="http://www.jboss.com/products/seam">JBoss
+    Seam</ulink> documentation for more information.</para>
+  </section>
+
+  <section>
+    <title>Validation informations</title>
+
+    <para>As a validation information carrier, hibernate provide an array of
+    <classname>InvalidValue</classname>. Each <literal>InvalidValue</literal>
+    has a buch of methods describing the individual issues.</para>
+
+    <para><methodname>getBeanClass()</methodname> retrieves the failing bean
+    type</para>
+
+    <para><methodname>getBean()</methodname>retrieves the failing instance (if
+    any ie not when using
+    <methodname>getPotentianInvalidValues()</methodname>)</para>
+
+    <para><methodname>getValue()</methodname> retrieves the failing
+    value</para>
+
+    <para><methodname>getMessage()</methodname> retrieves the proper
+    internationalized error message</para>
+
+    <para><methodname>getRootBean()</methodname> retrieves the root bean
+    instance generating the issue (useful in conjunction with
+    <literal>@Valid</literal>), is null if getPotentianInvalidValues() is
+    used.</para>
+
+    <para><literal>getPropertyPath()</literal> retrieves the dotted path of
+    the failing property starting from the root bean</para>
+  </section>
+</chapter>
\ No newline at end of file

Added: validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/defineconstraints.xml
===================================================================
--- validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/defineconstraints.xml	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/defineconstraints.xml	2009-02-05 17:43:34 UTC (rev 15907)
@@ -0,0 +1,494 @@
+<?xml version='1.0' encoding="UTF-8"?>
+<!--
+  ~ Hibernate, Relational Persistence for Idiomatic Java
+  ~
+  ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+  ~ indicated by the @author tags or express copyright attribution
+  ~ statements applied by the authors.  All third-party contributions are
+  ~ distributed under license by Red Hat Middleware LLC.
+  ~
+  ~ This copyrighted material is made available to anyone wishing to use, modify,
+  ~ copy, or redistribute it subject to the terms and conditions of the GNU
+  ~ Lesser General Public License, as published by the Free Software Foundation.
+  ~
+  ~ This program is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+  ~ or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+  ~ for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public License
+  ~ along with this distribution; if not, write to:
+  ~ Free Software Foundation, Inc.
+  ~ 51 Franklin Street, Fifth Floor
+  ~ Boston, MA  02110-1301  USA
+  -->
+
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+
+<chapter id="validator-defineconstraints">
+  <title>Defining constraints</title>
+
+  <section id="validator-defineconstraints-definition" revision="1">
+    <title>What is a constraint?</title>
+
+    <para>A constraint is a rule that a given element (field, property or
+    bean) has to comply to. The rule semantic is expressed by an annotation. A
+    constraint usually has some attributes used to parameterize the
+    constraints limits. The constraint applies to the annotated
+    element.</para>
+  </section>
+
+  <section id="validator-defineconstraints-builtin" revision="2">
+    <title>Built in constraints</title>
+
+    <para>Hibernate Validator comes with some built-in constraints, which
+    covers most basic data checks. As we'll see later, you're not limited to
+    them, you can literally in a minute write your own constraints.</para>
+
+    <table>
+      <title>Built-in constraints</title>
+
+      <tgroup cols="4">
+        <colspec align="center" />
+
+        <thead>
+          <row>
+            <entry>Annotation</entry>
+
+            <entry>Apply on</entry>
+
+            <entry>Runtime checking</entry>
+
+            <entry>Hibernate Metadata impact</entry>
+          </row>
+        </thead>
+
+        <tbody>
+          <row>
+            <entry>@Length(min=, max=)</entry>
+
+            <entry>property (String)</entry>
+
+            <entry>check if the string length match the range</entry>
+
+            <entry>Column length will be set to max</entry>
+          </row>
+
+          <row>
+            <entry>@Max(value=)</entry>
+
+            <entry>property (numeric or string representation of a
+            numeric)</entry>
+
+            <entry>check if the value is less than or equals to max</entry>
+
+            <entry>Add a check constraint on the column</entry>
+          </row>
+
+          <row>
+            <entry>@Min(value=)</entry>
+
+            <entry>property (numeric or string representation of a
+            numeric)</entry>
+
+            <entry>check if the value is more than or equals to min</entry>
+
+            <entry>Add a check constraint on the column</entry>
+          </row>
+
+          <row>
+            <entry>@NotNull</entry>
+
+            <entry>property</entry>
+
+            <entry>check if the value is not null</entry>
+
+            <entry>Column(s) are not null</entry>
+          </row>
+
+          <row>
+            <entry>@NotEmpty</entry>
+
+            <entry>property</entry>
+
+            <entry>check if the string is not null nor empty. Check if the
+            connection is not null nor empty</entry>
+
+            <entry>Column(s) are not null (for String)</entry>
+          </row>
+
+          <row>
+            <entry>@Past</entry>
+
+            <entry>property (date or calendar)</entry>
+
+            <entry>check if the date is in the past</entry>
+
+            <entry>Add a check constraint on the column</entry>
+          </row>
+
+          <row>
+            <entry>@Future</entry>
+
+            <entry>property (date or calendar)</entry>
+
+            <entry>check if the date is in the future</entry>
+
+            <entry>none</entry>
+          </row>
+
+          <row>
+            <entry>@Pattern(regex="regexp", flag=) or @Patterns(
+            {@Pattern(...)} )</entry>
+
+            <entry>property (string)</entry>
+
+            <entry>check if the property match the regular expression given a
+            match flag (see <classname>java.util.regex.Pattern </classname>
+            )</entry>
+
+            <entry>none</entry>
+          </row>
+
+          <row>
+            <entry>@Range(min=, max=)</entry>
+
+            <entry>property (numeric or string representation of a
+            numeric)</entry>
+
+            <entry>check if the value is between min and max
+            (included)</entry>
+
+            <entry>Add a check constraint on the column</entry>
+          </row>
+
+          <row>
+            <entry>@Size(min=, max=)</entry>
+
+            <entry>property (array, collection, map)</entry>
+
+            <entry>check if the element size is between min and max
+            (included)</entry>
+
+            <entry>none</entry>
+          </row>
+
+          <row>
+            <entry>@AssertFalse</entry>
+
+            <entry>property</entry>
+
+            <entry>check that the method evaluates to false (useful for
+            constraints expressed in code rather than annotations)</entry>
+
+            <entry>none</entry>
+          </row>
+
+          <row>
+            <entry>@AssertTrue</entry>
+
+            <entry>property</entry>
+
+            <entry>check that the method evaluates to true (useful for
+            constraints expressed in code rather than annotations)</entry>
+
+            <entry>none</entry>
+          </row>
+
+          <row>
+            <entry>@Valid</entry>
+
+            <entry>property (object)</entry>
+
+            <entry>perform validation recursively on the associated object. If
+            the object is a Collection or an array, the elements are validated
+            recursively. If the object is a Map, the value elements are
+            validated recursively.</entry>
+
+            <entry>none</entry>
+          </row>
+
+          <row>
+            <entry>@Email</entry>
+
+            <entry>property (String)</entry>
+
+            <entry>check whether the string is conform to the email address
+            specification</entry>
+
+            <entry>none</entry>
+          </row>
+
+          <row>
+            <entry>@CreditCardNumber</entry>
+
+            <entry>property (String)</entry>
+
+            <entry>check whether the string is a well formated credit card
+            number (derivative of the Luhn algorithm)</entry>
+
+            <entry>none</entry>
+          </row>
+
+          <row>
+            <entry>@Digits</entry>
+
+            <entry>property (numeric or string representation of a
+            numeric)</entry>
+
+            <entry>check whether the property is a number having up to
+            <literal>integerDigits</literal> integer digits and
+            <literal>fractionalDigits</literal> fractonal digits</entry>
+
+            <entry>define column precision and scale</entry>
+          </row>
+
+          <row>
+            <entry>@EAN</entry>
+
+            <entry>property (string)</entry>
+
+            <entry>check whether the string is a properly formated EAN or
+            UPC-A code</entry>
+
+            <entry>none</entry>
+          </row>
+        </tbody>
+      </tgroup>
+    </table>
+  </section>
+
+  <section id="validator-defineconstraints-error" xreflabel="Error messages">
+    <title>Error messages</title>
+
+    <para>Hibernate Validator comes with a default set of error messages
+    translated in about ten languages (if yours is not part of it, please sent
+    us a patch). You can override those messages by creating a
+    <filename>ValidatorMessages.properties</filename> or (
+    <filename>ValidatorMessages_loc.properties</filename> ) and override the
+    needed keys. You can even add your own additional set of messages while
+    writing your validator annotations. If Hibernate Validator cannot resolve
+    a key from your resourceBundle nor from ValidatorMessage, it falls back to
+    the default built-in values.</para>
+
+    <para>Alternatively you can provide a
+    <classname>ResourceBundle</classname> while checking programmatically the
+    validation rules on a bean or if you want a completly different
+    interpolation mechanism, you can provide an implementation of
+    <literal>org.hibernate.validator.MessageInterpolator</literal> (check the
+    JavaDoc for more informations).</para>
+  </section>
+
+  <section id="validator-defineconstraints-own" revision="1">
+    <title>Writing your own constraints</title>
+
+    <para>Extending the set of built-in constraints is extremely easy. Any
+    constraint consists of two pieces: the constraint
+    <emphasis>descriptor</emphasis> (the annotation) and the constraint
+    <emphasis>validator</emphasis> (the implementation class). Here is a
+    simple user-defined descriptor:</para>
+
+    <programlisting>@ValidatorClass(CapitalizedValidator.class)
+ at Target(METHOD)
+ at Retention(RUNTIME)
+ at Documented
+public @interface Capitalized {
+    CapitalizeType type() default Capitalize.FIRST;
+    String message() default "has incorrect capitalization"
+}        </programlisting>
+
+    <para><literal>type</literal> is a parameter describing how the property
+    should to be capitalized. This is a user parameter fully dependant on the
+    annotation business.</para>
+
+    <para><literal>message</literal> is the default string used to describe
+    the constraint violation and is mandatory. You can hard code the string or
+    you can externalize part/all of it through the Java ResourceBundle
+    mechanism. Parameters values are going to be injected inside the message
+    when the <literal>{parameter}</literal> string is found (in our example
+    <literal>Capitalization is not {type}</literal> would generate
+    <literal>Capitalization is not FIRST</literal> ), externalizing the whole
+    string in <filename>ValidatorMessages.properties</filename> is considered
+    good practice. See <xref linkend="validator-defineconstraints-error" />
+    .</para>
+
+    <programlisting>@ValidatorClass(CapitalizedValidator.class)
+ at Target(METHOD)
+ at Retention(RUNTIME)
+ at Documented
+public @interface Capitalized {
+    CapitalizeType type() default Capitalize.FIRST;
+    String message() default "{validator.capitalized}";
+}
+
+
+#in ValidatorMessages.properties
+validator.capitalized = <literal>Capitalization is not {type}</literal>
+        </programlisting>
+
+    <para>As you can see the {} notation is recursive.</para>
+
+    <para>To link a descriptor to its validator implementation, we use the
+    <literal>@ValidatorClass</literal> meta-annotation. The validator class
+    parameter must name a class which implements
+    <literal>Validator&lt;ConstraintAnnotation&gt;</literal> .</para>
+
+    <para>We now have to implement the validator (ie. the rule checking
+    implementation). A validation implementation can check the value of the a
+    property (by implementing <literal>PropertyConstraint</literal> ) and/or
+    can modify the hibernate mapping metadata to express the constraint at the
+    database level (by implementing
+    <literal>PersistentClassConstraint</literal> )</para>
+
+    <programlisting>public class CapitalizedValidator
+        implements Validator&lt;Capitalized&gt;, PropertyConstraint {
+    private CapitalizeType type;
+
+    //part of the Validator&lt;Annotation&gt; contract,
+    //allows to get and use the annotation values
+    public void initialize(Capitalized parameters) {
+        type = parameters.type();
+    }
+
+    //part of the property constraint contract
+    public boolean isValid(Object value) {
+        if (value==null) return true;
+        if ( !(value instanceof String) ) return false;
+        String string = (String) value;
+        if (type == CapitalizeType.ALL) {
+            return string.equals( string.toUpperCase() );
+        }
+        else {
+            String first = string.substring(0,1);
+            return first.equals( first.toUpperCase();
+        }
+    }
+}        </programlisting>
+
+    <para>The <literal>isValid()</literal> method should return false if the
+    constraint has been violated. For more examples, refer to the built-in
+    validator implementations.</para>
+
+    <para>We only have seen property level validation, but you can write a
+    Bean level validation annotation. Instead of receiving the return instance
+    of a property, the bean itself will be passed to the validator. To
+    activate the validation checking, just annotated the bean itself instead.
+    A small sample can be found in the unit test suite.</para>
+
+    <para>If your constraint can be applied multiple times (with different
+    parameters) on the same property or type, you can use the following
+    annotation form:</para>
+
+    <programlisting>@Target(METHOD)
+ at Retention(RUNTIME)
+ at Documented
+<emphasis role="bold">public @interface Patterns {</emphasis>
+    Pattern[] value();
+}
+
+ at Target(METHOD)
+ at Retention(RUNTIME)
+ at Documented
+ at ValidatorClass(PatternValidator.class)
+public @interface Pattern {
+    String regexp();
+}</programlisting>
+
+    <para>Basically an annotation containing the value attribute as an array
+    of validator annotations.</para>
+  </section>
+
+  <section>
+    <title>Annotating your domain model</title>
+
+    <para>Since you are already familiar with annotations now, the syntax
+    should be very familiar</para>
+
+    <programlisting>public class Address {
+    private String line1;
+    private String line2;
+    private String zip;
+    private String state;
+    private String country;
+    private long id;
+
+    // a not null string of 20 characters maximum
+    @Length(max=20)
+    @NotNull
+    public String getCountry() {
+        return country;
+    }
+
+    // a non null string
+    @NotNull
+    public String getLine1() {
+        return line1;
+    }
+
+    //no constraint
+    public String getLine2() {
+        return line2;
+    }
+
+    // a not null string of 3 characters maximum
+    @Length(max=3) @NotNull
+    public String getState() {
+        return state;
+    }
+
+    // a not null numeric string of 5 characters maximum
+    // if the string is longer, the message will
+    //be searched in the resource bundle at key 'long'
+    @Length(max=5, message="{long}")
+    @Pattern(regex="[0-9]+")
+    @NotNull
+    public String getZip() {
+        return zip;
+    }
+
+    // should always be true
+    @AssertTrue
+    public boolean isValid() {
+        return true;
+    }
+
+    // a numeric between 1 and 2000
+    @Id @Min(1)
+    @Range(max=2000)
+    public long getId() {
+        return id;
+    }
+}        </programlisting>
+
+    <para>While the example only shows public property validation, you can
+    also annotate fields of any kind of visibility</para>
+
+    <programlisting>@MyBeanConstraint(max=45
+public class Dog {
+    @AssertTrue private boolean isMale;
+    @NotNull protected String getName() { ... };
+    ...
+}        </programlisting>
+
+    <para>You can also annotate interfaces. Hibernate Validator will check all
+    superclasses and interfaces extended or implemented by a given bean to
+    read the appropriate validator annotations.</para>
+
+    <programlisting>public interface Named {
+    @NotNull String getName();
+    ...
+}
+
+public class Dog implements Named {
+
+    @AssertTrue private boolean isMale;
+
+    public String getName() { ... };
+
+}
+        </programlisting>
+
+    <para>The name property will be checked for nullity when the Dog bean is
+    validated.</para>
+  </section>
+</chapter>
\ No newline at end of file

Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ResourceBundleMessageInterpolator.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ResourceBundleMessageInterpolator.java	2009-02-05 17:41:58 UTC (rev 15906)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ResourceBundleMessageInterpolator.java	2009-02-05 17:43:34 UTC (rev 15907)
@@ -30,11 +30,11 @@
 
 import org.hibernate.validation.util.LoggerFactory;
 
-
 /**
  * Resource bundle backed message interpolator.
  *
  * @author Emmanuel Bernard
+ * @author Hardy Ferentschik
  */
 public class ResourceBundleMessageInterpolator implements MessageInterpolator {
 	private static final String DEFAULT_VALIDATION_MESSAGES = "org.hibernate.validation.ValidationMessages";
@@ -63,6 +63,16 @@
 		defaultResourceBundle = ResourceBundle.getBundle( DEFAULT_VALIDATION_MESSAGES );
 	}
 
+	public String interpolate(String message, ConstraintDescriptor constraintDescriptor, Object value) {
+		// probably no need for caching, but it could be done by parameters since the map
+		// is immutable and uniquely built per Validation definition, the comparaison has to be based on == and not equals though
+		return replace( message, constraintDescriptor.getParameters() );
+	}
+
+	public String interpolate(String message, ConstraintDescriptor constraintDescriptor, Object value, Locale locale) {
+		throw new UnsupportedOperationException( "Interpolation for Locale. Has to be done." );
+	}
+
 	/**
 	 * Search current thread classloader for the resource bundle. If not found, search validator (this) classloader.
 	 *
@@ -101,17 +111,6 @@
 		return rb;
 	}
 
-	public String interpolate(String message, ConstraintDescriptor constraintDescriptor, Object value) {
-		//probably no need for caching, but it could be done by parameters since the map
-		//is immutable and uniquely built per Validation definition, the comparaison has to be based on == and not equals though
-		return replace( message, constraintDescriptor.getParameters() );
-	}
-
-	public String interpolate(String message, ConstraintDescriptor constraintDescriptor, Object value, Locale locale) {
-		throw new UnsupportedOperationException( "Interpolation for Locale. Has to be done." );
-	}
-
-
 	private String replace(String message, Map<String, Object> parameters) {
 		Matcher matcher = messagePattern.matcher( message );
 		StringBuffer sb = new StringBuffer();
@@ -122,7 +121,6 @@
 		return sb.toString();
 	}
 
-
 	private String resolveParameter(String token, Map<String, Object> parameters) {
 		Object variable = parameters.get( token );
 		if ( variable != null ) {

Added: validator/trunk/hibernate-validator/src/test/resources/org/hibernate/validation/ValidationMessages_de.properties
===================================================================
--- validator/trunk/hibernate-validator/src/test/resources/org/hibernate/validation/ValidationMessages_de.properties	                        (rev 0)
+++ validator/trunk/hibernate-validator/src/test/resources/org/hibernate/validation/ValidationMessages_de.properties	2009-02-05 17:43:34 UTC (rev 15907)
@@ -0,0 +1,11 @@
+# $Id: ValidationMessages.properties 15846 2009-02-02 11:56:15Z hardy.ferentschik $
+validator.notNull=may not be null
+validator.size=size must be between {min} and {max}
+validator.length=length must be between {min} and {max}
+validator.notEmpty=may not be empty
+validator.pattern=must match "{regex}"
+validator.min=must be greater than {value}
+validator.max=must be less than {value}
+validator.null=must be null
+validator.past=must be in the past
+validator.future=must be in the future




More information about the hibernate-commits mailing list