Author: hardy.ferentschik
Date: 2009-09-10 05:44:26 -0400 (Thu, 10 Sep 2009)
New Revision: 17501
Modified:
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/bootstrapping.xml
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/customconstraints.xml
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/gettingstarted.xml
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/usingvalidator.xml
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/xmlconfiguration.xml
Log:
HV-220
Modified:
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/bootstrapping.xml
===================================================================
---
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/bootstrapping.xml 2009-09-10
08:42:57 UTC (rev 17500)
+++
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/bootstrapping.xml 2009-09-10
09:44:26 UTC (rev 17501)
@@ -32,7 +32,7 @@
how to create a <classname>Validator</classname> instance using the
different methods in <classname>javax.validation.Validation</classname>.
In
this chapter we have a closer look and discuss the different configuration
- possibilties available via the <classname>Configuration</classname>
+ possibilities available via the <classname>Configuration</classname>
object.</para>
<para>One requirement of the Bean Validation framework is that each
@@ -54,49 +54,224 @@
<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>
+ used.</para>
</note></para>
<section>
<title><classname>ValidationProviderResolver</classname></title>
- <para>The </para>
+ <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>
+
+ <para><example id="example-provider-resolver">
+ <title>Providing a custom ValidationProviderResolver</title>
+
+ <programlisting>Configuration<?> config =
Validation.byDefaultProvider()
+ <emphasis role="bold">.providerResolver( new OSGiServiceDiscoverer()
)</emphasis>
+ .configure();
+
+ValidatorFactory factory = config.buildValidatorFactory();
+Validator validator = factory.getValidator();
+</programlisting>
+ </example>Your <classname>OSGiServiceDiscoverer</classname> must
in this
+ case implement the interface
+ <classname>ValidationProviderResolver</classname>:</para>
+
+ <example>
+ <title>ValidationProviderResolver interface</title>
+
+ <programlisting>public interface ValidationProviderResolver {
+ /**
+ * Returns a list of ValidationProviders available in the runtime environment.
+ *
+ * @return list of validation providers.
+ */
+ List<ValidationProvider<?>> getValidationProviders();
+}
+</programlisting>
+ </example>
</section>
<section>
<title><classname>MessageInterpolator</classname></title>
- <para>The message interpolator is provided to the ValidatorFactory at
- construction time using Configuration.messageInterpolator(). This message
- interpolator is shared by all validators gener- ated by this
- ValidatorFactory. It is recommended that MessageInterpolator
- implementations delegate final interpolation to the Bean Validation
- default MessageInterpolator to ensure standard Bean Validation
- interpolation rules are followed. The default implementation is accessible
- through Configuration.getDefaultMessageInterpolator().</para>
+ <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>(see <xref
+ linkend="example-message-interpolator" />).</para>
+
+ <example id="example-message-interpolator">
+ <title>Providing a custom MessageInterpolator</title>
+
+ <programlisting>Configuration<?> configuration =
Validation.byDefaultProvider().configure();
+ValidatorFactory factory = configuration
+ <emphasis role="bold">.messageInterpolator(new
ContextualMessageInterpolator(configuration.getDefaultMessageInterpolator()))</emphasis>
+ .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>
<section>
<title><classname>TraversableResolver</classname></title>
- <para>The Bean Validation provider must not access the state of a
- property, nor validate its constraints if the property is not traversable.
- A property is traversable if TraversableResolver returns true for this
- property.</para>
+ <para>The usage of the <classname>TraversableResolver</classname>
has so
+ far been not be 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" />).<example
+ id="example-traversable-resolver">
+ <title>TraversableResolver interface</title>
+
+ <programlisting>/**
+ * 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
<code>traversableProperty</code> 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
+ * <code>traversableObject</code>
+ * (using the path specification defined by Bean Validator).
+ * @param elementType either <code>FIELD</code> or
<code>METHOD</code>.
+ *
+ * @return <code>true</code> if the Bean Validation
provider is allowed to
+ * reach the property state, <code>false</code>
otherwise.
+ */
+ boolean isReachable(Object traversableObject,
+ Path.Node traversableProperty,
+ Class<?> 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 <code>@Valid</code>.
+ * Note that this method is called only if isReachable returns true for the same set
of
+ * arguments and if the property is marked as
<code>@Valid</code>
+ *
+ * @param traversableObject object hosting
<code>traversableProperty</code> 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
+ * <code>traversableObject</code>
+ * (using the path specification defined by Bean Validator).
+ * @param elementType either <code>FIELD</code> or
<code>METHOD</code>.
+ *
+ * @return <code>true</code> if the Bean Validation
provider is allowed to
+ * cascade validation, <code>false</code>
otherwise.
+ */
+ boolean isCascadable(Object traversableObject,
+ Path.Node traversableProperty,
+ Class<?> rootBeanType,
+ Path pathToTraversableObject,
+ ElementType elementType);
+}
+</programlisting>
+ </example>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
+ i<methodname>sTraversable()</methodname>. The second is the
+ <classname>JPATraversableResolver</classname> which gets enabled when
+ Hibernate Validator gets used in combination with JPA2. 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" />.<example
+ id="example-traversable-resolver-config">
+ <title>Providing a custom TraversableResolver</title>
+
+ <programlisting>Configuration<?> configuration =
Validation.byDefaultProvider().configure();
+ValidatorFactory factory = configuration
+ <emphasis role="bold">.traversableResolver(new
MyTraversableResolver())</emphasis>
+ .buildValidatorFactory();
+
+Validator validator = factory.getValidator();
+</programlisting>
+ </example></para>
</section>
<section>
<title><classname>ConstraintValidatorFactory</classname></title>
- <para>The default ConstraintValidatorFactory provided by the Bean
- Validation provider implementation uses the pub- lic constraint no-arg
- constructor. A custom ConstraintValidatorFactory can be provided for
- example to benefit from dependency injection control in constraint
- implementations. Any constraint implementation relying on Con-
- straintValidatorFactory behaviors specific to an implementation
- (dependency injection, no no-arg constructor and so on) are not considered
- portable, hence great care should be given before walking that path.
- ConstraintValidatorFactory should not cache instances as the state of each
- instance can be altered in the ini- tialize method.</para>
+ <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 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>
+
+ <para><example id="example-constraint-validator-factory">
+ <title>Providing a custom ConstraintValidatorFactory</title>
+
+ <programlisting>Configuration<?> configuration =
Validation.byDefaultProvider().configure();
+ValidatorFactory factory = configuration
+ <emphasis role="bold">.constraintValidatorFactory(new
IOCConstraintValidatorFactory())</emphasis>
+ .buildValidatorFactory();
+
+Validator validator = factory.getValidator();
+</programlisting>
+ </example>The interface you have to implement is:</para>
+
+ <para><example>
+ <title>ConstraintValidatorFactory interface</title>
+
+ <programlisting>public interface ConstraintValidatorFactory {
+ /**
+ * @param key The class of the constraint validator to instantiate.
+ *
+ * @return A constraint validator instance of the specified class.
+ */
+ <T extends ConstraintValidator<?,?>> T
getInstance(Class<T> 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></para>
</section>
</chapter>
Modified:
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/customconstraints.xml
===================================================================
---
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/customconstraints.xml 2009-09-10
08:42:57 UTC (rev 17500)
+++
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/customconstraints.xml 2009-09-10
09:44:26 UTC (rev 17501)
@@ -166,7 +166,8 @@
</section>
<section id="validator-customconstraints-validator"
revision="1">
- <title>The constraint validator</title>
+ <title id="section-constraint-validator">The constraint
+ validator</title>
<para>Next, we need to implement a constraint validator, that's able to
validate elements with a <classname>@CheckCase</classname> annotation.
Modified:
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/gettingstarted.xml
===================================================================
---
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/gettingstarted.xml 2009-09-10
08:42:57 UTC (rev 17500)
+++
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/gettingstarted.xml 2009-09-10
09:44:26 UTC (rev 17501)
@@ -232,8 +232,8 @@
<classname>ValidatorFactory</classname>. A
<classname>Validator</classname> instance is thread-safe and may be
reused
multiple times, therefore we store it as field of our test class. We can
- use the validator now to validate the different car instances in the test
- methods.</para>
+ use the <classname>Validator</classname> now to validate the different
car
+ instances in the test methods.</para>
<para>The <methodname>validate()</methodname> method returns a set
of
<classname>ConstraintViolation</classname> instances, which we can
iterate
Modified:
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/usingvalidator.xml
===================================================================
---
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/usingvalidator.xml 2009-09-10
08:42:57 UTC (rev 17500)
+++
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/usingvalidator.xml 2009-09-10
09:44:26 UTC (rev 17501)
@@ -145,7 +145,7 @@
provider accesses the instance variable directly.</para>
<note>
- <para>The access type (private, protected or plublic) does not
+ <para>The access type (private, protected or public) does not
matter.</para>
</note>
@@ -483,7 +483,7 @@
<para>All of three methods return a
<classname>Set<ConstraintViolation></classname>. The set
is empty,
- if the validation succeedes. Otherwise a
+ if the validation succeeds. Otherwise a
<classname>ConstraintViolation</classname> instance is added to the
set
for each violated constraint.</para>
@@ -523,7 +523,7 @@
<para>With help of the
<methodname>validateProperty()</methodname> a
single named property of a given object can be validated. The property
- name is the JavaBeans property name. </para>
+ name is the JavaBeans property name.</para>
<example>
<title>Usage of
@@ -580,7 +580,7 @@
returns. Using the different methods of a
<classname>ConstraintViolation</classname> instance a lot of useful
information about the cause of the validation failure can be determined.
- <xref linkend="table-constraint-violation" /> gived an overview of
these
+ <xref linkend="table-constraint-violation" /> gives an overview of
these
methods:</para>
<table id="table-constraint-violation">
@@ -651,7 +651,7 @@
</table>
</section>
- <section>
+ <section id="section-message-interpolation">
<title>Message interpolation</title>
<para>As we will see in <xref
linkend="validator-customconstraints" />
@@ -663,7 +663,7 @@
<classname>MessageInterpolator</classname>. The interpolator will try
to
resolve any message parameters, meaning string literals enclosed in
braces. In order to resolve these parameters Hibernate Validator's
- default <classname>MessageInterpolator</classname> first recusively
+ default <classname>MessageInterpolator</classname> first recursively
resolves parameters against a custom
<classname>ResourceBundle</classname> called
<filename>ValidationMessages.properties</filename> at the root of the
@@ -678,7 +678,7 @@
to be validated.</para>
<para>Since the braces { and } have special meaning in the messages they
- need to be escpaped if they are used literally. The following The
+ need to be escaped if they are used literally. The following The
following rules apply:<itemizedlist>
<listitem>
<para>\{ is considered as the literal {</para>
@@ -693,7 +693,7 @@
</listitem>
</itemizedlist></para>
- <para>If the default message interpolator does ot fit your requirements
+ <para>If the default message interpolator does not fit your requirements
it is possible to plug a custom
<classname>MessageInterpolator</classname> when the
<classname>ValidatorFactory</classname> gets created. This can be seen
@@ -715,7 +715,7 @@
First we have the class <classname>Person</classname> (<xref
linkend="example-person" />) which has a <classname>@NotNull
</classname>constraint on <property>name</property>. Since no group
is
- specified for this annoation its default groups is
+ specified for this annotation its default groups is
<classname>javax.validation.Default</classname>.</para>
<note>
@@ -919,7 +919,7 @@
must not be involved in a cyclic dependency either directly or
indirectly, either through cascaded sequence definition or group
inheritance. If a group containing such a circularity is evaluated,
- a GroupDefinitionException is raised.</para>
+ a <classname>GroupDefinitionException</classname> is
raised.</para>
</warning>The usage of the new sequence could then look like in <xref
linkend="example-group-sequence" />.</para>
@@ -984,8 +984,8 @@
</example>
<note>
- <para>Due to the fact that there cannot be a cyclic dependecy in the
- group and group sequence defintions one cannot just at
+ <para>Due to the fact that there cannot be a cyclic dependency in the
+ group and group sequence definitions one cannot just at
<classname>Default</classname> to the sequence redefining
<classname>Default</classname> for a class. Instead the class itself
should be added!</para>
@@ -1058,7 +1058,7 @@
<classname>BigInteger</classname>,
<classname>String</classname>,
<classname>byte</classname>,
<classname>short</classname>,
<classname>int</classname>,
<classname>long</classname> and the
- respective warppers of the primtive types.</entry>
+ respective wrappers of the primitive types.</entry>
<entry>The annotated element must be a number whose value must be
lower or equal to the specified maximum. The parameter value is
@@ -1078,7 +1078,7 @@
<classname>BigInteger</classname>,
<classname>String</classname>,
<classname>byte</classname>,
<classname>short</classname>,
<classname>int</classname>,
<classname>long</classname> and the
- respective warppers of the primtive types.</entry>
+ respective wrappers of the primitive types.</entry>
<entry>The annotated element must be a number whose value must be
higher or equal to the specified maximum. The parameter value is
@@ -1098,7 +1098,7 @@
<classname>BigInteger</classname>,
<classname>String</classname>,
<classname>byte</classname>,
<classname>short</classname>,
<classname>int</classname>,
<classname>long</classname> and the
- respective warppers of the primtive types.</entry>
+ respective wrappers of the primitive types.</entry>
<entry>Check whether the property is a number having up to
<literal>integer</literal> digits and
<literal>fraction</literal>
@@ -1145,9 +1145,9 @@
<classname>BigInteger</classname>,
<classname>String</classname>,
<classname>byte</classname>,
<classname>short</classname>,
<classname>int</classname>,
<classname>long</classname> and the
- respective warppers of the primtive types.</entry>
+ respective wrappers of the primitive types.</entry>
- <entry>Checks whether the annoated value is less than or equal to
+ <entry>Checks whether the annotated value is less than or equal to
the specified maximum.</entry>
<entry>Add a check constraint on the column.</entry>
@@ -1163,10 +1163,10 @@
<classname>BigInteger</classname>,
<classname>String</classname>,
<classname>byte</classname>,
<classname>short</classname>,
<classname>int</classname>,
<classname>long</classname> and the
- respective warppers of the primtive types.</entry>
+ respective wrappers of the primitive types.</entry>
- <entry>Check whether the annoated value is higher than or equal to
- the specified minimum.</entry>
+ <entry>Check whether the annotated value is higher than or equal
+ to the specified minimum.</entry>
<entry>Add a check constraint on the column.</entry>
</row>
@@ -1178,7 +1178,7 @@
<entry>field/property</entry>
- <entry>Check that the annoated value is not
+ <entry>Check that the annotated value is not
<constant>null.</constant></entry>
<entry>Column(s) are not null.</entry>
Modified:
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/xmlconfiguration.xml
===================================================================
---
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/xmlconfiguration.xml 2009-09-10
08:42:57 UTC (rev 17500)
+++
validator/trunk/hibernate-validator/src/main/docbook/en-US/modules/xmlconfiguration.xml 2009-09-10
09:44:26 UTC (rev 17501)
@@ -53,7 +53,7 @@
</mediaobject>
</example></para>
- <para> <xref linkend="example-validation-xml" /> shows the
several
+ <para><xref linkend="example-validation-xml" /> shows the
several
configuration options of
<filename>validation.xml</filename>.</para>
<example id="example-validation-xml">
@@ -91,12 +91,12 @@
These are the same configuration option as available programmatically
through the <classname>javax.validation.Configuration</classname>. In
fact
XML configuration will be overriden by values explicitly specified via the
- API. It is even possible to ignore the xml configuration completely via
+ API. It is even possible to ignore the XML configuration completely via
<methodname> Configuration.ignoreXmlConfiguration()</methodname>. See
also
<xref linkend="validator-bootstrapping" />.</para>
<para>Via the <property>constraint-mapping</property> you can list
an
- abritrary number of additional xml files containing the actual constraint
+ arbitrary number of additional XML files containing the actual constraint
configuration. See <xref linkend="section-mapping-constraints"
/>.</para>
<para>Last but not least, you can specify provider specific properties via
@@ -131,7 +131,7 @@
<para><xref linkend="example-constraints-car" /> shows how our
classes Car
and RentalCar from <xref linkend="example-car" /> resp. <xref
- linkend="example-rental-car" /> could be mapped in xml.</para>
+ linkend="example-rental-car" /> could be mapped in XML.</para>
<example id="example-constraints-car">
<title>constraints-car.xml</title>
@@ -181,7 +181,7 @@
</constraint-mappings></programlisting>
</example>
- <para>The xml configurtion is closely mirroring the programmatic API. For
+ <para>The XML configuration is closely mirroring the programmatic API. For
this reason it should suffice to just add some comments.
<property>default-package</property> is used for all fields where a
classname is expected. If the specified class is not fully qualified the
@@ -214,7 +214,7 @@
<property>group-sequence</property> node.</para>
<para>Last but not least, constraint annotations cannot be configured in
- xml. However, the list of <classname>ConstraintValidator</classname>s
+ XML. However, the list of <classname>ConstraintValidator</classname>s
associated to a given constraint can be altered via the
<property>constraint-definition</property> node. The
<property>annotation</property> attribute represents the constraint