All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ation.beanvalidation-tck-tests.3.0.0-M1.source-code.tck-audit.xml Maven / Gradle / Ivy

There is a newer version: 3.0.1
Show newest version
<?xml version="1.0" encoding="UTF-8"?>
<!--

    Jakarta Bean Validation TCK

    License: Apache License, Version 2.0
    See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.

-->
<!-- Generated by tck-audit.xsl at 2020-03-03 19:09 (revision 2.0.2-24-g2bf1fa6) -->
<specification xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xalan="http://xml.apache.org/xslt" xmlns:exslt="http://exslt.org/common" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://jboss.com/products/weld/tck/audit" xsi:schemaLocation="http://jboss.com/products/weld/tck/audit" name="Jakarta Bean Validation 3.0" version="3.0.0" id="beanvalidation" generateSectionIds="true">
    <section id="introduction" title="Introduction" level="1">
        <!-- 1 - INTRODUCTION -->
    </section>
    <section id="introduction-expertgroup" title="Expert group" level="2">
        <!-- 1.1 - INTRODUCTION_EXPERTGROUP -->
    </section>
    <section id="introduction-goals" title="Specification goals" level="2">
        <!-- 1.2 - INTRODUCTION_GOALS -->
    </section>
    <section id="introduction-requirements" title="Required Java version" level="2">
        <!-- 1.3 - INTRODUCTION_REQUIREMENTS -->
    </section>
    <section id="introduction-documentorganization" title="How this document is organized" level="2">
        <!-- 1.4 - INTRODUCTION_DOCUMENTORGANIZATION -->
    </section>
    <section id="introduction-commentingprocess" title="How to comment" level="2">
        <!-- 1.5 - INTRODUCTION_COMMENTINGPROCESS -->
    </section>
    <section id="whatsnew" title="What's new" level="1">
        <!-- 2 - WHATSNEW -->
    </section>
    <section id="whatsnew-30" title="What's new in 3.0" level="2">
        <!-- 2.1 - WHATSNEW_30 -->
    </section>
    <section id="whatsnew-20" title="What's new in 2.0" level="2">
        <!-- 2.2 - WHATSNEW_20 -->
    </section>
    <section id="whatsnew-11" title="What's new in 1.1" level="2">
        <!-- 2.3 - WHATSNEW_11 -->
    </section>
    <section id="whatsnew-11-openness" title="Openness" level="3">
        <!-- 2.3.1 - WHATSNEW_11_OPENNESS -->
    </section>
    <section id="whatsnew-11-dependencyinjection" title="Dependency injection" level="3">
        <!-- 2.3.2 - WHATSNEW_11_DEPENDENCYINJECTION -->
    </section>
    <section id="whatsnew-11-methodvalidation" title="Method validation" level="3">
        <!-- 2.3.3 - WHATSNEW_11_METHODVALIDATION -->
    </section>
    <section id="whatsnew-11-contextdependencyinjection" title="Integration with CDI" level="3">
        <!-- 2.3.4 - WHATSNEW_11_CONTEXTDEPENDENCYINJECTION -->
    </section>
    <section id="whatsnew-11-groupconversion" title="Group conversion" level="3">
        <!-- 2.3.5 - WHATSNEW_11_GROUPCONVERSION -->
    </section>
    <section id="whatsnew-11-expressionlanguage" title="Message interpolation via the unified expression language" level="3">
        <!-- 2.3.6 - WHATSNEW_11_EXPRESSIONLANGUAGE -->
    </section>
    <section id="whatsnew-11-others" title="Others" level="3">
        <!-- 2.3.7 - WHATSNEW_11_OTHERS -->
    </section>
    <section id="constraintsdefinitionimplementation" title="Constraint definition" level="1">
        <!-- 3 - CONSTRAINTSDEFINITIONIMPLEMENTATION -->
    </section>
    <section id="constraintsdefinitionimplementation-constraintdefinition" title="Constraint annotation" level="2">
        <!-- 3.1 - CONSTRAINTSDEFINITIONIMPLEMENTATION_CONSTRAINTDEFINITION -->
        <assertion id="a" testable="false">
            <text>An annotation is considered a constraint definition if its retention policy contains RUNTIME and if the annotation itself is annotated with jakarta.validation.Constraint</text>
        </assertion>
        <assertion id="b" testable="false">
            <text>Generic constraint annotations can target any of the following ElementTypes: FIELD for constrained attributes METHOD for constrained getters and constrained method return values CONSTRUCTOR for constrained constructor return values PARAMETER for constrained method and constructor parameters TYPE for constrained beans ANNOTATION_TYPE for constraints composing other constraints TYPE_USE for container element constraints</text>
        </assertion>
        <assertion id="c" testable="false">
            <text>Cross-parameter constraint annotations can target any of the following ElementTypes: METHOD CONSTRUCTOR ANNOTATION_TYPE for cross-parameter constraints composing other cross-parameter constraints</text>
        </assertion>
        <assertion id="d" testable="false">
            <text>A constraint annotation that is both can target the union of the generic and cross-parameter constraint annotations targets.</text>
        </assertion>
        <assertion id="e">
            <text>Applying a constraint annotation to an incompatible type will raise an UnexpectedTypeException.</text>
        </assertion>
        <assertion id="f">
            <text>At most one ConstraintValidator supporting cross-parameter validation must be present for a given constraint. A ConstraintDefinitionException is raised otherwise.</text>
        </assertion>
        <assertion id="g">
            <text>If a constraint definition is not valid, a ConstraintDefinitionException is raised either at validation time or when the metadata is requested.</text>
        </assertion>
    </section>
    <section id="constraintsdefinitionimplementation-constraintdefinition-properties" title="Constraint definition properties" level="3">
        <!-- 3.1.1 - CONSTRAINTSDEFINITIONIMPLEMENTATION_CONSTRAINTDEFINITION_PROPERTIES -->
        <assertion id="a">
            <text>A constraint definition may have attributes that are specified at the time the constraint is applied to a JavaBean.</text>
        </assertion>
        <assertion id="b">
            <text>Annotation elements starting with valid are not allowed</text>
        </assertion>
    </section>
    <section id="constraintsdefinitionimplementation-constraintdefinition-properties-message" title="message" level="4">
        <!-- 3.1.1.1 - CONSTRAINTSDEFINITIONIMPLEMENTATION_CONSTRAINTDEFINITION_PROPERTIES_MESSAGE -->
        <assertion id="a">
            <text>Every constraint annotation must define a message element of type String.</text>
        </assertion>
    </section>
    <section id="constraintsdefinitionimplementation-constraintdefinition-properties-groups" title="groups" level="4">
        <!-- 3.1.1.2 - CONSTRAINTSDEFINITIONIMPLEMENTATION_CONSTRAINTDEFINITION_PROPERTIES_GROUPS -->
        <assertion id="a">
            <text>Every constraint annotation must define a groups element that specifies the processing groups with which the constraint declaration is associated.</text>
        </assertion>
        <assertion id="b">
            <text>The type of the groups parameter is Class&lt;?&gt;[].</text>
        </assertion>
        <assertion id="c">
            <text>The default value must be an empty array.</text>
        </assertion>
        <assertion id="d">
            <text>If no group is specified when declaring the constraint on an element, the Default group is considered declared.</text>
        </assertion>
    </section>
    <section id="constraintsdefinitionimplementation-constraintdefinition-properties-payload" title="payload" level="4">
        <!-- 3.1.1.3 - CONSTRAINTSDEFINITIONIMPLEMENTATION_CONSTRAINTDEFINITION_PROPERTIES_PAYLOAD -->
        <assertion id="a">
            <text>Constraint annotations must define a payload element that specifies the payload with which the constraint declaration is associated. The type of the payload parameter is Payload[].</text>
        </assertion>
        <assertion id="b">
            <text>The default value must be an empty array.</text>
        </assertion>
        <assertion id="c">
            <text>Each attachable payload extends Payload.</text>
        </assertion>
    </section>
    <section id="constraintsdefinitionimplementation-constraintdefinition-properties-validationappliesto" title="validationAppliesTo" level="4">
        <!-- 3.1.1.4 - CONSTRAINTSDEFINITIONIMPLEMENTATION_CONSTRAINTDEFINITION_PROPERTIES_VALIDATIONAPPLIESTO -->
        <assertion id="a">
            <text>The element validationAppliesTo must only be present for constraints that are both generic and cross-parameter, it is mandatory in this situation. A ConstraintDefinitionException is raised if these rules are violated.</text>
        </assertion>
        <assertion id="b">
            <text>The type of the validationAppliesTo parameter is ConstraintTarget. The default value must be ConstraintTarget.IMPLICIT.</text>
        </assertion>
        <assertion id="c">
            <text>If a ConstraintTarget is used in an illegal situation, a ConstraintDeclarationException is raised either at validation time or when the metadata is requested.</text>
        </assertion>
        <assertion id="d">
            <text>Using IMPLICIT in a situation that cannot be inferred (see the JavaDoc for the detailed rules),</text>
        </assertion>
        <assertion id="e">
            <text>Using PARAMETERS on a constructor or method that has no parameter,</text>
        </assertion>
        <assertion id="f">
            <text>Using RETURN_VALUE on a method with no return value,</text>
        </assertion>
        <assertion id="g">
            <text>Using PARAMETERS or RETURN_VALUE on a type - class or interface - or on a field.</text>
        </assertion>
    </section>
    <section id="constraintsdefinitionimplementation-constraintdefinition-properties-specific" title="Constraint specific parameter" level="4">
        <!-- 3.1.1.5 - CONSTRAINTSDEFINITIONIMPLEMENTATION_CONSTRAINTDEFINITION_PROPERTIES_SPECIFIC -->
    </section>
    <section id="constraintsdefinitionimplementation-constraintdefinition-examples" title="Examples" level="3">
        <!-- 3.1.2 - CONSTRAINTSDEFINITIONIMPLEMENTATION_CONSTRAINTDEFINITION_EXAMPLES -->
    </section>
    <section id="constraintsdefinitionimplementation-multipleconstraints" title="Applying multiple constraints of the same type" level="2">
        <!-- 3.2 - CONSTRAINTSDEFINITIONIMPLEMENTATION_MULTIPLECONSTRAINTS -->
        <assertion id="a">
            <text>The Jakarta Bean Validation provider treats regular annotations (annotations not annotated by @Constraint) whose value element has a return type of an array of constraint annotations in a special way. Each element in the value array are processed by the Jakarta Bean Validation implementation as regular constraint annotations.</text>
        </assertion>
        <assertion id="b">
            <text>This marks the constraint annotation type as repeatable and lets users specify the constraint several times without explicitly using the List annotation.</text>
        </assertion>
    </section>
    <section id="constraintsdefinitionimplementation-constraintcomposition" title="Constraint composition" level="2">
        <!-- 3.3 - CONSTRAINTSDEFINITIONIMPLEMENTATION_CONSTRAINTCOMPOSITION -->
        <assertion id="a">
            <text>More formally, each constraint annotation hosted on a constraint annotation is applied to the target element and this is done recursively.</text>
        </assertion>
        <assertion id="b">
            <text>Note that the main annotation and its constraint validation implementation is also applied.</text>
        </assertion>
        <assertion id="c">
            <text>By default, each failing constraint generates an error report.</text>
        </assertion>
        <assertion id="d">
            <text>Groups from the main constraint annotation are inherited by the composing annotations.</text>
        </assertion>
        <assertion id="e">
            <text>Any groups definition on a composing annotation is ignored.</text>
        </assertion>
        <assertion id="f">
            <text>Payload from the main constraint annotation is inherited by the composing annotations.</text>
        </assertion>
        <assertion id="g">
            <text>Any payload definition on a composing annotation is ignored.</text>
        </assertion>
        <assertion id="h">
            <text>The constraint target from the main constraint annotation is inherited by the composing annotations.</text>
        </assertion>
        <assertion id="i">
            <text>Any validationAppliesTo definition on a composing annotation is ignored.</text>
        </assertion>
        <assertion id="j">
            <text>The type upon which composed constraint is placed must be compatible with all constraints (composing and composed).</text>
        </assertion>
        <assertion id="k">
            <text>All composed and composing constraints must have a constraint type in common.</text>
        </assertion>
        <assertion id="l">
            <text>More specifically, if a composed constraint is marked as @ReportAsSingleViolation, the evaluation of the composing constraints stops at the first failing constraint and the error report corresponding to the composed constraint is generated and returned.</text>
        </assertion>
        <assertion id="m">
            <text>Composing annotations can define the value of message and custom attributes (excluding groups, payload and validationAppliesTo) but these are fixed in the composed constraint definition.</text>
        </assertion>
        <assertion id="n">
            <text>It is possible to override attributes and messages defined on a composing annotation. An attribute from the main annotation is used to override one or more attributes of the composing annotations. Such an attribute is annotated with one or more @OverridesAttribute annotations.</text>
        </assertion>
        <assertion id="o">
            <text>If left undefined, the default value for @OverridesAttribute.name is the name of the composed constraint attribute hosting the @OverridesAttribute annotation.</text>
        </assertion>
        <assertion id="p">
            <text>The types of the overridden and overriding attributes must be identical.</text>
        </assertion>
        <assertion id="q">
            <text>A composing constraint can itself be a composed constraint. In this case, attribute values are overridden recursively according to the described rules.</text>
        </assertion>
        <assertion id="r">
            <text>If a constraint is used more than once as a composing constraint, the multi value constraints model as described in 3.2 is used.</text>
        </assertion>
        <assertion id="s">
            <text>If the composing constraints are directly given on the composed constraint (i.e. via the repeatable annotation feature), constraintIndex refers to the left-to-right order of the constraints of this type in which they are given on the composed constraint.</text>
        </assertion>
        <assertion id="t">
            <text>If the composing constraints are specified using their corresponding List annotation, constraintIndex refers to the index within the value array.</text>
        </assertion>
        <assertion id="u">
            <text>A composing constraint must not be given directly on the composed constraint and using the corresponding List annotation at the same time. A ConstraintDeclarationException will be raised in this case.</text>
        </assertion>
        <assertion id="v">
            <text>If index is undefined, the single constraint declaration is targeted.</text>
        </assertion>
        <assertion id="w">
            <text>If the composition is invalid, e.g. infinitely recursive composition wrong attribute overriding a single attribute mapped to more than one source attribute a composing and composed constraint marked as different constraint types (i.e., generic and cross-parameter) etc. a ConstraintDefinitionException is raised either at validation time or when the metadata is requested.</text>
        </assertion>
    </section>
    <section id="constraintsdefinitionimplementation-validationimplementation" title="Constraint validation implementation" level="2">
        <!-- 3.4 - CONSTRAINTSDEFINITIONIMPLEMENTATION_VALIDATIONIMPLEMENTATION -->
        <assertion id="a">
            <text>A constraint validation implementation performs the validation of a given constraint annotation for a given type.</text>
        </assertion>
        <assertion id="b">
            <text>The implementation classes are specified by the validatedBy element of the @Constraint annotation that decorates the constraint definition.</text>
        </assertion>
        <assertion id="c" testable="false">
            <text>The constraint validation implementation implements the ConstraintValidator interface.</text>
        </assertion>
        <assertion id="d" testable="false">
            <text>Some restrictions apply on the generic type T (used in the isValid() method). T must resolve to a non parameterized type (i.e. because the type is not using generics or because the raw type is used instead of the generic version) or generic parameters of T must be unbounded wildcard types (i.e. &lt;?&gt;).</text>
        </assertion>
        <assertion id="e">
            <text>By default, a ConstraintValidator targets the (returned) element annotated by the constraint. You can make a ConstraintValidator target the array of parameters of a method or constructor (aka cross-parameter) by annotating the validator implementation with @SupportedValidationTarget.</text>
        </assertion>
        <assertion id="f">
            <text>A ConstraintValidator implementation can target both annotated elements and array of parameters.</text>
        </assertion>
        <assertion id="g">
            <text>If a ConstraintValidator targets array of parameters (cross-parameter), T must resolve to Object[] (or Object) in order to have the array of parameter values passed to the isValid() method. A ConstraintDefinitionException is raised otherwise.</text>
        </assertion>
        <assertion id="h">
            <text>The initialize() method is called by the Jakarta Bean Validation provider prior to any use of the constraint implementation.</text>
        </assertion>
        <assertion id="i">
            <text>As of Jakarta Bean Validation 2.0, initialize() has an empty default implementation, allowing to omit the implementation from validators that don't need to access any constraint attributes.</text>
        </assertion>
        <assertion id="j">
            <text>The isValid() method is evaluated by the Jakarta Bean Validation provider each time a given value is validated.</text>
        </assertion>
        <assertion id="k" testable="false">
            <text>It returns false if the value is not valid, true otherwise.</text>
        </assertion>
        <assertion id="l" testable="false">
            <text>isValid() implementations must be thread-safe.</text>
        </assertion>
        <assertion id="m">
            <text>If the property is of an unanticipated type, an UnexpectedTypeException is raised.</text>
        </assertion>
        <assertion id="n">
            <text>If an exception occurs either in the initialize() or isValid() method, the runtime exception is wrapped into a ValidationException by the Jakarta Bean Validation engine.</text>
        </assertion>
        <assertion id="o" testable="false">
            <text>The constraint validation implementation is not allowed to change the state of the value passed to isValid().</text>
        </assertion>
        <assertion id="p">
            <text>By default, each invalid constraint leads to the generation of one error object represented by a ConstraintViolation object. This object is built from the default constraint message template as defined by the constraint declaration and the context in which the constraint declaration is placed (bean, property, executable parameter, cross-parameter, executable return value or container element).</text>
        </assertion>
        <assertion id="q">
            <text>The ConstraintValidatorContext methods let the constraint implementation disable the default ConstraintViolation generation and create one or more custom ones.</text>
        </assertion>
        <assertion id="r">
            <text>The non-interpolated message passed as a parameter is used to build the ConstraintViolation message (the message interpolation operation is applied to it).</text>
        </assertion>
        <assertion id="s">
            <text>By default, the Path exposed on the ConstraintViolation represents the path to the bean, property, parameter, cross-parameter, return value or container element hosting the constraint (see 6.2 for more information).</text>
        </assertion>
        <assertion id="t">
            <text>You can point it to a subpath of this default path by using the constraint violation builder fluent API.</text>
        </assertion>
        <assertion id="u">
            <text>If disableDefaultConstraintViolation() is called, no custom error is added (using the error builder) and if the constraint is not valid, a ValidationException is raised.</text>
        </assertion>
    </section>
    <section id="constraintsdefinitionimplementation-validationimplementation-temporalvalidators" title="Implementation of temporal constraint validators" level="3">
        <!-- 3.4.1 - CONSTRAINTSDEFINITIONIMPLEMENTATION_VALIDATIONIMPLEMENTATION_TEMPORALVALIDATORS -->
        <assertion id="a">
            <text>Constraint validators for temporal constraints (either the built-in constraints @Past, @PastOrPresent, @Future and @FutureOrPresent or custom temporal constraints) can obtain the current instant from the ClockProvider object exposed by ConstraintValidatorContext#getClockProvider().</text>
        </assertion>
        <assertion id="b">
            <text>The getClock() method returns a java.time.Clock object which represents the current instant, date and time using a time zone. A conforming Jakarta Bean Validation implementation provides a default clock provider which returns a clock representing the current system time and default time zone.</text>
        </assertion>
    </section>
    <section id="constraintsdefinitionimplementation-validationimplementation-example" title="Examples" level="3">
        <!-- 3.4.2 - CONSTRAINTSDEFINITIONIMPLEMENTATION_VALIDATIONIMPLEMENTATION_EXAMPLE -->
    </section>
    <section id="constraintsdefinitionimplementation-constraintfactory" title="The ConstraintValidatorFactory" level="2">
        <!-- 3.5 - CONSTRAINTSDEFINITIONIMPLEMENTATION_CONSTRAINTFACTORY -->
        <assertion id="a" testable="false">
            <text>Jakarta Bean Validation providers must release each instance retrieved. The ConstraintValidatorFactory instance that has created a ConstraintValidator instance must be the one that releases it. In other words, passing an instance of ConstraintValidator to a ConstraintValidatorFactory that has not created it is an error.</text>
        </assertion>
        <assertion id="b">
            <text>The default ConstraintValidatorFactory provided by the Jakarta Bean Validation provider implementation uses the public no-arg constructor of the ConstraintValidator class.</text>
        </assertion>
        <assertion id="c">
            <text>If an exception occurs in the factory while retrieving the ConstraintValidator instance, the runtime exception is wrapped in a ValidationException.</text>
        </assertion>
        <assertion id="d">
            <text>If the instance returned by the factory is null, a ValidationException is raised.</text>
        </assertion>
    </section>
    <section id="valueextractordefinition" title="Value extractor definition" level="1">
        <!-- 4 - VALUEEXTRACTORDEFINITION -->
        <assertion id="a">
            <text>The validation engine passes the container instance and a value receiver object to the extractValues() method.</text>
        </assertion>
        <assertion id="b">
            <text>The value extractor is only invoked if the container is not null.</text>
        </assertion>
        <assertion id="c">
            <text>Value(), the given value will be passed to the validation engine</text>
        </assertion>
        <assertion id="d">
            <text>iterableValue(), the given value will be passed to the validation engine and the corresponding property path node (see 6.2) will be marked as iterable, i.e. Node#isInIterable() returns true</text>
        </assertion>
        <assertion id="e">
            <text>indexedValue(), the given value will be passed to the validation engine and the corresponding property path node will be marked as iterable and it will have set the given index, i.e. Node#getIndex() returns the given index value</text>
        </assertion>
        <assertion id="f">
            <text>keyedValue(), the given value will be passed to the validation engine and the corresponding property path node will be marked as iterable and it will have set the given key, i.e. Node#getKey() returns the given key value</text>
        </assertion>
        <assertion id="g">
            <text>When passing a non-null node name to any of the receiver methods, this node name will be used when adding a node of kind CONTAINER_ELEMENT to the property path (see 6.2 for the property path construction rules).</text>
        </assertion>
        <assertion id="h">
            <text>If null is passed as node name, no node will be appended to the property path. The resulting property path will then be the same as if the constraint had been given on the container instead of a container element. That is desirable for single-element wrapper types such as Optional, OptionalInt etc.</text>
        </assertion>
        <assertion id="i">
            <text>If an exception occurs during invocation of the extractValues() method, this exception is wrapped into a ValidationException by the Jakarta Bean Validation engine.</text>
        </assertion>
        <assertion id="j">
            <text>When validating the @NotNull constraint, the map as returned by the getter will be passed to the map key extractor in order to obtain the map keys.</text>
        </assertion>
        <assertion id="k">
            <text>When validating the @RetailOrder constraint and performing cascaded validation, the map as obtained directly from the field will be passed to the map value extractor in order to obtain the map values.</text>
        </assertion>
    </section>
    <section id="valueextractordefinition-extractedvalue" title="@ExtractedValue" level="2">
        <!-- 4.1 - VALUEEXTRACTORDEFINITION_EXTRACTEDVALUE -->
        <assertion id="a">
            <text>The @ExtractedValue annotation is used to denote the element extracted by a given value extractor</text>
        </assertion>
        <assertion id="b">
            <text>The @ExtractedValue annotation must be specified exactly once for a value extractor type.</text>
        </assertion>
        <assertion id="c">
            <text>For generic container types (e.g. java.util.List), @ExtractedValue is to be specified on a type argument of the container type as used in the extractor definition.</text>
        </assertion>
        <assertion id="d" testable="false">
            <text>Only unbounded wildcard type arguments are supported as target for @ExtractedValue in this case.</text>
        </assertion>
        <assertion id="e">
            <text>For non-generic container types (e.g. java.util.OptionalInt), @ExtractedValue is to be specified on the container type as used in the extractor definition. The type of the wrapped element(s) must be specified using @ExtractedValue#type() in this case.</text>
        </assertion>
        <assertion id="f">
            <text>In case an illegal value extractor definition is detected, a ValueExtractorDefinitionException is raised.</text>
        </assertion>
    </section>
    <section id="valueextractordefinition-unwrapbydefault" title="@UnwrapByDefault" level="2">
        <!-- 4.2 - VALUEEXTRACTORDEFINITION_UNWRAPBYDEFAULT -->
        <assertion id="a">
            <text>This causes constraints to be automatically applied to the wrapped value(s) if a constraint is found for an element of a type handled by that extractor</text>
        </assertion>
    </section>
    <section id="valueextractordefinition-builtinvalueextractors" title="Built-in value extractors" level="2">
        <!-- 4.3 - VALUEEXTRACTORDEFINITION_BUILTINVALUEEXTRACTORS -->
        <assertion id="a">
            <text>java.util.Iterable; iterableValue() must be invoked for each contained element, passing the string literal &lt;iterable element&gt; as node name</text>
        </assertion>
        <assertion id="b">
            <text>java.util.List; indexedValue() must be invoked for each contained element, passing the string literal &lt;list element&gt; as node name</text>
        </assertion>
        <assertion id="c">
            <text>java.util.Map; both map keys and map values are to be supported; keyedValue() must be invoked by the map key extractor for each contained key, passing the string literal &lt;map key&gt; as node name; keyedValue() must be invoked by the map value extractor for each contained value, passing the string literal &lt;map value&gt; as node name</text>
        </assertion>
        <assertion id="d">
            <text>java.util.Optional; value() must be invoked, passing null as node name and passing the contained object as value or null if none is present</text>
        </assertion>
        <assertion id="e">
            <text>java.util.OptionalInt, java.util.OptionalLong and java.util.OptionalDouble; the extracted value types must be java.lang.Integer, java.lang.Long and java.lang.Double, respectively. value() must be invoked, passing null as node name and passing the contained number as value or null if none is present. The extractors must be marked with @UnwrapByDefault.</text>
        </assertion>
        <assertion id="f">
            <text>javafx.beans.observable.ObservableValue; value() must be invoked with the observable value, passing null as node name; the extractor must be marked with @UnwrapByDefault</text>
        </assertion>
        <assertion id="g">
            <text>javafx.beans.property.ReadOnlyListProperty and javafx.beans.property.ListProperty; indexedValue() must be invoked for each contained element, passing the string literal &lt;list element&gt; as node name</text>
        </assertion>
        <assertion id="h">
            <text>javafx.beans.property.ReadOnlySetProperty and javafx.beans.property.SetProperty; iterableValue() must be invoked for each contained element, passing the string literal &lt;iterable element&gt; as node name</text>
        </assertion>
        <assertion id="i">
            <text>javafx.beans.property.ReadOnlyMapProperty and javafx.beans.property.MapProperty; both map keys and map values are to be supported; keyedValue() must be invoked by the map key extractor for each contained key, passing the string literal &lt;map key&gt; as node name; keyedValue() must be invoked by the map value extractor for each contained value, passing the string literal &lt;map value&gt; as node name</text>
        </assertion>
    </section>
    <section id="valueextractordefinition-examples" title="Examples" level="2">
        <!-- 4.4 - VALUEEXTRACTORDEFINITION_EXAMPLES -->
        <assertion id="a">
            <text>The following extractor definition is illegal as it specifies @ExtractedValue more than once</text>
        </assertion>
        <assertion id="b" testable="false">
            <text>The following extractor definition is unsupported as it specifies @ExtractedValue on a non-wildcard type argument</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess" title="Constraint declaration and validation process" level="1">
        <!-- 5 - CONSTRAINTDECLARATIONVALIDATIONPROCESS -->
    </section>
    <section id="constraintdeclarationvalidationprocess-requirements" title="Requirements on classes to be validated" level="2">
        <!-- 5.1 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_REQUIREMENTS -->
        <assertion id="a">
            <text>Properties to be validated must follow the method signature conventions for JavaBeans read properties, as defined by the JavaBeans specification. These properties are commonly referred as getters.</text>
        </assertion>
        <assertion id="b" testable="false">
            <text>Static fields and static methods are excluded from validation.</text>
        </assertion>
        <assertion id="c">
            <text>Constraints can be applied to interfaces and superclasses.</text>
        </assertion>
        <assertion id="d">
            <text>The JavaBeans specification specifies that a getter is a method whose name starts with get and has a return type but no parameter name starts with is, has no parameter and is returning boolean</text>
        </assertion>
        <assertion id="e">
            <text>The target of an annotation definition can be a type field or property constructor or method return value constructor or method parameter constructor or method cross-parameter container element provided that: the constraint definition supports the specified target (java.lang.annotation.Target) one of the ConstraintValidators declared on the constraint supports the declared type of the target or in the case of cross-parameter, one cross-parameter ConstraintValidator is present (see 5.7.4 to learn about ConstraintValidator resolution) in the case of container element constraints, a corresponding value extractor exists (see 5.7.5 for the details of value extractor resolution)</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-requirements-objectvalidation" title="Object validation" level="3">
        <!-- 5.1.1 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_REQUIREMENTS_OBJECTVALIDATION -->
        <assertion id="a">
            <text>Constraint declarations can be applied to a class or an interface.</text>
        </assertion>
        <assertion id="b">
            <text>Applying a constraint to a class or interface expresses a validation over the state of the class or the class implementing the interface.</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-requirements-propertyvalidation" title="Field and property validation" level="3">
        <!-- 5.1.2 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_REQUIREMENTS_PROPERTYVALIDATION -->
        <assertion id="a">
            <text>Constraint declarations can be applied on both fields and properties for the same object type.</text>
        </assertion>
        <assertion id="b">
            <text>The same constraint should however not be duplicated between a field and its associated property (the constraint validation would be applied twice).</text>
        </assertion>
        <assertion id="c">
            <text>When a field is annotated with a constraint declaration, field access strategy is used to access the state validated by such constraint.</text>
        </assertion>
        <assertion id="d">
            <text>When a property is annotated with a constraint declaration, property access strategy is used to access the state validated by such constraint.</text>
        </assertion>
        <assertion id="e">
            <text>The fields or methods visibility are not constrained.</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-requirements-graphvalidation" title="Graph validation" level="3">
        <!-- 5.1.3 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_REQUIREMENTS_GRAPHVALIDATION -->
        <assertion id="a">
            <text>Consider the situation where bean X contains a field of type Y. By annotating field Y with the @Valid annotation, the Validator will validate Y (and its properties) when X is validated.</text>
        </assertion>
        <assertion id="b">
            <text>The exact type Z of the value contained in the field declared of type Y (subclass, implementation) is determined at runtime. The constraint definitions of Z are used.</text>
        </assertion>
        <assertion id="c">
            <text>Any object implementing java.lang.Iterable is supported.</text>
        </assertion>
        <assertion id="d">
            <text>Arrays of objects</text>
        </assertion>
        <assertion id="e">
            <text>java.util.Collection</text>
        </assertion>
        <assertion id="f">
            <text>java.util.Set</text>
        </assertion>
        <assertion id="g">
            <text>java.util.List</text>
        </assertion>
        <assertion id="h">
            <text>java.util.Map</text>
        </assertion>
        <assertion id="i">
            <text>Each object provided by the iterator is validated.</text>
        </assertion>
        <assertion id="j">
            <text>For Map, the value (retrieved by getValue) of each Map.Entry is validated (the key is not validated).</text>
        </assertion>
        <assertion id="k">
            <text>Like regular references, its type is determined at runtime and the constraint definitions for this particular type are used.</text>
        </assertion>
        <assertion id="l">
            <text>As of Jakarta Bean Validation 2.0, @Valid can be applied to the elements of any generic container by putting it to the type argument(s) when using such container (e.g. MultiMap&lt;String, @Valid Address&gt; addressesByType), provided a value extractor implementation (see 4) for that container type and the targeted type argument is present.</text>
        </assertion>
        <assertion id="m">
            <text>@Valid also allows the validation of the elements of nested generic containers. @Valid must be put to a type argument of that nested container type in order to trigger validation of the elements of all the nested containers.</text>
        </assertion>
        <assertion id="n">
            <text>The @Valid annotation is applied recursively.</text>
        </assertion>
        <assertion id="o" testable="false">
            <text>It is not supported to put @Valid to the type parameters of generic types or methods.</text>
        </assertion>
        <assertion id="p" testable="false">
            <text>It is also not supported to put @Valid to type arguments within the extends or implements clauses of type definitions.</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-requirements-graphvalidation-examples" title="Examples" level="4">
        <!-- 5.1.3.1 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_REQUIREMENTS_GRAPHVALIDATION_EXAMPLES -->
    </section>
    <section id="constraintdeclarationvalidationprocess-constraintdeclaration" title="Constraint declaration" level="2">
        <!-- 5.2 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_CONSTRAINTDECLARATION -->
        <assertion id="a">
            <text>When a constraint is defined on a class, the class instance being validated is passed to the ConstraintValidator. When a constraint is defined on a field, the value of the field is passed to the ConstraintValidator. When a constraint is defined on a getter, the result of the getter invocation is passed to the ConstraintValidator.</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-inheritance" title="Inheritance (interface and superclass)" level="2">
        <!-- 5.3 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_INHERITANCE -->
        <assertion id="a">
            <text>A constraint declaration can be placed on an interface.</text>
        </assertion>
        <assertion id="b">
            <text>For a given class, constraint declarations held on superclasses as well as interfaces are evaluated by the Jakarta Bean Validation provider.</text>
        </assertion>
        <assertion id="c">
            <text>The effect of constraint declarations is cumulative. Constraints declared on a superclass getter will be validated along with any constraints defined on an overridden version of the getter according to the Java Language Specification visibility rules.</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-groupsequence" title="Group and group sequence" level="2">
        <!-- 5.4 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_GROUPSEQUENCE -->
        <assertion id="a">
            <text>If no group is explicitly declared, a constraint belongs to the Default group.</text>
        </assertion>
        <assertion id="b">
            <text>Groups are represented by interfaces.</text>
        </assertion>
        <assertion id="c">
            <text>A constraint can belong to one or more groups.</text>
        </assertion>
        <assertion id="d">
            <text>During the validation call, one or more groups are validated. All the constraints belonging to this set of groups is evaluated on the object graph.</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-groupsequence-groupinheritance" title="Group inheritance" level="3">
        <!-- 5.4.1 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_GROUPSEQUENCE_GROUPINHERITANCE -->
        <assertion id="a">
            <text>A group may inherit one or more groups by using interface inheritance.</text>
        </assertion>
        <assertion id="b">
            <text>For a given interface Z, constraints marked as belonging to the group Z (i.e. where the annotation element groups contains the interface Z) or any of the super interfaces of Z (inherited groups) are considered part of the group Z.</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-groupsequence-groupsequence" title="Group sequence" level="3">
        <!-- 5.4.2 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_GROUPSEQUENCE_GROUPSEQUENCE -->
        <assertion id="a" testable="false">
            <text>By default, constraints are evaluated in no particular order regardless of which groups they belong to.</text>
        </assertion>
        <assertion id="b">
            <text>Each group in a group sequence must be processed sequentially in the order defined by @GroupSequence.value when the group defined as a sequence is requested.</text>
        </assertion>
        <assertion id="c">
            <text>Note that a group member of a sequence can itself be composed of several groups via inheritance or sequence definition. In this case, each composed group must respect the sequence order as well.</text>
        </assertion>
        <assertion id="d">
            <text>If one of the groups processed in the sequence generates one or more constraint violations, the groups following in the sequence must not be processed.</text>
        </assertion>
        <assertion id="e">
            <text>Groups defining a sequence and groups composing a sequence must not be involved in a cyclic dependency: either directly or indirectly either through cascaded sequence definitions or group inheritance</text>
        </assertion>
        <assertion id="f">
            <text>If a group containing such a circularity is evaluated, a GroupDefinitionException is raised.</text>
        </assertion>
        <assertion id="g" testable="false">
            <text>Groups defining a sequence should not directly inherit other groups. In other words, the interface hosting the group sequence should not have any super interface.</text>
        </assertion>
        <assertion id="h" testable="false">
            <text>Groups defining a sequence should not be used directly in constraint declarations.</text>
        </assertion>
        <assertion id="i">
            <text>To define a group as a sequence, the interface must be annotated with the @GroupSequence annotation.</text>
        </assertion>
        <assertion id="j">
            <text>A given constraint can belong to two or more groups ordered by a sequence. In this case, the constraint is evaluated as part of the first group and ignored in the subsequent group(s).</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-groupsequence-redefiningdefaultgroup" title="Redefining the Default group for a class" level="3">
        <!-- 5.4.3 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_GROUPSEQUENCE_REDEFININGDEFAULTGROUP -->
        <assertion id="a">
            <text>To redefine Default for a class, place a @GroupSequence annotation on the class; this sequence expresses the sequence of groups that does substitute Default for this class.</text>
        </assertion>
        <assertion id="b" testable="false">
            <text>Constraints hosted on a class A and belonging to the Default group (by default or explicitly) implicitly belong to the group A.</text>
        </assertion>
        <assertion id="c">
            <text>A sequence defined on a class A (i.e. redefining the Default groups for the class) must contain the group A.</text>
        </assertion>
        <assertion id="d">
            <text>If a @GroupSequence redefining the Default group for a class A does not contain the group A, a GroupDefinitionException is raised when the class is validated or when its metadata is requested.</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-groupsequence-implicitgrouping" title="Implicit grouping" level="3">
        <!-- 5.4.4 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_GROUPSEQUENCE_IMPLICITGROUPING -->
        <assertion id="a">
            <text>Every constraint hosted on an interface Z and part of the Default group (implicitly or explicitly) belongs to the group Z.</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-groupsequence-groupconversion" title="Group conversion" level="3">
        <!-- 5.4.5 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_GROUPSEQUENCE_GROUPCONVERSION -->
        <assertion id="a">
            <text>@ConvertGroup and @ConvertGroup.List can be used everywhere @Valid can be used (associations, method/constructor parameters and return value). If these annotations are used without @Valid, a ConstraintDeclarationException is raised.</text>
        </assertion>
        <assertion id="b">
            <text>Groups are passed as is to the nested elements unless the @ConvertGroup annotation is used.</text>
        </assertion>
        <assertion id="c">
            <text>If the group expected to be passed to the nested element validation is defined as the from attribute of a @ConvertGroup annotation, the group used to effectively validate the nested element is the corresponding group defined in the to attribute.</text>
        </assertion>
        <assertion id="d">
            <text>If no value for the from attribute is specified, Default.class will be used as the source group of the conversion.</text>
        </assertion>
        <assertion id="e">
            <text>Rules are not executed recursively.</text>
        </assertion>
        <assertion id="f">
            <text>It is not legal to have more than one conversion rule containing the same from value. In this case, a ConstraintDeclarationException is raised.</text>
        </assertion>
        <assertion id="g">
            <text>Like regular constraint declarations, the from attribute cannot refer to a group sequence. A ConstraintDeclarationException is raised in this situation.</text>
        </assertion>
        <assertion id="h">
            <text>The to attribute can. The group sequence will then be expanded before validating the associated object.</text>
        </assertion>
        <assertion id="i">
            <text>@ConvertGroup and @ConvertGroup.List can only be placed where @Valid is present to ensure proper respect of the Liskov substitution principle</text>
        </assertion>
        <assertion id="j">
            <text>Likewise, if a sub type overrides/implements a method originally defined in several parallel types of the hierarchy (e.g. two interfaces not extending each other, or a class and an interface not implemented by said class) and if that method's return value has been marked for cascading validation in one of the parallel types, no group conversion rule may be declared for that method's return value in the parallel types of the hierarchy.</text>
        </assertion>
        <assertion id="k">
            <text>If any of these rules is violated, a ConstraintDeclarationException is raised by default as defined in 5.6.5.</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-groupsequence-groupconversion-examples" title="Group conversion examples" level="4">
        <!-- 5.4.5.1 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_GROUPSEQUENCE_GROUPCONVERSION_EXAMPLES -->
        <assertion id="a">
            <text>Group conversions can also be applied during container element validation</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-groupsequence-formaldefinition" title="Formal group definitions" level="3">
        <!-- 5.4.6 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_GROUPSEQUENCE_FORMALDEFINITION -->
        <assertion id="a">
            <text>The group X contains the following constraints: every constraint declared by the class X which does not declare a group or does declare the group Default explicitly. every constraint declared by any interface implemented by X and not annotated @GroupSequence which does not explicitly declare a group or does declare the group Default explicitly. if X has a direct superclass Y, every constraint in the group Y</text>
        </assertion>
        <assertion id="b">
            <text>If X has no @GroupSequence annotation, the group Default contains the following constraints: every constraint in the group X if X has a direct superclass Y, every constraint in the group Default of Y</text>
        </assertion>
        <assertion id="c">
            <text>If X does have a @GroupSequence annotation, the group Default contains every constraint belonging to every group declared by the @GroupSequence annotation.</text>
        </assertion>
        <assertion id="d">
            <text>The @GroupSequence annotation must declare the group X</text>
        </assertion>
        <assertion id="e">
            <text>For every interface Z, the group Z contains the following constraints: every constraint declared by the interface Z which does not explicitly declare a group or does declare the group Default explicitly. every constraint (which does not explicitly declare a group) declared by any superinterface not annotated @GroupSequence of the interface Z every constraint declared by the class X which explicitly declares the group Z every constraint declared by any interface implemented by X and not annotated @GroupSequence which explicitly declares the group Z if X has a direct superclass Y, every constraint in the group Z of Y</text>
        </assertion>
        <assertion id="f">
            <text>For every interface Z annotated @GroupSequence, the group Z contains every constraint belonging to every group declared by the @GroupSequence annotation.</text>
        </assertion>
        <assertion id="g">
            <text>When a given group G (represented by an interface G) is requested for the validation of a class X: constraints belonging to the group G are evaluated if the interface G is not annotated @GroupSequence, every group represented by the super interface of G are requested for validation if the interface G is annotated with @GroupSequence, every group represented by the interfaces declared by the @GroupSequence annotation are requested for validation the validation of groups declared to the @GroupSequence must happen in the sequencing order declared by @GroupSequence: the sequencing order is propagated to the groups composing the sequenced group (via inheritance or group sequence) if a group validation triggers the failure of one or more constraints, groups following in the sequence must not be evaluated. if the group G represents the Default group of X overridden by @GroupSequence, operations are equivalent</text>
        </assertion>
        <assertion id="h">
            <text>When the Default group of a given class X is overridden via @GroupSequence, its validation is as followed: every group represented by the interfaces declared by the @GroupSequence annotation are requested for validation the validation of groups declared to the @GroupSequence must happen in the sequencing order declared by @GroupSequence: the sequencing order is propagated to the groups composing the sequenced group (via inheritance or group sequence) if a group validation triggers the failure of one or more constraints, groups following in the sequence must not be evaluated.</text>
        </assertion>
        <assertion id="i" testable="false">
            <text>Unless defined by a @GroupSequence, evaluation ordering is not constrained. In particular, several groups can be validated in the same pass.</text>
        </assertion>
        <assertion id="j">
            <text>If a group definition leads to a circular sequencing order between groups, a GroupDefinitionException is raised.</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-containerelementconstraints" title="Container element constraints" level="2">
        <!-- 5.5 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_CONTAINERELEMENTCONSTRAINTS -->
        <assertion id="a">
            <text>Constraints can be applied to the elements of generic containers, e.g. List, Map or Optional. This is done by putting constraint annotations to the type arguments of such containers.</text>
        </assertion>
        <assertion id="b">
            <text>Container element constraints can be used within the following declarations: fields, properties, method or constructor parameters or method return values.</text>
        </assertion>
        <assertion id="c">
            <text>When a field, property, executable parameter or method return value which is of a container type gets validated, then all values contained in the container will be validated provided that their container element type is constrained.</text>
        </assertion>
        <assertion id="d">
            <text>Any container element constraints of that element will be validated alongside any other constraints hosted by that element.</text>
        </assertion>
        <assertion id="e">
            <text>For container element constraints, the same rules for validation groups and group sequences apply as for any other constraint on the same element.</text>
        </assertion>
        <assertion id="f">
            <text>Container element constraints can be applied to nested container types</text>
        </assertion>
        <assertion id="g" testable="false">
            <text>It is not supported to declare container element constraints on the type parameters of generic types or methods.</text>
        </assertion>
        <assertion id="h" testable="false">
            <text>It is also not supported to declare container element constraints on type arguments within the extends or implements clauses of type definitions.</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-containerelementconstraints-implicitunwrapping" title="Implicit unwrapping of containers" level="3">
        <!-- 5.5.1 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_CONTAINERELEMENTCONSTRAINTS_IMPLICITUNWRAPPING -->
        <assertion id="a">
            <text>This is useful for applying a constraint given on a non-generic container to the container element(s) if there is no value extractor marked with @UnwrapByDefault (by using Unwrap) the container itself in case there is a value extractor marked with @UnwrapByDefault (by using Skip)</text>
        </assertion>
        <assertion id="b">
            <text>If both Unwrap and Skip are present in the definition of a payload, a ConstraintDeclarationException is raised.</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-methodlevelconstraints" title="Method and constructor constraints" level="2">
        <!-- 5.6 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_METHODLEVELCONSTRAINTS -->
    </section>
    <section id="constraintdeclarationvalidationprocess-methodlevelconstraints-requirements" title="Requirements on methods to be validated" level="3">
        <!-- 5.6.1 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_METHODLEVELCONSTRAINTS_REQUIREMENTS -->
        <assertion id="a" testable="false">
            <text>Static methods are ignored by validation. Putting constraints on a static method is not portable.</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-methodlevelconstraints-parameterconstraints" title="Declaring parameter constraints" level="3">
        <!-- 5.6.2 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_METHODLEVELCONSTRAINTS_PARAMETERCONSTRAINTS -->
        <assertion id="a">
            <text>Parameter constraints are declared by putting constraint annotations on method or constructor parameters.</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-methodlevelconstraints-parameterconstraints-crossparameterconstraints" title="Cross-parameter constraints" level="4">
        <!-- 5.6.2.1 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_METHODLEVELCONSTRAINTS_PARAMETERCONSTRAINTS_CROSSPARAMETERCONSTRAINTS -->
        <assertion id="a">
            <text>Cross-parameter constraints are declared by putting cross-parameter constraint annotations on methods or constructors</text>
        </assertion>
        <assertion id="b">
            <text>It is not legal to declare a cross-parameter constraint on a method or constructor which has no parameters. A ConstraintDeclarationException is raised in this case.</text>
        </assertion>
        <assertion id="c">
            <text>They are known to be both generic and cross-parameter constraints. When using such a constraint on an executable to target the parameters, one must set validationAppliesTo if there is an ambiguity.</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-methodlevelconstraints-parameterconstraints-namingparameters" title="Naming parameters" level="4">
        <!-- 5.6.2.2 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_METHODLEVELCONSTRAINTS_PARAMETERCONSTRAINTS_NAMINGPARAMETERS -->
        <assertion id="a">
            <text>A conforming Jakarta Bean Validation implementation provides a default ParameterNameProvider implementation which returns parameter names as stored in the class file containing the validated executable, if present. A conforming implementation must either use the Java reflection API or ensure behavioral compatibility to using the reflection API in the following way: Obtain the method's or constructor's parameters via java.lang.reflect.Executable.getParameters() Obtain each parameter's name via java.lang.reflect.Parameter.getName()</text>
        </assertion>
        <assertion id="b">
            <text>If an exception occurs during invocation of the getParameterNames() methods, this exception is wrapped into a ValidationException by the Jakarta Bean Validation engine.</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-methodlevelconstraints-returnvalueconstraints" title="Declaring return value constraints" level="3">
        <!-- 5.6.3 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_METHODLEVELCONSTRAINTS_RETURNVALUECONSTRAINTS -->
        <assertion id="a">
            <text>Return value constraints are declared by putting constraint annotations directly on a method or constructor.</text>
        </assertion>
        <assertion id="b">
            <text>They are known to be both generic and cross-parameter constraints. When using such constraint on an executable to target the return value, one must set validationAppliesTo in case there is an ambiguity.</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-methodlevelconstraints-cascadedvalidation" title="Marking parameters and return values for cascaded validation" level="3">
        <!-- 5.6.4 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_METHODLEVELCONSTRAINTS_CASCADEDVALIDATION -->
        <assertion id="a">
            <text>The @Valid annotation is used to declare that a cascaded validation of the given method/constructor parameters or return values is performed by the Jakarta Bean Validation provider. When marked, the parameter or return value is considered a bean object to validate.</text>
        </assertion>
        <assertion id="b">
            <text>Null arguments and null return values are ignored</text>
        </assertion>
        <assertion id="c">
            <text>The validation is recursive; that is, if validated parameter or return value objects have references marked with @Valid themselves, these references will also be validated</text>
        </assertion>
        <assertion id="d" testable="false">
            <text>Jakarta Bean Validation providers must guarantee the prevention of infinite loops during cascaded validation</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-methodlevelconstraints-inheritance" title="Method constraints in inheritance hierarchies" level="3">
        <!-- 5.6.5 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_METHODLEVELCONSTRAINTS_INHERITANCE -->
        <assertion id="a">
            <text>In sub types (be it sub classes/interfaces or interface implementations), no parameter constraints may be declared on overridden or implemented methods, nor may parameters be marked for cascaded validation. This would pose a strengthening of preconditions to be fulfilled by the caller.</text>
        </assertion>
        <assertion id="b">
            <text>If a sub type overrides/implements a method originally defined in several parallel types of the hierarchy (e.g. two interfaces not extending each other, or a class and an interface not implemented by said class), no parameter constraints may be declared for that method at all nor parameters be marked for cascaded validation. This again is to avoid an unexpected strengthening of preconditions to be fulfilled by the caller.</text>
        </assertion>
        <assertion id="c">
            <text>In sub types (be it sub classes/interfaces or interface implementations), return value constraints may be declared on overridden or implemented methods and the return value may be marked for cascaded validation. Upon validation, all return value constraints of the method in question are validated, wherever they are declared in the hierarchy. This only poses possibly a strengthening but no weakening of the method's postconditions guaranteed to the caller.</text>
        </assertion>
        <assertion id="d">
            <text>One must not mark a method return value for cascaded validation more than once in a line of a class hierarchy. In other words, overriding methods on sub types (be it sub classes/interfaces or interface implementations) cannot mark the return value for cascaded validation if the return value has already been marked on the overridden method of the super type or interface.</text>
        </assertion>
        <assertion id="e">
            <text>Out of the box, a conforming Jakarta Bean Validation provider must throw a ConstraintDeclarationException when discovering that any of these rules are violated.</text>
        </assertion>
        <assertion id="f">
            <text>The above rules do not apply when validating constructor constraints as constructors do not override one another. Parameter and return value constraints can be applied to any constructor in the type hierarchy, but only the constraints defined directly on the validated constructor are evaluated.</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-methodlevelconstraints-inheritance-examples" title="Examples" level="4">
        <!-- 5.6.5.1 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_METHODLEVELCONSTRAINTS_INHERITANCE_EXAMPLES -->
    </section>
    <section id="constraintdeclarationvalidationprocess-validationroutine" title="Validation routine" level="2">
        <!-- 5.7 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_VALIDATIONROUTINE -->
        <assertion id="a">
            <text>For a given group, the validation routine applied on a given bean instance is expected to execute the following constraint validations in no particular order: for all reachable fields, execute all field level validations (including the ones expressed on superclasses) matching the targeted group unless the given validation constraint has already been processed during this validation routine for a given navigation path (see 5.7.1) as part of a previous group match. for all reachable getters, execute all getter level validations (including the ones expressed on interfaces and superclasses) matching the targeted group unless the given validation constraint has already been processed during this validation routine for a given navigation path (see 5.7.1) as part of a previous group match. execute all class level validations (including the ones expressed on interfaces and superclasses) matching the targeted group unless the given validation constraint has already been processed during this validation routine for a given navigation path (see 5.7.1) as part of a previous group match. for all reachable and cascadable associations, execute all cascading validations (see 5.7.1) including the ones expressed on interfaces and superclasses (see 5.4.6). Note that group conversion can apply (see 5.4.5).</text>
        </assertion>
        <assertion id="b" testable="false">
            <text>Unless ordered by group sequences, groups can be validated in no particular order.</text>
        </assertion>
        <assertion id="c">
            <text>The object validation routine is described as such. For each constraint declaration: determine for the constraint declaration, the appropriate ConstraintValidator to use (see 5.7.4). execute the isValid operation (from the constraint validation implementation) on the appropriate data (see 3.4) if isValid() returns true, continue to the next constraint, if isValid() returns false, the Jakarta Bean Validation provider populates ConstraintViolation object(s) according to the rules defined in 3.4 and appends these objects to the list of constraint violations.</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-validationroutine-graphvalidation" title="Object graph validation" level="3">
        <!-- 5.7.1 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_VALIDATIONROUTINE_GRAPHVALIDATION -->
        <assertion id="a">
            <text>The @Valid annotation on a given association (i.e. object reference or collection, array, Iterable of objects), dictates the Jakarta Bean Validation implementation to apply recursively the Jakarta Bean Validation routine on (each of) the associated object(s).</text>
        </assertion>
        <assertion id="b">
            <text>This mechanism is recursive: an associated object can itself contain cascaded references.</text>
        </assertion>
        <assertion id="c">
            <text>Null references are ignored.</text>
        </assertion>
        <assertion id="d">
            <text>To prevent infinite loops, the Jakarta Bean Validation implementation must ignore the cascading operation if the associated object instance has already been validated in the current navigation path (starting from the root object).</text>
        </assertion>
        <assertion id="e">
            <text>@Valid is an orthogonal concept to the notion of group. If two groups are in sequence, the first group must pass for all associated objects before the second group is evaluated.</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-validationroutine-methodconstructorvalidation" title="Method and constructor validation" level="3">
        <!-- 5.7.2 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_VALIDATIONROUTINE_METHODCONSTRUCTORVALIDATION -->
        <assertion id="a">
            <text>For a given group, the validation routine applied to validate parameters of a method or constructor is expected to execute the following constraint validations in no particular order: execute all parameter validations (in case of overriding method validation, including the ones expressed on overridden methods of the interfaces and superclasses) matching the targeted group unless the given validation constraint has already been processed during this validation routine for a given navigation path (see 5.7.1) as part of a previous group match. execute all cross parameter validations (in case of overriding method validation, including the ones expressed on overridden methods of the interfaces and superclasses) matching the targeted group unless the given validation constraint has already been processed during this validation routine for a given navigation path (see 5.7.1) as part of a previous group match. for all parameters marked for cascaded validation, execute all cascading validations (see 5.7.1), in case of overriding method validation including the ones expressed on overridden methods of the interfaces and superclasses (see 5.4.6). Note that group conversion can apply (see 5.4.5).</text>
        </assertion>
        <assertion id="b">
            <text>For a given group, the validation routine applied to validate the return value of a method or constructor is expected to execute the following constraint validations in no particular order: execute all return value validations (including the ones expressed on interfaces and superclasses) matching the targeted group unless the given validation constraint has already been processed during this validation routine for a given navigation path (see 5.7.1) as part of a previous group match. if the return value is marked for cascaded validation, execute all cascading validations (see 5.7.1) including the ones expressed on interfaces and superclasses (see 5.4.6). Note that group conversion can apply (see 5.4.5).</text>
        </assertion>
        <assertion id="c" testable="false">
            <text>Unless ordered by group sequences, groups can be validated in no particular order.</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-validationroutine-traversable" title="Traversable property" level="3">
        <!-- 5.7.3 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_VALIDATIONROUTINE_TRAVERSABLE -->
        <assertion id="a">
            <text>isReachable() is called for every property about to be accessed either for validation or for cascading.</text>
        </assertion>
        <assertion id="b">
            <text>isCascadable() is called for every property about to be cascaded (i.e. marked as @Valid).</text>
        </assertion>
        <assertion id="c">
            <text>isCascadable() for a given property is only called if isReachable() returns true. In other words, isReachable() is always called before isCascadable() for a given property.</text>
        </assertion>
        <assertion id="d">
            <text>traversableObject is the object instance being evaluated. null if the check is triggered as part of a validateValue() call.</text>
        </assertion>
        <assertion id="e">
            <text>traversableProperty is the Node representing the property hosted by the traversableObject being considered for traversal. The name of a property is defined in 5.1.2.</text>
        </assertion>
        <assertion id="f">
            <text>rootBeanType is the class of the root being validated, i.e. either the type of the object passed to the validate method or the type declaring the validated method/constructor in case of method validation.</text>
        </assertion>
        <assertion id="g">
            <text>pathToTraversableObject is the Path from the rootBeanType down to the traversableObject. If the root object is traversableObject, pathToTraversableObject is composed of a single Node whose name is null. The path is described following the conventions described in 6.2 (getPropertyPath).</text>
        </assertion>
        <assertion id="h">
            <text>elementType is the java.lang.annotation.ElementType the annotation is placed on. It can be either FIELD or METHOD. Any other value is not expected.</text>
        </assertion>
        <assertion id="i">
            <text>The Jakarta 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.</text>
        </assertion>
        <assertion id="j">
            <text>If an exception occurs when the TraversableResolver is called, the exception is wrapped into a ValidationException.</text>
        </assertion>
        <assertion id="k">
            <text>The following elements are not passed through the traversable resolver filter: the bean instance validated the method and constructor parameter values being validated the method and constructor return value being validated</text>
        </assertion>
        <assertion id="l">
            <text>But the properties of these elements (if validated) are. In this case the complete path is provided via pathToTraversableObject.</text>
        </assertion>
        <assertion id="m" testable="false">
            <text>If Jakarta Persistence is available in the runtime environment, a property is considered reachable if Jakarta Persistence considers the property as loaded.</text>
        </assertion>
        <assertion id="n" testable="false">
            <text>If Jakarta Persistence is not available in the runtime environment, all properties are considered reachable.</text>
        </assertion>
        <assertion id="o" testable="false">
            <text>All properties are considered cascadable.</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-validationroutine-traversable-examples" title="Examples" level="4">
        <!-- 5.7.3.1 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_VALIDATIONROUTINE_TRAVERSABLE_EXAMPLES -->
    </section>
    <section id="constraintdeclarationvalidationprocess-validationroutine-typevalidatorresolution" title="ConstraintValidator resolution algorithm" level="3">
        <!-- 5.7.4 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_VALIDATIONROUTINE_TYPEVALIDATORRESOLUTION -->
        <assertion id="a">
            <text>The list of ConstraintValidators can contain at most one which targets cross-parameter. If the constraint targets the parameters of an executable either implicitly or by the use of validationAppliesTo in the constraint - see 3.1.1.4, then the cross-parameter ConstraintValidator is used. If none is present, a ConstraintDefinitionException is raised. If more than one cross-parameter ConstraintValidator is present, a ConstraintDefinitionException is raised.</text>
        </assertion>
        <assertion id="b">
            <text>If the constraint declaration is hosted on a class or an interface, the targeted type is the class or the interface.</text>
        </assertion>
        <assertion id="c">
            <text>If the constraint is hosted on a class attribute, the type of the attribute is the targeted type.</text>
        </assertion>
        <assertion id="d">
            <text>If the constraint is hosted on a method (getter or non-getter) or constructor, the return type is the targeted type.</text>
        </assertion>
        <assertion id="e">
            <text>If the constraint is hosted on a method or constructor parameter, the parameter type is the targeted type.</text>
        </assertion>
        <assertion id="f">
            <text>If the constraint is hosted on a type argument of a parameterized type (i.e. a container element constraint, see 5.5), the type argument's type is the targeted type.</text>
        </assertion>
        <assertion id="g">
            <text>If the constraint is subject to implicit unwrapping (see 5.5.1) and the applicable value extractor is defined for a generic type (e.g. javafx.beans.value.ObservableValue), the targeted type is the type captured for the type parameter handled by the value extractor (e.g. String if the constraint is placed on a StringProperty).</text>
        </assertion>
        <assertion id="h">
            <text>If the constraint is subject to implicit unwrapping and the applicable value extractor is defined for a non-generic type, the targeted type is the type defined by the extractor via @ExtractedValue#type() (e.g. Integer if the constraint is placed on a java.util.OptionalInt).</text>
        </assertion>
        <assertion id="i">
            <text>The ConstraintValidator chosen to validate the generic constraint on a declared type T is the one where the ConstraintValidator targets the annotated element, where the type supported by the ConstraintValidator is a supertype of T and where there is no other ConstraintValidator whose supported type is a supertype of T and not a supertype of the chosen ConstraintValidator supported type.</text>
        </assertion>
        <assertion id="j">
            <text>Only ConstraintValidator implementations targeting annotated elements are considered.</text>
        </assertion>
        <assertion id="k">
            <text>Primitive types are considered equivalent to their respective primitive wrapper class.</text>
        </assertion>
        <assertion id="l">
            <text>If no ConstraintValidator compliant with T is found among the ConstraintValidators listed by the constraint A, an UnexpectedTypeException is raised.</text>
        </assertion>
        <assertion id="m">
            <text>A ConstraintValidator&lt;A, U&gt; compliant with T is considered strictly more specific than a ConstraintValidator&lt;A, V&gt; compliant with T if U is a strict subtype of V. U is a strict subtype of V if U is a subtype of V and U != V (according to the Java Language Specification).</text>
        </assertion>
        <assertion id="n">
            <text>If more than one maximally specific ConstraintValidator is found, an UnexpectedTypeException is raised.</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-validationroutine-valueextractorresolution" title="ValueExtractor resolution" level="3">
        <!-- 5.7.5 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_VALIDATIONROUTINE_VALUEEXTRACTORRESOLUTION -->
    </section>
    <section id="constraintdeclarationvalidationprocess-validationroutine-valueextractorresolution-registering" title="Registering ValueExtractor implementations" level="4">
        <!-- 5.7.5.1 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_VALIDATIONROUTINE_VALUEEXTRACTORRESOLUTION_REGISTERING -->
        <assertion id="a">
            <text>Via the Java service loader mechanism; for this the file META-INF/services/jakarta.validation.valueextraction.ValueExtractor must be provided</text>
        </assertion>
        <assertion id="b">
            <text>By specifying the fully-qualified class name of one or several extractors in META-INF/validation.xml</text>
        </assertion>
        <assertion id="c">
            <text>By invoking the method Configuration#addValueExtractor(ValueExtractor&lt;?&gt;) (to apply it at the validator factory level).</text>
        </assertion>
        <assertion id="d">
            <text>By invoking the method ValidatorContext#addValueExtractor(ValueExtractor&lt;?&gt;) (to apply it for a single Validator instance).</text>
        </assertion>
        <assertion id="e">
            <text>A value extractor for a given type and type parameter specified at a higher priority overrides any other extractors for the same type and type parameter given at lower priorities.</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-validationroutine-valueextractorresolution-algorithm-constraints" title="ValueExtractor resolution algorithm for container element constraints" level="4">
        <!-- 5.7.5.2 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_VALIDATIONROUTINE_VALUEEXTRACTORRESOLUTION_ALGORITHM_CONSTRAINTS -->
        <assertion id="a">
            <text>A ValueExtractor&lt;T&gt; is said to be type-compliant with C, if C is a subtype of T (according to the Java Language Specification, Java SE 8 Edition, chapter 4.10, "Subtyping"). Note that C is a subtype of T if C = T.</text>
        </assertion>
        <assertion id="b">
            <text>A ValueExtractor implementation is said to be container-element-compliant with C, if C is a generic container type and the value extractor implementation handles a type parameter that maps to the constrained type argument.</text>
        </assertion>
        <assertion id="c">
            <text>If no ValueExtractor type-compliant and container-element-compliant with C is found among the available value extractors, a ConstraintDeclarationException is raised.</text>
        </assertion>
        <assertion id="d">
            <text>A ValueExtractor&lt;U&gt; type-compliant with C is considered strictly more specific than a ValueExtractor&lt;V&gt; compliant with C if U is a strict subtype of V.</text>
        </assertion>
        <assertion id="e">
            <text>If more than one maximally specific and container-element-compliant ValueExtractor is found, a ConstraintDeclarationException is raised.</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-validationroutine-valueextractorresolution-algorithm-cascaded" title="ValueExtractor resolution algorithm for cascaded validation" level="4">
        <!-- 5.7.5.3 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_VALIDATIONROUTINE_VALUEEXTRACTORRESOLUTION_ALGORITHM_CASCADED -->
        <assertion id="a">
            <text>A ValueExtractor&lt;T&gt; is said to be type-compliant with C', if C' is a subtype of T.</text>
        </assertion>
        <assertion id="b">
            <text>A ValueExtractor implementation is said to be container-element-compliant with C, if it handles a type parameter that maps to the type argument marked with @Valid.</text>
        </assertion>
        <assertion id="c">
            <text>If no ValueExtractor type-compliant with C' and container-element-compliant with C is found among the available value extractors, a ConstraintDeclarationException is raised.</text>
        </assertion>
        <assertion id="d">
            <text>A ValueExtractor&lt;U&gt; type-compliant with C' is considered strictly more specific than a ValueExtractor&lt;V&gt; compliant with C' if U is a strict subtype of V.</text>
        </assertion>
        <assertion id="e">
            <text>A ValueExtractor&lt;U&gt; type-compliant with C' is considered maximally specific if no other ValueExtractor&lt;V&gt; type-compliant with C' is strictly more specific than ValueExtractor&lt;U&gt;.</text>
        </assertion>
        <assertion id="f">
            <text>If more than one maximally specific and container-element-compliant ValueExtractor is found, a ConstraintDeclarationException is raised.</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-validationroutine-valueextractorresolution-implicitunwrapping" title="ValueExtractor resolution algorithm for applying container-level constraints to container elements" level="4">
        <!-- 5.7.5.4 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_VALIDATIONROUTINE_VALUEEXTRACTORRESOLUTION_IMPLICITUNWRAPPING -->
        <assertion id="a">
            <text>If the constraint carries the Unwrapping.Skip payload, no value extractor is applied.</text>
        </assertion>
        <assertion id="b">
            <text>If the constraint carries the Unwrapping.Unwrap payload and there is exactly one maximally-specific type-compliant value extractor, this extractor is applied;</text>
        </assertion>
        <assertion id="c">
            <text>If no type-compliant extractor or multiple maximally-specific type-compliant extractors exist, a ConstraintDeclarationException is raised.</text>
        </assertion>
        <assertion id="d">
            <text>If there is exactly one maximally-specific type-compliant value extractor and this extractor is marked with @UnwrapByDefault, this extractor is applied;</text>
        </assertion>
        <assertion id="e">
            <text>Otherwise, no value extractor is applied.</text>
        </assertion>
    </section>
    <section id="constraintdeclarationvalidationprocess-validationroutine-algorithm-examples" title="Examples" level="4">
        <!-- 5.7.5.5 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_VALIDATIONROUTINE_ALGORITHM_EXAMPLES -->
    </section>
    <section id="constraintdeclarationvalidationprocess-examples" title="Examples" level="2">
        <!-- 5.8 - CONSTRAINTDECLARATIONVALIDATIONPROCESS_EXAMPLES -->
    </section>
    <section id="validationapi" title="Validation APIs" level="1">
        <!-- 6 - VALIDATIONAPI -->
    </section>
    <section id="validationapi-validatorapi" title="Validator API" level="2">
        <!-- 6.1 - VALIDATIONAPI_VALIDATORAPI -->
        <assertion id="a" testable="false">
            <text>Validator implementations must be thread-safe.</text>
        </assertion>
    </section>
    <section id="validationapi-validatorapi-validationmethods" title="Validation methods" level="3">
        <!-- 6.1.1 - VALIDATIONAPI_VALIDATORAPI_VALIDATIONMETHODS -->
        <assertion id="a">
            <text>&lt;T&gt; Set&lt;ConstraintViolation&lt;T&gt;&gt; validate(T object, Class&lt;?&gt;... groups) is used to validate a given object.</text>
        </assertion>
        <assertion id="b">
            <text>An IllegalArgumentException is thrown when null is passed for the object parameter or the varargs groups parameter.</text>
        </assertion>
        <assertion id="c">
            <text>A Set containing all ConstraintViolation objects representing the failing constraints is returned, an empty Set is returned otherwise.</text>
        </assertion>
        <assertion id="d">
            <text>&lt;T&gt; Set&lt;ConstraintViolation&lt;T&gt;&gt; validateProperty(T object, String propertyName, Class&lt;?&gt;... groups) validates a given field or property of an object.</text>
        </assertion>
        <assertion id="e">
            <text>An IllegalArgumentException is thrown when validateProperty() is called and object is null or propertyName is null, empty or invalid or null is passed to the varargs groups parameter.</text>
        </assertion>
        <assertion id="f">
            <text>The property name is the JavaBeans property name (as defined by the JavaBeans Introspector class).</text>
        </assertion>
        <assertion id="g">
            <text>@Valid is not honored by this method.</text>
        </assertion>
        <assertion id="h">
            <text>&lt;T&gt; Set&lt;ConstraintViolation&lt;T&gt;&gt; validateValue(Class&lt;T&gt; beanType, String propertyName, Object value, Class&lt;?&gt;... groups) validates the property referenced by propertyName present on beanType or any of its superclasses, if the property value were value.</text>
        </assertion>
        <assertion id="i">
            <text>An IllegalArgumentException is thrown when validateValue() is called and beanType is null or propertyName is null, empty or invalid or null is passed to the varargs groups parameter.</text>
        </assertion>
        <assertion id="j">
            <text>@Valid is not honored by this method.</text>
        </assertion>
        <assertion id="k">
            <text>If some unrecoverable failure happens during validation, a ValidationException is raised.</text>
        </assertion>
    </section>
    <section id="validationapi-validatorapi-validationmethods-examples" title="Examples" level="4">
        <!-- 6.1.1.1 - VALIDATIONAPI_VALIDATORAPI_VALIDATIONMETHODS_EXAMPLES -->
    </section>
    <section id="validationapi-validatorapi-methodlevelvalidationmethods" title="Methods for validating method and constructor constraints" level="3">
        <!-- 6.1.2 - VALIDATIONAPI_VALIDATORAPI_METHODLEVELVALIDATIONMETHODS -->
        <assertion id="a">
            <text>&lt;T&gt; Set&lt;ConstraintViolation&lt;T&gt;&gt; validateParameters(T object, Method method, Object[] parameterValues, Class&lt;?&gt;... groups) validates the arguments (as given in parameterValues) for the parameters of a given method (identified by method). Cross-parameter constraints are also validated.</text>
        </assertion>
        <assertion id="b">
            <text>A set containing all ConstraintViolation objects representing the failing constraints is returned, an empty set is returned if no constraint violations occurred.</text>
        </assertion>
        <assertion id="c">
            <text>An IllegalArgumentException will be thrown if null is passed for any of the parameters or if the parameters don't match with each other (i.e. object and method don't match, parameterValues and method don't match).</text>
        </assertion>
        <assertion id="d">
            <text>&lt;T&gt; Set&lt;ConstraintViolation&lt;T&gt;&gt; validateReturnValue(T object, Method method, Object returnValue, Class&lt;?&gt;... groups) validates the return value (specified by returnValue) of a given method (identified by method).</text>
        </assertion>
        <assertion id="e">
            <text>A set containing all ConstraintViolation objects representing the failing constraints is returned, an empty set is returned if no constraint violations occurred.</text>
        </assertion>
        <assertion id="f">
            <text>An IllegalArgumentException will be thrown if null is passed for any of the parameters object, method and groups or if the parameters don't match with each other (i.e. object and method don't match, returnValue and method don't match).</text>
        </assertion>
        <assertion id="g">
            <text>&lt;T&gt; Set&lt;ConstraintViolation&lt;T&gt;&gt; validateConstructorParameters(Constructor&lt;T&gt; constructor, Object[] parameterValues, Class&lt;?&gt;... groups) validates the arguments (as given in parameterValues) for the parameters of a given constructor (identified by constructor). Cross-parameter constraints are also validated.</text>
        </assertion>
        <assertion id="h">
            <text>A set containing all ConstraintViolation objects representing the failing constraints is returned, an empty set is returned if no constraint violations occurred.</text>
        </assertion>
        <assertion id="i">
            <text>An IllegalArgumentException will be thrown if null is passed for any of the parameters or if the parameters don't match with each other (i.e. parameterValues and constructor don't match).</text>
        </assertion>
        <assertion id="j">
            <text>&lt;T&gt; Set&lt;ConstraintViolation&lt;T&gt;&gt; validateConstructorReturnValue(Constructor&lt;T&gt; constructor, T createdObject, Class&lt;?&gt;... groups) validates the object (specified by createdObject) of a given constructor (identified by constructor).</text>
        </assertion>
        <assertion id="k">
            <text>A set containing all ConstraintViolation objects representing the failing constraints is returned, an empty set is returned if no constraint violations occurred.</text>
        </assertion>
        <assertion id="l">
            <text>An IllegalArgumentException will be thrown if null is passed for any of the parameters or if the parameters don't match with each other (i.e. createdObject and constructor don't match).</text>
        </assertion>
        <assertion id="m">
            <text>None of those methods honor the XML configuration around executable validation nor the presence of @ValidateOnExecution. In other words, elements will be validated regardless of these settings when explicitly calling the validation methods.</text>
        </assertion>
    </section>
    <section id="validationapi-validatorapi-methodlevelvalidationmethods-examples" title="Examples" level="4">
        <!-- 6.1.2.1 - VALIDATIONAPI_VALIDATORAPI_METHODLEVELVALIDATIONMETHODS_EXAMPLES -->
    </section>
    <section id="validationapi-validatorapi-groups" title="groups" level="3">
        <!-- 6.1.3 - VALIDATIONAPI_VALIDATORAPI_GROUPS -->
        <assertion id="a">
            <text>All constraints belonging to the targeted group(s) are applied during the 5.7.</text>
        </assertion>
        <assertion id="b">
            <text>If no group is passed, the Default group is assumed.</text>
        </assertion>
        <assertion id="c" testable="false">
            <text>When more than one group is evaluated and passed to the various validate methods, order is not constrained.</text>
        </assertion>
    </section>
    <section id="validationapi-validatorapi-groups-examples" title="Examples" level="4">
        <!-- 6.1.3.1 - VALIDATIONAPI_VALIDATORAPI_GROUPS_EXAMPLES -->
    </section>
    <section id="validationapi-constraintviolation" title="ConstraintViolation" level="2">
        <!-- 6.2 - VALIDATIONAPI_CONSTRAINTVIOLATION -->
        <assertion id="a">
            <text>The getMessage() method returns the interpolated (localized) message for the failing constraint</text>
        </assertion>
        <assertion id="b">
            <text>The getMessageTemplate() method returns the non-interpolated error message</text>
        </assertion>
        <assertion id="c">
            <text>The getRootBean() method returns the root object being validated that led to the failing constraint</text>
        </assertion>
        <assertion id="d">
            <text>For method validation, returns the object the method is executed on. For constructors or when Validator.validateValue() is used, returns null.</text>
        </assertion>
        <assertion id="e">
            <text>The getRootBeanClass() method returns the class of the root bean being validated. For method validation, this is the object class the method is executed on. For constructor validation, this is the class the constructor is declared on.</text>
        </assertion>
        <assertion id="f">
            <text>The getLeafBean() method returns the following object: If a bean constraint, the bean instance the constraint is applied on. If a property constraint or a container element constraint hosted on a property, the bean instance hosting the property the constraint is applied on. If a property constraint, null when the ConstraintViolation is returned after calling Validator.validateValue(). If a method parameter, cross-parameter or return value constraint or a container element constraint hosted on a method parameter or return value, the object the method is executed on. If a constructor parameter or cross-parameter constraint or a container element constraint hosted on a constructor parameter, null. If a constructor return value constraint, the object the constructor has created.</text>
        </assertion>
        <assertion id="g">
            <text>The getExecutableParameters() returns the parameters provided to the method or constructor invocation or null if not validating a method or constructor parameters.</text>
        </assertion>
        <assertion id="h">
            <text>The getExecutableReturnValue() returns the return value of the method or constructor invocation or null if the method has no return value or if not validating a method or constructor return value.</text>
        </assertion>
        <assertion id="i">
            <text>The getInvalidValue() method returns the value (field, property, method/constructor parameter, method/constructor return value, container element or validated object) being passed to isValid().</text>
        </assertion>
        <assertion id="j">
            <text>For a cross-parameter constraint failure, an Object[] representing the method/constructor invocation arguments is returned.</text>
        </assertion>
        <assertion id="k">
            <text>In case a constraint given on a container is subject to implicit application to the container element(s) (see 5.5.1), getInvalidValue() returns the invalid container element value.</text>
        </assertion>
        <assertion id="l">
            <text>getConstraintDescriptor() provides access to the failing constraint metadata</text>
        </assertion>
        <assertion id="m">
            <text>The getPropertyPath() method returns the Path object representing the navigation path from the root object to the failing object.</text>
        </assertion>
        <assertion id="n">
            <text>getName() returns the name of the element which the node represents</text>
        </assertion>
        <assertion id="o">
            <text>isInIterable() returns true if the node represents an object contained in an array or in a multi-valued container such as Iterable or Map, false otherwise.</text>
        </assertion>
        <assertion id="p">
            <text>getIndex() returns the index of the node if it is contained in an array, List or any other container supporting indexed access. Returns null otherwise.</text>
        </assertion>
        <assertion id="q">
            <text>getKey() returns the key of the node if it is contained in a Map or any other container supporting keyed access. Returns null otherwise.</text>
        </assertion>
        <assertion id="r">
            <text>getKind() returns the ElementKind corresponding to the actual node type. This can be used in conjunction with the method as() to narrow the type and access node specific methods</text>
        </assertion>
        <assertion id="s">
            <text>as(Class&lt;? extends Node&gt;) returns the node instance narrowed to the type passed as a parameter or throws a ClassCastException if the type and node don't match.</text>
        </assertion>
        <assertion id="t">
            <text>In particular, MethodNode and ConstructorNode host getParameterTypes() which return the method or constructor parameter list.</text>
        </assertion>
        <assertion id="u">
            <text>Likewise ParameterNode hosts getParameterIndex() which returns the parameter index in the method or constructor parameter list.</text>
        </assertion>
        <assertion id="v">
            <text>BeanNode, PropertyNode and ContainerElementNode host getContainerClass() and getTypeArgumentIndex(). If the node represents an element that is contained in a container such as Optional, List or Map, the former returns the declared type of the container and, if the container is of a generic type, the latter returns the index of the affected type argument.</text>
        </assertion>
        <assertion id="w">
            <text>The runtime type is considered, not the static type. For example if a property is declared Collection&lt;String&gt; but its runtime type is ArrayList&lt;String&gt;, the property is considered an ArrayList&lt;String&gt;.</text>
        </assertion>
        <assertion id="x">
            <text>If the failing object is the root object, a BeanNode with name set to null is added to the Path. The ElementKind of the node is ElementKind.BEAN.</text>
        </assertion>
        <assertion id="y">
            <text>A PropertyNode object whose name equals the name of the association property (field name or Java Bean property name) is added to Path. The ElementKind of the node is ElementKind.PROPERTY.</text>
        </assertion>
        <assertion id="z">
            <text>If the association is an array, a List or any other container whose value extractor invokes ValueReceiver#indexedValue() (see 4), the following Node object added contains the index value in getIndex()</text>
        </assertion>
        <assertion id="aa">
            <text>If the association is a Map or any other container whose value extractor invokes ValueReceiver#keyedValue(), the following Node object added (representing a given map entry) contains the key value in getKey()</text>
        </assertion>
        <assertion id="ab">
            <text>For all Iterable, Map or other container whose value extractor invokes ValueReceiver#indexedValue(), ValueReceiver#keyedValue() or ValueReceiver#iterableValue(), the following Node object added is marked as inIterable (isInIterable())</text>
        </assertion>
        <assertion id="ac">
            <text>If the traversed object is of a container type (e.g. a List or Map), the following Node object added returns the declared type of the traversed container via getContainerClass() and the index of the affected type argument via getTypeArgumentIndex()</text>
        </assertion>
        <assertion id="ad">
            <text>If the value extractor of the outer container has provided a non-null node name, a ContainerElementNode object whose name equals that name is added to Path. The ElementKind of the node is ElementKind.CONTAINER_ELEMENT</text>
        </assertion>
        <assertion id="ae">
            <text>If the container is a List or any other container whose value extractor invokes ValueReceiver#indexedValue(), the following Node object added contains the index value in getIndex()</text>
        </assertion>
        <assertion id="af">
            <text>If the container is a Map or any other container whose value extractor invokes ValueReceiver#keyedValue(), the following Node object added (representing a given map entry) contains the key value in getKey()</text>
        </assertion>
        <assertion id="ag">
            <text>For all Iterable, Map or other container whose value extractor invokes ValueReceiver#indexedValue(), ValueReceiver#keyedValue() or ValueReceiver#iterableValue(), the following Node object added is marked as inIterable (isInIterable())</text>
        </assertion>
        <assertion id="ah">
            <text>The following Node object added returns the declared type of the traversed container via getContainerClass() and the index of the affected type argument via getTypeArgumentIndex()</text>
        </assertion>
        <assertion id="ai">
            <text>For a property level constraint (field and getter) a PropertyNode object is added to Path whose name equals the name of the property (field name or Java Bean property name). The ElementKind of the node is ElementKind.PROPERTY. the property path is considered complete</text>
        </assertion>
        <assertion id="aj">
            <text>For a class level constraint: a BeanNode object is added to Path whose name is null. The ElementKind of the node is ElementKind.BEAN. the property path is considered complete</text>
        </assertion>
        <assertion id="ak">
            <text>A MethodNode respectively a ConstructorNode object is added to the Path which represents the validated method respectively constructor. The name of the node equals the validated method name or the validated constructor's unqualified class name, the ElementKind of the node is ElementKind.METHOD respectively ElementKind.CONSTRUCTOR.</text>
        </assertion>
        <assertion id="al">
            <text>If the constraint is on a parameter, a ParameterNode object is added to the Path which represents the validated parameter. The name of the node equals the parameter name as determined by the current parameter name provider (see 5.6.2.2). The ElementKind of the node is ElementKind.PARAMETER.</text>
        </assertion>
        <assertion id="am">
            <text>If the constraint is a cross-parameter constraint, a CrossParameterNode object is added to the Path which represents the validated cross-parameter element. The name of the node has the constant value &lt;cross-parameter&gt;. The ElementKind of the node is ElementKind.CROSS_PARAMETER.</text>
        </assertion>
        <assertion id="an">
            <text>If the constraint is on the return value, a ReturnValueNode object is added to the Path which represents the validated return value. The name of the node has the constant value &lt;return value&gt;. The ElementKind of the node is ElementKind.RETURN_VALUE.</text>
        </assertion>
        <assertion id="ao">
            <text>The property path is considered complete</text>
        </assertion>
        <assertion id="ap">
            <text>A MethodNode respectively ConstructorNode object is added to the Path which represents the concerned method respectively constructor. The name of the node equals the concerned method name or the constructor's unqualified class name, the ElementKind of the node is ElementKind.METHOD or ElementKind.CONSTRUCTOR, respectively.</text>
        </assertion>
        <assertion id="aq">
            <text>If a parameter is traversed, a ParameterNode object is added to the Path which represents the traversed parameter. The name of the node equals the parameter name as determined by the current parameter name provider. The ElementKind of the node is ElementKind.PARAMETER.</text>
        </assertion>
        <assertion id="ar">
            <text>If a return value is traversed, a ReturnValueNode object is added to the Path which represents the traversed return value. The name of the node has the constant value &lt;return value&gt;. The ElementKind of the node is ElementKind.RETURN_VALUE.</text>
        </assertion>
        <assertion id="as">
            <text>If the parameter/return value is a List or an array, the following Node object added contains the index value in getIndex().</text>
        </assertion>
        <assertion id="at">
            <text>If the parameter/return value is a Map, the following Node object added (representing a given map entry) contains the key value in getKey().</text>
        </assertion>
        <assertion id="au">
            <text>For all Iterable or Map, the following Node object added is marked as inIterable (isInIterable()).</text>
        </assertion>
        <assertion id="av">
            <text>For a container element constraint: if the corresponding value extractor (see 4) has specified a node name when calling one of the receiver methods, a ContainerElementNode object with that name is added to the Path. The ElementKind of the node is ElementKind.CONTAINER_ELEMENT. getContainerClass() returns the declared type of the container hosting the constraint. getTypeArgumentIndex() returns the index of the type argument hosting the constraint. If the constraint is given on a container and is subject to implicit application to the container's element(s) (see 5.5.1) and the applied value extractor is not tied to a type parameter, getTypeArgumentIndex() returns null. if the corresponding value extractor has passed no node name to the called receiver method, no node is appended. the property path is considered complete</text>
        </assertion>
        <assertion id="aw">
            <text>If additional path nodes are added in a constraint validator implementation using the node builder API (see 3.4), the following rules apply: if the default path ends with a BeanNode, this node is removed and the first added node (a PropertyNode) inherits its inIterable, key and index values. inIterable, key and index value must not be specified directly on this first node by the user. if the default path ends with a CrossParameterNode, this node is removed. then the additional nodes are appended to the (possibly amended) path generated by the Jakarta Bean Validation engine as previously described</text>
        </assertion>
        <assertion id="ax">
            <text>A PropertyNode is appended in case addPropertyNode(String) is invoked. The node name is equal to the name provided. The ElementKind of the node is ElementKind.PROPERTY.</text>
        </assertion>
        <assertion id="ay">
            <text>A BeanNode is appended in case addBeanNode() is invoked. The node name is null. The ElementKind of the node is ElementKind.BEAN.</text>
        </assertion>
        <assertion id="az">
            <text>A ParameterNode is appended in case addParameterNode(int) is invoked. The node name is equal to the parameter name at the provided index. The name is determined by the current parameter name provider. The ElementKind of the node is ElementKind.PARAMETER. The previous node (removed) must be a CrossParameterNode.</text>
        </assertion>
        <assertion id="ba">
            <text>A ContainerElementNode is appended in case addContainerElementNode(String, Class, Integer) is invoked. The name, container type and type argument index of the node are equal to the values provided. The ElementKind of the node is ElementKind.CONTAINER_ELEMENT.</text>
        </assertion>
        <assertion id="bb">
            <text>If inIterable() is invoked, the node returns true for isInIterable(), false otherwise.</text>
        </assertion>
        <assertion id="bc">
            <text>If inContainer(Class, Integer) is invoked, the node returns the passed container type and type argument index from getContainerClass() and getTypeArgumentIndex(), respectively.</text>
        </assertion>
        <assertion id="bd">
            <text>If atIndex(Integer) is invoked, the node returns the provided integer for getIndex(), null otherwise.</text>
        </assertion>
        <assertion id="be">
            <text>If atKey(Object) is invoked, the node returns the provided object for getKey(), null otherwise.</text>
        </assertion>
        <assertion id="bf" testable="false">
            <text>Jakarta Bean Validation implementations should ensure that a ConstraintViolation implementation is Serializable provided that the root bean, the leaf bean, the invalid value and keys in the Path object are Serializable objects.</text>
        </assertion>
    </section>
    <section id="validationapi-constraintviolation-examples" title="Examples" level="3">
        <!-- 6.2.1 - VALIDATIONAPI_CONSTRAINTVIOLATION_EXAMPLES -->
    </section>
    <section id="validationapi-constraintviolation-examplesexecutables" title="Examples for method and constructor constraint violations" level="3">
        <!-- 6.2.2 - VALIDATIONAPI_CONSTRAINTVIOLATION_EXAMPLESEXECUTABLES -->
    </section>
    <section id="validationapi-message" title="Message interpolation" level="2">
        <!-- 6.3 - VALIDATIONAPI_MESSAGE -->
    </section>
    <section id="validationapi-message-defaultmessageinterpolation" title="Default message interpolation" level="3">
        <!-- 6.3.1 - VALIDATIONAPI_MESSAGE_DEFAULTMESSAGEINTERPOLATION -->
        <assertion id="a">
            <text>Every conforming Jakarta Bean Validation implementation includes a default message interpolator which has to comply with the algorithm defined here to interpolate message descriptors.</text>
        </assertion>
        <assertion id="b">
            <text>Each constraint defines a message descriptor via its message property.</text>
        </assertion>
        <assertion id="c">
            <text>Every constraint definition defines a default message descriptor for that constraint.</text>
        </assertion>
        <assertion id="d">
            <text>Messages can be overridden at constraint declaration time by setting the message property on the constraint.</text>
        </assertion>
        <assertion id="e">
            <text>The message descriptor is a string literal and may contain one or more message parameters or expressions. Message parameters and expressions are string literals enclosed in {} or ${} respectively.</text>
        </assertion>
        <assertion id="f">
            <text>\{ is considered as the literal { instead of being considered as the beginning of a message parameter</text>
        </assertion>
        <assertion id="g">
            <text>\} is considered as the literal } instead of being considered as the end of a message parameter</text>
        </assertion>
        <assertion id="h">
            <text>\\ is considered as the literal \ instead of being considered as the escaping character</text>
        </assertion>
        <assertion id="i">
            <text>\$ is considered as the literal $ instead of being considered as the beginning of a message expression</text>
        </assertion>
    </section>
    <section id="validationapi-message-defaultmessageinterpolation-resolutionalgorithm" title="Default message interpolation algorithm" level="4">
        <!-- 6.3.1.1 - VALIDATIONAPI_MESSAGE_DEFAULTMESSAGEINTERPOLATION_RESOLUTIONALGORITHM -->
        <assertion id="a">
            <text>Message parameters are extracted from the message string and used as keys to search the ResourceBundle named ValidationMessages</text>
        </assertion>
        <assertion id="b">
            <text>Step 1 is applied recursively until no replacement is performed</text>
        </assertion>
        <assertion id="c">
            <text>Message parameters are extracted from the message string and used as keys to search the Jakarta Bean Validation provider's built-in ResourceBundle using the defined locale (see 6.3.1.2). If a property is found, the message parameter is replaced with the property value in the message string.</text>
        </assertion>
        <assertion id="d" testable="false">
            <text>Contrary to step 1, step 2 is not processed recursively.</text>
        </assertion>
        <assertion id="e" testable="false">
            <text>If step 2 triggers a replacement, then step 1 is applied again.</text>
        </assertion>
        <assertion id="f">
            <text>Message parameters are extracted from the message string. Those matching the name of an attribute of the constraint are replaced by the value of that attribute in the constraint declaration. Parameter interpolation has precedence over message expressions. For example for the message descriptor ${value}, trying to evaluate {value} as message parameter has precedence over evaluating ${value} as message expression.</text>
        </assertion>
        <assertion id="g">
            <text>Message expressions are extracted from the message string and evaluated using Jakarta Expression Language. See also 6.3.1.3.</text>
        </assertion>
    </section>
    <section id="validationapi-message-defaultmessageinterpolation-locale" title="Locale for default message interpolation" level="4">
        <!-- 6.3.1.2 - VALIDATIONAPI_MESSAGE_DEFAULTMESSAGEINTERPOLATION_LOCALE -->
        <assertion id="a">
            <text>If the locale is passed explicitly to the interpolator method via interpolate(String, Context, Locale), this provided instance is used.</text>
        </assertion>
        <assertion id="b">
            <text>Otherwise, the default Locale as provided by Locale.getDefault() is used.</text>
        </assertion>
    </section>
    <section id="validationapi-message-defaultmessageinterpolation-expressionlanguage" title="Message expressions using Jakarta Expression Language" level="4">
        <!-- 6.3.1.3 - VALIDATIONAPI_MESSAGE_DEFAULTMESSAGEINTERPOLATION_EXPRESSIONLANGUAGE -->
        <assertion id="a">
            <text>The default message interpolation allows the use of Jakarta Expression Language.</text>
        </assertion>
        <assertion id="b">
            <text>Expressions to be evaluated by Jakarta Expression Language need to be enclosed in ${} within the message descriptor</text>
        </assertion>
        <assertion id="c">
            <text>The attribute values of the constraint declaration mapped to their attribute name</text>
        </assertion>
        <assertion id="d">
            <text>The validated value mapped under the name validatedValue.</text>
        </assertion>
        <assertion id="e">
            <text>A bean mapped to the name formatter exposing the vararg method format(String format, Object... args). This method must behave like java.util.Formatter.format(String format, Object... args). The locale used for formatting is defined by 6.3.1.2. The formatter bean allows to format property values, for example in the case of the validated value being 98.12345678, ${formatter.format('%1$.2f', validatedValue)} would format it to 98.12 (two digits after the decimal point, where the use of '.' vs ',' would be locale specific).</text>
        </assertion>
        <assertion id="f">
            <text>If an exception occurs during message interpolation, e.g. due to invalid expressions or references to an unknown property, the message expression stays unchanged.</text>
        </assertion>
    </section>
    <section id="validationapi-message-customresolution" title="Custom message interpolation" level="3">
        <!-- 6.3.2 - VALIDATIONAPI_MESSAGE_CUSTOMRESOLUTION -->
        <assertion id="a">
            <text>messageTemplate is the value of the message attribute of the constraint declaration or provided to the ConstraintValidatorContext methods.</text>
        </assertion>
        <assertion id="b">
            <text>getConstraintDescriptor() returns the ConstraintDescriptor object representing the metadata of the failing constraint (see 7).</text>
        </assertion>
        <assertion id="c">
            <text>getValidatedValue() returns the value being validated.</text>
        </assertion>
        <assertion id="d" testable="false">
            <text>A message interpolator implementation must be thread-safe.</text>
        </assertion>
        <assertion id="e">
            <text>It is possible to override the MessageInterpolator implementation for a given Validator instance by invoking ValidatorFactory.usingContext().messageInterpolator(messageInterpolator).getValidator().</text>
        </assertion>
        <assertion id="f">
            <text>The default implementation is accessible through Configuration.getDefaultMessageInterpolator().</text>
        </assertion>
        <assertion id="g">
            <text>If the interpolation process leads to an exception, the exception is wrapped into a ValidationException.</text>
        </assertion>
    </section>
    <section id="validationapi-message-examples" title="Examples" level="3">
        <!-- 6.3.3 - VALIDATIONAPI_MESSAGE_EXAMPLES -->
    </section>
    <section id="validationapi-triggeringmethodvalidation" title="Triggering method validation" level="2">
        <!-- 6.4 - VALIDATIONAPI_TRIGGERINGMETHODVALIDATION -->
        <assertion id="a">
            <text>The validation of method / constructor constraints comprises the following steps: Intercept the method call to be validated Validate the parameter values provided by the method caller using ExecutableValidator.validateParameters() or ExecutableValidator.validateConstructorParameters(). If this validation yields a non-empty set of constraint violations, throw a ConstraintViolationException wrapping the violations. Otherwise proceed with the actual method invocation. Validate the result returned by the invoked method using ExecutableValidator.validateReturnValue() or ExecutableValidator.validateConstructorReturnValue(). If this validation yields a non-empty set of constraint violations, throw a ConstraintViolationException wrapping the violations. Otherwise return the invocation result to the method caller.</text>
        </assertion>
        <assertion id="b">
            <text>The Default group is used for validation out of the box.</text>
        </assertion>
    </section>
    <section id="validationapi-bootstrapping" title="Bootstrapping" level="2">
        <!-- 6.5 - VALIDATIONAPI_BOOTSTRAPPING -->
        <assertion id="a">
            <text>A bootstrap implementation must be able to bootstrap any Jakarta Bean Validation provider implementation.</text>
        </assertion>
    </section>
    <section id="validationapi-bootstrapping-examples" title="Examples" level="3">
        <!-- 6.5.1 - VALIDATIONAPI_BOOTSTRAPPING_EXAMPLES -->
        <assertion id="a" testable="false">
            <text>The ValidatorFactory object is thread-safe.</text>
        </assertion>
    </section>
    <section id="validationapi-bootstrapping-validatorfactory" title="ValidatorFactory" level="3">
        <!-- 6.5.2 - VALIDATIONAPI_BOOTSTRAPPING_VALIDATORFACTORY -->
        <assertion id="a" testable="false">
            <text>ValidatorFactory implementations must be thread-safe.</text>
        </assertion>
        <assertion id="b">
            <text>getMessageInterpolator() returns the MessageInterpolator instance configured during the initialization of the ValidatorFactory.</text>
        </assertion>
        <assertion id="c">
            <text>getTraversableResolver() returns the TraversableResolver instance configured during the initialization of the ValidatorFactory.</text>
        </assertion>
        <assertion id="d">
            <text>getConstraintValidatorFactory() returns the ConstraintValidatorFactory instance configured during the initialization of the ValidatorFactory.</text>
        </assertion>
        <assertion id="e">
            <text>getParameterNameProvider() returns the ParameterNameProvider instance configured during the initialization of the ValidatorFactory.</text>
        </assertion>
        <assertion id="f">
            <text>getClockProvider() returns the ClockProvider instance configured during the initialization of the ValidatorFactory.</text>
        </assertion>
        <assertion id="g">
            <text>The MessageInterpolator, the TraversableResolver, the ConstraintValidatorFactory, the ParameterNameProvider or the ClockProvider passed to the ValidatorContext are used instead of the ValidatorFactory's MessageInterpolator, TraversableResolver, ConstraintValidatorFactory, ParameterNameProvider or ClockProvider instances.</text>
        </assertion>
        <assertion id="h">
            <text>A ValueExtractorDeclarationException is raised if more than one extractor for the same type and type parameter is added via addValueExtractor().</text>
        </assertion>
    </section>
    <section id="validationapi-bootstrapping-configuration" title="Configuration" level="3">
        <!-- 6.5.3 - VALIDATIONAPI_BOOTSTRAPPING_CONFIGURATION -->
        <assertion id="a">
            <text>Configuration does provide a MessageInterpolator implementation following the default Jakarta Bean Validation MessageInterpolator rules as defined in 6.3.1. You can access it by calling getDefaultMessageInterpolator().</text>
        </assertion>
        <assertion id="b">
            <text>Configuration does provide a TraversableResolver implementation following the default Jakarta Bean Validation TraversableResolver rules as defined in 5.7.3. You can access it by calling getDefaultTraversableResolver().</text>
        </assertion>
        <assertion id="c">
            <text>Configuration does provide a ConstraintValidatorFactory implementation following the default Jakarta Bean Validation ConstraintValidatorFactory rules as defined in 3.5. You can access it by calling getDefaultConstraintValidatorFactory().</text>
        </assertion>
        <assertion id="d">
            <text>Configuration does provide a ParameterNameProvider implementation following the default Jakarta Bean Validation ParameterNameProvider rules as defined in 5.6.2.2. You can access it by calling getDefaultParameterNameProvider().</text>
        </assertion>
        <assertion id="e">
            <text>Configuration does provide a ClockProvider implementation following the default Jakarta Bean Validation ClockProvider rules as defined in 3.4.1. You can access it by calling getDefaultClockProvider().</text>
        </assertion>
        <assertion id="f">
            <text>Via getBootstrapConfiguration(), Configuration also exposes data stored in META-INF/validation.xml</text>
        </assertion>
        <assertion id="g">
            <text>Via addValueExtractor(), additional value extractor implementations can be added to the configuration. A value extractor for a given type and type parameter takes precedence over any extractor for the same type and type parameter detected through the service loader or given in the XML configuration.</text>
        </assertion>
        <assertion id="h">
            <text>A ValueExtractorDeclarationException is raised if more than one extractor for the same type and type parameter is added.</text>
        </assertion>
        <assertion id="i">
            <text>Using addMapping(), additional constraint mapping XML descriptors can be added to the configuration</text>
        </assertion>
        <assertion id="j">
            <text>Streams not supporting the mark() and reset() methods will be wrapped with an InputStream implementation supporting these methods by the Jakarta Bean Validation provider in order to allow the streams to be read several times.</text>
        </assertion>
        <assertion id="k">
            <text>It is legal to invoke buildValidatorFactory() several times, e.g. in order to retrieve several ValidatorFactory instances with a slightly different configuration (see ).</text>
        </assertion>
        <assertion id="l">
            <text>A Jakarta Bean Validation provider must define a sub interface of Configuration uniquely identifying the provider.</text>
        </assertion>
        <assertion id="m" testable="false">
            <text>Streams represented in the XML configuration and opened by the Configuration implementation must be closed by the Configuration implementation after the ValidatorFactory creation (or if an exception occurs).</text>
        </assertion>
        <assertion id="n">
            <text>The requested provider implementation is resolved according to the following rules in the following order: Use the provider implementation requested if Configuration has been created from Validation.byProvider(Class). Use the provider implementation described in the XML configuration (under validation-config.default-provider see 6.5.6) if defined: the value of this element is the fully qualified class name of the ValidationProvider implementation uniquely identifying the provider. Use the first provider implementation returned by validationProviderResolver.getValidationProviders().</text>
        </assertion>
        <assertion id="o" testable="false">
            <text>If no ValidationProviderResolver instance has been specified, the default ValidationProviderResolver is used.</text>
        </assertion>
    </section>
    <section id="validationapi-bootstrapping-validationprovider" title="ValidationProvider and ValidationProviderResolver" level="3">
        <!-- 6.5.4 - VALIDATIONAPI_BOOTSTRAPPING_VALIDATIONPROVIDER -->
    </section>
    <section id="validationapi-bootstrapping-validationprovider-resolver" title="ValidationProviderResolver" level="4">
        <!-- 6.5.4.1 - VALIDATIONAPI_BOOTSTRAPPING_VALIDATIONPROVIDER_RESOLVER -->
        <assertion id="a">
            <text>ValidationProviderResolver returns the list of Jakarta Bean Validation providers available at runtime and more specifically a ValidationProvider instance for each provider available in the context.</text>
        </assertion>
        <assertion id="b" testable="false">
            <text>Implementations must be thread-safe.</text>
        </assertion>
        <assertion id="c" testable="false">
            <text>Jakarta Bean Validation providers must supply a service provider configuration file by creating a text file jakarta.validation.spi.ValidationProvider and placing it in the META-INF/services directory of one of its jar files.</text>
        </assertion>
    </section>
    <section id="validationapi-bootstrapping-validationprovider-provider" title="ValidationProvider" level="4">
        <!-- 6.5.4.2 - VALIDATIONAPI_BOOTSTRAPPING_VALIDATIONPROVIDER_PROVIDER -->
        <assertion id="a">
            <text>A client can request a specific Jakarta Bean Validation provider by using &lt;T extends Configuration&lt;T&gt;, U extends ValidationProvider&lt;T&gt;&gt; Validation.byProvider(Class&lt;U&gt;) or by defining the provider in the XML configuration file.</text>
        </assertion>
        <assertion id="b">
            <text>The provider discovery mechanism uses the following algorithm: Retrieve available providers using ValidationProviderResolver.getValidationProviders(). The first ValidationProvider matching the requested provider is returned. Providers are evaluated in the order they are returned by ValidationProviderResolver. A provider instance is considered matching if it is assignable to the requested provider class.</text>
        </assertion>
        <assertion id="c">
            <text>When the default Jakarta Bean Validation provider is requested, the first ValidationProvider returned by the ValidationProviderResolver strategy is returned.</text>
        </assertion>
        <assertion id="d">
            <text>Every Jakarta Bean Validation provider must provide a ValidationProvider implementation containing a public no-arg constructor</text>
        </assertion>
        <assertion id="e">
            <text>If a problem occurs while building the ValidatorFactory, a ValidationException is raised.</text>
        </assertion>
    </section>
    <section id="validationapi-bootstrapping-validation" title="Validation" level="3">
        <!-- 6.5.5 - VALIDATIONAPI_BOOTSTRAPPING_VALIDATION -->
        <assertion id="a">
            <text>The first entry point, buildDefaultValidatorFactory(), is considered to be the default ValidatorFactory and is equivalent to the ValidatorFactory returned by Validation.byDefaultProvider().configure().buildValidatorFactory().</text>
        </assertion>
        <assertion id="b">
            <text>The second entry point lets the client provide a custom ValidationProviderResolver instance. This instance is passed to GenericBootstrap. GenericBootstrap builds a generic Configuration using the first ValidationProvider returned by ValidationProviderResolution and calling ValidationProvider.createGenericConfiguration(BootstrapState state).</text>
        </assertion>
        <assertion id="c">
            <text>The last entry point lets the client define the specific Jakarta Bean Validation provider requested as well as a custom ValidationProviderResolver implementation if needed. The entry point method, Validation.byProvider(Class&lt;U&gt; providerType), takes the provider specific ValidationProvider implementation type and returns a ProviderSpecificBootstrap object that guarantees to return an instance of the specific Configuration sub interface.</text>
        </assertion>
        <assertion id="d">
            <text>The Validation implementation must not contain any non private attribute or method aside from the three public static bootstrap methods</text>
        </assertion>
        <assertion id="e">
            <text>The bootstrap implementation must ensure it can bootstrap third party providers.</text>
        </assertion>
        <assertion id="f">
            <text>When bootstrapping a Jakarta Bean Validation provider, if the ValidationProviderResolver either fails or if the expected provider is not found, a ValidationException is raised.</text>
        </assertion>
    </section>
    <section id="validationapi-bootstrapping-xmlconfiguration" title="XML configuration: META-INF/validation.xml" level="3">
        <!-- 6.5.6 - VALIDATIONAPI_BOOTSTRAPPING_XMLCONFIGURATION -->
        <assertion id="a">
            <text>Unless explicitly ignored by calling Configuration.ignoreXMLConfiguration(), a Configuration takes into account the configuration available in META-INF/validation.xml.</text>
        </assertion>
        <assertion id="b">
            <text>This configuration file is optional</text>
        </assertion>
        <assertion id="c" testable="false">
            <text>If more than one META-INF/validation.xml file is found in the classpath, a ValidationException is raised.</text>
        </assertion>
        <assertion id="d">
            <text>Unless stated otherwise, XML based configuration settings are overridden by values explicitly set via the Configuration API.</text>
        </assertion>
        <assertion id="e">
            <text>default-provider: represents the class name of the provider specific ValidationProvider implementation class. If defined, the specific provider is used</text>
        </assertion>
        <assertion id="f">
            <text>message-interpolator: represents the fully qualified class name of the MessageInterpolator implementation. When defined in XML, the implementation must have a public no-arg constructor.</text>
        </assertion>
        <assertion id="g">
            <text>traversable-resolver: represents the fully qualified class name of the TraversableResolver implementation. When defined in XML, the implementation must have a public no-arg constructor.</text>
        </assertion>
        <assertion id="h">
            <text>constraint-validator-factory: represents the fully qualified class name of the ConstraintValidatorFactory implementation. When defined in XML, the implementation must have a public no-arg constructor.</text>
        </assertion>
        <assertion id="i">
            <text>parameter-name-provider: represents the fully qualified class name of the ParameterNameProvider implementation. When defined in XML, the implementation must have a public no-arg constructor.</text>
        </assertion>
        <assertion id="j">
            <text>clock-provider: represents the fully qualified class name of the ClockProvider implementation. When defined in XML, the implementation must have a public no-arg constructor.</text>
        </assertion>
        <assertion id="k">
            <text>value-extractor: represents the fully qualified class name of a ValueExtractor implementation.</text>
        </assertion>
        <assertion id="l">
            <text>value-extractor can be given several times for declaring multiple extractors.</text>
        </assertion>
        <assertion id="m">
            <text>When defined in XML, the implementation must have a public no-arg constructor.</text>
        </assertion>
        <assertion id="n">
            <text>An extractor for a given type and type parameter configured via XML takes precedence over any extractor for the same type and type parameter detected through the service loader or provided by the Jakarta Bean Validation implementation itself.</text>
        </assertion>
        <assertion id="o">
            <text>If more than one value extractor for the same type and type parameter is configured via XML, a ValueExtractorDeclarationException is raised.</text>
        </assertion>
        <assertion id="p">
            <text>executable-validation: allows to disable executable validation entirely via its attribute enabled="false" and optionally contains default-validated-executable-types. enabled defaults to true.</text>
        </assertion>
        <assertion id="q">
            <text>default-validated-executable-types: declared under executable-validation, contains the list of executable-type that are considered by default by the integration technology validating executables upon execution.</text>
        </assertion>
        <assertion id="r">
            <text>constraint-mapping: represents the resource path of an XML mapping file.</text>
        </assertion>
        <assertion id="s">
            <text>More than one constraint-mapping element can be present.</text>
        </assertion>
        <assertion id="t">
            <text>Mappings provided via Configuration.addMapping(InputStream) are added to the list of mappings described via constraint-mapping.</text>
        </assertion>
        <assertion id="u" testable="false">
            <text>The namespace jakarta.validation is reserved for use by this specification.</text>
        </assertion>
        <assertion id="v" testable="false">
            <text>Properties defined via Configuration.addProperty(String, String) are added to the properties defined via property.</text>
        </assertion>
        <assertion id="w" testable="false">
            <text>If a property with the same name are defined in both XML and via the programmatic API, the value provided via programmatic API has priority.</text>
        </assertion>
        <assertion id="x">
            <text>All these top level elements are optional.</text>
        </assertion>
        <assertion id="y">
            <text>If a public no-arg constructor is missing on any of the classes referenced by the relevant XML elements, a ValidationException is raised during the Configuration.buildValidatorFactory() call.</text>
        </assertion>
    </section>
    <section id="validationapi-bootstrapping-usageandcontainerexpectation" title="Bootstrapping considerations" level="3">
        <!-- 6.5.7 - VALIDATIONAPI_BOOTSTRAPPING_USAGEANDCONTAINEREXPECTATION -->
        <assertion id="a" testable="false">
            <text>ValidatorFactory is a thread-safe object that should be built once per deployment unit.</text>
        </assertion>
        <assertion id="b" testable="false">
            <text>Validator is a thread-safe and lightweight object which can be cached by the ValidatorFactory instance.</text>
        </assertion>
    </section>
    <section id="constraintmetadata" title="Constraint metadata request APIs" level="1">
        <!-- 7 - CONSTRAINTMETADATA -->
    </section>
    <section id="constraintmetadata-validator" title="Validator" level="2">
        <!-- 7.1 - CONSTRAINTMETADATA_VALIDATOR -->
        <assertion id="a">
            <text>getConstraintsForClass() returns a BeanDescriptor object describing the bean level constraints (see 5.1.1) and providing access to the property level constraints metadata.</text>
        </assertion>
        <assertion id="b">
            <text>An IllegalArgumentException is raised if the clazz parameter is null.</text>
        </assertion>
        <assertion id="c">
            <text>If a constraint definition or declaration hosted by the requested class (or any of its superclasses and interfaces according to the constraint propagation rules) is invalid, a ValidationException is raised.</text>
        </assertion>
    </section>
    <section id="constraintmetadata-elementdescriptor" title="ElementDescriptor" level="2">
        <!-- 7.2 - CONSTRAINTMETADATA_ELEMENTDESCRIPTOR -->
        <assertion id="a">
            <text>getElementClass() returns the object type when invoked on BeanDescriptor, the type of a property or parameter when invoked on PropertyDescriptor or ParameterDescriptor respectively, Object[].class when invoked on CrossParameterDescriptor, the return type when invoked on ConstructorDescriptor, MethodDescriptor or ReturnValueDescriptor, the container element type when invoked on ContainerElementTypeDescriptor (e.g. when invoked on a descriptor representing the container element type of List&lt;String&gt;, String.class will be returned).</text>
        </assertion>
        <assertion id="b">
            <text>getConstraintDescriptors() returns all the ConstraintDescriptors (see 7.12) hosted on the given element in the class hierarchy, each ConstraintDescriptor describing one of the constraints declared on the given element.</text>
        </assertion>
        <assertion id="c">
            <text>hasConstraints() returns true if the given element in the class hierarchy holds at least one constraint declaration.</text>
        </assertion>
        <assertion id="d">
            <text>If you need to query the metadata API in a more fine grained way for example by restricting the constraints to the ones described on fields or on getters or by restricting to a given set of groups, you can use the ConstraintFinder fluent API by calling findConstraints().</text>
        </assertion>
        <assertion id="e">
            <text>unorderedAndMatchingGroups() restricts the results to the ConstraintDescriptors (see 7.12) matching the given groups. Order is not respected but group inheritance and inheritance via sequence (including the Default group overriding at the class level) are honored.</text>
        </assertion>
        <assertion id="f">
            <text>declaredOn() lets you restrict the list of element types constraints are hosted on.</text>
        </assertion>
        <assertion id="g">
            <text>lookingAt() lets you restrict which constraints are considered. Either constraints belonging to the element but hosted on the class represented by the given descriptor (Scope.LOCAL_ELEMENT), or constraints belonging to the element but hosted anywhere in the class hierarchy (Scope.HIERARCHY).</text>
        </assertion>
    </section>
    <section id="constraintmetadata-beandescriptor" title="BeanDescriptor" level="2">
        <!-- 7.3 - CONSTRAINTMETADATA_BEANDESCRIPTOR -->
        <assertion id="a">
            <text>isBeanConstrained() returns true if the given class (and superclasses and interfaces) has at least one class-level or property-level constraint or validation cascade.</text>
        </assertion>
        <assertion id="b">
            <text>getConstraintsForProperty() returns a PropertyDescriptor object describing the property level constraints (See 5.1.2). The property is uniquely identified by its name as per the JavaBeans convention: field level and getter level constraints of the given name are all returned.</text>
        </assertion>
        <assertion id="c">
            <text>An IllegalArgumentException is raised if the propertyName parameter is null.</text>
        </assertion>
        <assertion id="d">
            <text>getConstrainedProperties() returns the PropertyDescriptors of the bean properties having at least one constraint or being cascaded (@Valid annotation).</text>
        </assertion>
        <assertion id="e">
            <text>getConstraintsForMethod() returns a MethodDescriptor object describing the method constraints of the given method. The method is uniquely identified by its name and the types of its parameters.</text>
        </assertion>
        <assertion id="f">
            <text>getConstrainedMethods() returns the MethodDescriptors of the methods matching the MethodTypes provided as parameter and having at least one constraint or cascaded parameter or return value.</text>
        </assertion>
        <assertion id="g">
            <text>getConstraintsForConstructor() returns a ConstructorDescriptor object describing the method constraints of the given constructor. The constructor is uniquely identified by its name and the types of its parameters.</text>
        </assertion>
        <assertion id="h">
            <text>getConstrainedConstructors() returns the ConstructorDescriptors of the constructors having at least one constraint or cascaded parameter or return value.</text>
        </assertion>
    </section>
    <section id="constraintmetadata-cascadabledescriptor" title="CascadableDescriptor" level="2">
        <!-- 7.4 - CONSTRAINTMETADATA_CASCADABLEDESCRIPTOR -->
        <assertion id="a">
            <text>The isCascaded() method returns true if the element is marked for cascaded validation.</text>
        </assertion>
        <assertion id="b">
            <text>The method getGroupConversions() returns a set with the group conversions declared for the cascadable element. An empty set will be returned if no group conversions are configured.</text>
        </assertion>
    </section>
    <section id="constraintmetadata-groupconversiondescriptor" title="GroupConversionDescriptor" level="2">
        <!-- 7.5 - CONSTRAINTMETADATA_GROUPCONVERSIONDESCRIPTOR -->
        <assertion id="a">
            <text>The getFrom() method returns the source of a group conversion rule.</text>
        </assertion>
        <assertion id="b">
            <text>The getTo() method returns the target of a group conversion rule.</text>
        </assertion>
    </section>
    <section id="constraintmetadata-propertydescriptor" title="PropertyDescriptor" level="2">
        <!-- 7.6 - CONSTRAINTMETADATA_PROPERTYDESCRIPTOR -->
        <assertion id="a">
            <text>getPropertyName() returns the property name as described in 6.2.</text>
        </assertion>
    </section>
    <section id="constraintmetadata-executabledescriptor" title="ExecutableDescriptor, MethodDescriptor and ConstructorDescriptor" level="2">
        <!-- 7.7 - CONSTRAINTMETADATA_EXECUTABLEDESCRIPTOR -->
        <assertion id="a">
            <text>getName() returns the name of the represented method (e.g. "placeOrder") respectively the non-qualified name of the declaring class of the represented constructor (e.g. "OrderService").</text>
        </assertion>
        <assertion id="b">
            <text>getParameterDescriptors() returns a list of ParameterDescriptors representing the method's or constructor's parameters in order of their declaration, including synthetic parameters. An empty list will be returned in case the method or constructor has no parameters.</text>
        </assertion>
        <assertion id="c">
            <text>getCrossParameterDescriptor() returns a descriptor containing cross-parameter constraints of the method or constructor. If no cross-parameter constraint is present, the descriptor will return an empty set of constraint descriptors.</text>
        </assertion>
        <assertion id="d">
            <text>getReturnValueDescriptor() returns a descriptor for the method's or constructor's return value. A descriptor representing the special class void, without any constraint descriptors, will be returned for executables which have no return value.</text>
        </assertion>
        <assertion id="e">
            <text>hasConstrainedParameters() returns true if any of the parameters is constrained or cascaded or if the represented executable has at least one cross-parameter constraint. Returns false if there is no parameter.</text>
        </assertion>
        <assertion id="f">
            <text>hasConstrainedReturnValue() returns true if the return value is constrained or cascaded. Returns false if there is no return value.</text>
        </assertion>
        <assertion id="g">
            <text>The methods hasConstraints(), getConstraintDescriptors() and findConstraints() defined on ElementDescriptor are redefined to clarify that executables do not host constraints directly and thus will always return false or an empty set of constraints, respectively. Constraint descriptors for individual parameters can be obtained from the corresponding ParameterDescriptor object, constraint descriptors for cross-parameter constraints can be obtained from the corresponding CrossParameterDescriptor object and constraint descriptors for the return value can be obtained from ReturnValueDescriptor.</text>
        </assertion>
        <assertion id="h">
            <text>None of the metadata API methods honor the XML configuration around executable validation nor the presence of @ValidateOnExecution. In other words, all constrained methods and constructors will be returned by the metadata API regardless of these settings.</text>
        </assertion>
    </section>
    <section id="constraintmetadata-parameterdescriptor" title="ParameterDescriptor" level="2">
        <!-- 7.8 - CONSTRAINTMETADATA_PARAMETERDESCRIPTOR -->
        <assertion id="a">
            <text>getIndex() returns the index of the represented parameter within the parameter array of the method or constructor holding it.</text>
        </assertion>
        <assertion id="b">
            <text>getName() returns the name of the represented parameter.</text>
        </assertion>
    </section>
    <section id="constraintmetadata-crossparameterdescriptor" title="CrossParameterDescriptor" level="2">
        <!-- 7.9 - CONSTRAINTMETADATA_CROSSPARAMETERDESCRIPTOR -->
        <assertion id="a">
            <text>getElementClass() returns Object[].</text>
        </assertion>
    </section>
    <section id="constraintmetadata-returnvaluedescriptor" title="ReturnValueDescriptor" level="2">
        <!-- 7.10 - CONSTRAINTMETADATA_RETURNVALUEDESCRIPTOR -->
    </section>
    <section id="constraintmetadata-containerdescriptor" title="ContainerDescriptor and ContainerElementTypeDescriptor" level="2">
        <!-- 7.11 - CONSTRAINTMETADATA_CONTAINERDESCRIPTOR -->
        <assertion id="a">
            <text>If a given element is of a container type, getConstrainedContainerElementTypes() returns a set with descriptors representing those container element types that either host at least one constraint or are marked with @Valid.</text>
        </assertion>
        <assertion id="b">
            <text>The returned set will be empty if the given element is not of a container type or is of a container type but has no element types that are constrained or marked with @Valid.</text>
        </assertion>
        <assertion id="c">
            <text>The ContainerElementTypeDescriptor interface describes the potential container element constraints applied to one element type of a container.</text>
        </assertion>
        <assertion id="d">
            <text>getTypeArgumentIndex() returns the index of the type argument corresponding to this descriptor instance.</text>
        </assertion>
        <assertion id="e">
            <text>getContainerClass() returns the type of the container declaring the container element type represented by this descriptor instance.</text>
        </assertion>
    </section>
    <section id="constraintmetadata-constraintdescriptor" title="ConstraintDescriptor" level="2">
        <!-- 7.12 - CONSTRAINTMETADATA_CONSTRAINTDESCRIPTOR -->
        <assertion id="a">
            <text>getAnnotation() returns the annotation instance (or an annotation instance representing the given constraint declaration).</text>
        </assertion>
        <assertion id="b">
            <text>If ConstraintDescriptor represents a composing annotation (see 3.3), the returned annotation must reflect parameter overriding.</text>
        </assertion>
        <assertion id="c">
            <text>getAttributes() returns a map containing the annotation attribute names as a key, and the annotation attribute values as a value</text>
        </assertion>
        <assertion id="d">
            <text>If ConstraintDescriptor() represents a composing annotation (see 3.3), the returned Map must reflect attribute overriding.</text>
        </assertion>
        <assertion id="e">
            <text>getMessageTemplate() returns the non-interpolated error message.</text>
        </assertion>
        <assertion id="f">
            <text>getGroups() returns the groups the constraint is supposed to be applied upon.</text>
        </assertion>
        <assertion id="g">
            <text>If no group is set on the constraint declaration, the Default group is returned.</text>
        </assertion>
        <assertion id="h">
            <text>The groups of a composing constraint are the groups of the composed constraint.</text>
        </assertion>
        <assertion id="i">
            <text>getPayload() returns the payloads associated to the constraint or an empty set if none.</text>
        </assertion>
        <assertion id="j">
            <text>The payload from the main constraint annotation is inherited by the composing annotations.</text>
        </assertion>
        <assertion id="k">
            <text>Any payload definition on a composing annotation is ignored.</text>
        </assertion>
        <assertion id="l">
            <text>getValidationAppliesTo() returns the ConstraintTarget returned by validationAppliesTo if the constraint hosts the attribute or null otherwise. The constraint target from the main constraint annotation is inherited by the composing annotation. Any constraint target definition on a composing annotation is ignored.</text>
        </assertion>
        <assertion id="m">
            <text>isReportAsSingleViolation() returns true if the constraint is annotated with @ReportAsSingleViolation.</text>
        </assertion>
        <assertion id="n">
            <text>getComposingConstraints() return a set of composing ConstraintDescriptors where each descriptor describes a composing constraint.</text>
        </assertion>
        <assertion id="o">
            <text>getConstraintValidatorClasses() returns the ConstraintValidator classes associated with the constraint.</text>
        </assertion>
        <assertion id="p">
            <text>getValueUnwrapping() returns a ValidateUnwrappedValue instance describing the unwrapping behavior.</text>
        </assertion>
    </section>
    <section id="constraintmetadata-example" title="Example" level="2">
        <!-- 7.13 - CONSTRAINTMETADATA_EXAMPLE -->
    </section>
    <section id="builtinconstraints" title="Built-in Constraint definitions" level="1">
        <!-- 8 - BUILTINCONSTRAINTS -->
        <assertion id="a">
            <text>Each Jakarta Bean Validation provider must recognize built-in constraint annotations as valid constraint definitions and provide compliant constraint implementations for each.</text>
        </assertion>
        <assertion id="b">
            <text>The built-in constraint validation implementation is having a lower priority than an XML mapping definition.</text>
        </assertion>
    </section>
    <section id="builtinconstraints-null" title="@Null constraint" level="2">
        <!-- 8.1 - BUILTINCONSTRAINTS_NULL -->
        <assertion id="a">
            <text>@Null constraint</text>
        </assertion>
    </section>
    <section id="builtinconstraints-notnull" title="@NotNull constraint" level="2">
        <!-- 8.2 - BUILTINCONSTRAINTS_NOTNULL -->
        <assertion id="a">
            <text>@NotNull constraint</text>
        </assertion>
    </section>
    <section id="builtinconstraints-asserttrue" title="@AssertTrue constraint" level="2">
        <!-- 8.3 - BUILTINCONSTRAINTS_ASSERTTRUE -->
        <assertion id="a">
            <text>@AssertTrue constraint</text>
        </assertion>
    </section>
    <section id="builtinconstraints-assertfalse" title="@AssertFalse constraint" level="2">
        <!-- 8.4 - BUILTINCONSTRAINTS_ASSERTFALSE -->
        <assertion id="a">
            <text>@AssertFalse constraint</text>
        </assertion>
    </section>
    <section id="builtinconstraints-min" title="@Min constraint" level="2">
        <!-- 8.5 - BUILTINCONSTRAINTS_MIN -->
        <assertion id="a">
            <text>@Min constraint</text>
        </assertion>
    </section>
    <section id="builtinconstraints-max" title="@Max constraint" level="2">
        <!-- 8.6 - BUILTINCONSTRAINTS_MAX -->
        <assertion id="a">
            <text>@Max constraint</text>
        </assertion>
    </section>
    <section id="builtinconstraints-decimalmin" title="@DecimalMin constraint" level="2">
        <!-- 8.7 - BUILTINCONSTRAINTS_DECIMALMIN -->
        <assertion id="a">
            <text>@DecimalMin constraint</text>
        </assertion>
    </section>
    <section id="builtinconstraints-decimalmax" title="@DecimalMax constraint" level="2">
        <!-- 8.8 - BUILTINCONSTRAINTS_DECIMALMAX -->
        <assertion id="a">
            <text>@DecimalMax constraint</text>
        </assertion>
    </section>
    <section id="builtinconstraints-negative" title="@Negative constraint" level="2">
        <!-- 8.9 - BUILTINCONSTRAINTS_NEGATIVE -->
        <assertion id="a">
            <text>@Negative constraint</text>
        </assertion>
    </section>
    <section id="builtinconstraints-negativeorzero" title="@NegativeOrZero constraint" level="2">
        <!-- 8.10 - BUILTINCONSTRAINTS_NEGATIVEORZERO -->
        <assertion id="a">
            <text>@NegativeOrZero constraint</text>
        </assertion>
    </section>
    <section id="builtinconstraints-positive" title="@Positive constraint" level="2">
        <!-- 8.11 - BUILTINCONSTRAINTS_POSITIVE -->
        <assertion id="a">
            <text>@Positive constraint</text>
        </assertion>
    </section>
    <section id="builtinconstraints-positiveorzero" title="@PositiveOrZero constraint" level="2">
        <!-- 8.12 - BUILTINCONSTRAINTS_POSITIVEORZERO -->
        <assertion id="a">
            <text>@PositiveOrZero constraint</text>
        </assertion>
    </section>
    <section id="builtinconstraints-size" title="@Size constraint" level="2">
        <!-- 8.13 - BUILTINCONSTRAINTS_SIZE -->
        <assertion id="a">
            <text>@Size constraint</text>
        </assertion>
    </section>
    <section id="builtinconstraints-digits" title="@Digits constraint" level="2">
        <!-- 8.14 - BUILTINCONSTRAINTS_DIGITS -->
        <assertion id="a">
            <text>@Digits constraint</text>
        </assertion>
    </section>
    <section id="builtinconstraints-past" title="@Past constraint" level="2">
        <!-- 8.15 - BUILTINCONSTRAINTS_PAST -->
        <assertion id="a">
            <text>@Past constraint</text>
        </assertion>
    </section>
    <section id="builtinconstraints-pastorpresent" title="@PastOrPresent constraint" level="2">
        <!-- 8.16 - BUILTINCONSTRAINTS_PASTORPRESENT -->
        <assertion id="a">
            <text>@PastOrPresent constraint</text>
        </assertion>
    </section>
    <section id="builtinconstraints-future" title="@Future constraint" level="2">
        <!-- 8.17 - BUILTINCONSTRAINTS_FUTURE -->
        <assertion id="a">
            <text>@Future constraint</text>
        </assertion>
    </section>
    <section id="builtinconstraints-futureorpresent" title="@FutureOrPresent constraint" level="2">
        <!-- 8.18 - BUILTINCONSTRAINTS_FUTUREORPRESENT -->
        <assertion id="a">
            <text>@FutureOrPresent constraint</text>
        </assertion>
    </section>
    <section id="builtinconstraints-pattern" title="@Pattern constraint" level="2">
        <!-- 8.19 - BUILTINCONSTRAINTS_PATTERN -->
        <assertion id="a">
            <text>@Pattern constraint</text>
        </assertion>
    </section>
    <section id="builtinconstraints-notempty" title="@NotEmpty constraint" level="2">
        <!-- 8.20 - BUILTINCONSTRAINTS_NOTEMPTY -->
        <assertion id="a">
            <text>@NotEmpty constraint</text>
        </assertion>
    </section>
    <section id="builtinconstraints-notblank" title="@NotBlank constraint" level="2">
        <!-- 8.21 - BUILTINCONSTRAINTS_NOTBLANK -->
        <assertion id="a">
            <text>@NotBlank constraint</text>
        </assertion>
    </section>
    <section id="builtinconstraints-email" title="@Email constraint" level="2">
        <!-- 8.22 - BUILTINCONSTRAINTS_EMAIL -->
        <assertion id="a">
            <text>@Email constraint</text>
        </assertion>
    </section>
    <section id="xml" title="XML deployment descriptor" level="1">
        <!-- 9 - XML -->
        <assertion id="a">
            <text>If an XML descriptor does not validate against the corresponding XSD file, a ValidationException is raised.</text>
        </assertion>
    </section>
    <section id="xml-mapping" title="Constraint definition and declaration" level="2">
        <!-- 9.1 - XML_MAPPING -->
        <assertion id="a">
            <text>Specifically when exploring metadata, the Jakarta Bean Validation provider must ensure that an annotation instance corresponding to the XML declaration is provided via ConstraintDescriptor.getAnnnotation().</text>
        </assertion>
        <assertion id="b">
            <text>A given class must not be described more than once among all the XML mapping descriptors.</text>
        </assertion>
        <assertion id="c">
            <text>A given field or getter must not be described more than once on a given class description.</text>
        </assertion>
        <assertion id="d">
            <text>A given constraint definition must not be overridden more than once among all the XML mapping descriptors.</text>
        </assertion>
        <assertion id="e">
            <text>If any of these rules is violated in a given validation deployment, a ValidationException is raised during the creation of the ValidatorFactory.</text>
        </assertion>
    </section>
    <section id="xml-mapping-constraintdeclarationinxml" title="Constraint declaration in XML" level="3">
        <!-- 9.1.1 - XML_MAPPING_CONSTRAINTDECLARATIONINXML -->
        <assertion id="a">
            <text>If default-package is set, all unqualified class names (including annotations) are considered part of the package described by default-package.</text>
        </assertion>
        <assertion id="b">
            <text>A given JavaBean is described by the bean element.</text>
        </assertion>
        <assertion id="c">
            <text>The name of the class is mandatory.</text>
        </assertion>
        <assertion id="d">
            <text>By default, all constraint declarations expressed via annotations are ignored for classes described in XML.</text>
        </assertion>
        <assertion id="e">
            <text>You can force Jakarta Bean Validation to consider both annotations and XML constraint declarations by using ignore-annotations="false" on bean.</text>
        </assertion>
        <assertion id="f">
            <text>If the name of the class does refer to a class not present in the classpath, a ValidationException is raised.</text>
        </assertion>
    </section>
    <section id="xml-mapping-constraintdeclarationinxml-classleveloverriding" title="Class-level overriding" level="4">
        <!-- 9.1.1.1 - XML_MAPPING_CONSTRAINTDECLARATIONINXML_CLASSLEVELOVERRIDING -->
        <assertion id="a">
            <text>If ignore-annotations is declared, Jakarta Bean Validation must honor the explicit value for this element.</text>
        </assertion>
        <assertion id="b">
            <text>If not declared, the default value defined in the encapsulating bean element is considered.</text>
        </assertion>
        <assertion id="c">
            <text>When ignore-annotations is true, class-level Jakarta Bean Validation annotations are ignored for this class (including the @GroupSequence).</text>
        </assertion>
        <assertion id="d">
            <text>Constraints declared in XML and constraints declared in annotations are added and form the list of class-level declared constraints.</text>
        </assertion>
        <assertion id="e">
            <text>@GroupSequence is considered unless group-sequence element is explicitly used.</text>
        </assertion>
    </section>
    <section id="xml-mapping-constraintdeclarationinxml-fieldleveloverriding" title="Field-level overriding" level="4">
        <!-- 9.1.1.2 - XML_MAPPING_CONSTRAINTDECLARATIONINXML_FIELDLEVELOVERRIDING -->
        <assertion id="a">
            <text>If ignore-annotations is declared, Jakarta Bean Validation must honor the explicit value for this element.</text>
        </assertion>
        <assertion id="b">
            <text>If not declared, the default value defined in the encapsulating bean element is considered.</text>
        </assertion>
        <assertion id="c">
            <text>When ignore-annotations is true, field-level Jakarta Bean Validation annotations on the targeted field are ignored (including @Valid and @ConvertGroup).</text>
        </assertion>
        <assertion id="d">
            <text>Constraints declared in XML and constraints declared in annotations are added and form the list of field-level declared constraints.</text>
        </assertion>
        <assertion id="e">
            <text>@Valid is considered unless the valid element is explicitly used.</text>
        </assertion>
        <assertion id="f">
            <text>Group conversions declared in XML and via the @ConvertGroup annotation are added and form the list of applied conversions. Note that the rules for the declaration of group conversions as outlined in 5.4.5 apply, in particular it is not legal to declare several conversions for the same source group.</text>
        </assertion>
        <assertion id="g">
            <text>If the name of the field does not correspond to a field in the given bean a ValidationException is raised.</text>
        </assertion>
    </section>
    <section id="xml-mapping-constraintdeclarationinxml-propertyleveloverriding" title="Property-level overriding" level="4">
        <!-- 9.1.1.3 - XML_MAPPING_CONSTRAINTDECLARATIONINXML_PROPERTYLEVELOVERRIDING -->
        <assertion id="a">
            <text>The name attribute corresponds to the name of the property considered as defined in 5.1.2 (for example a getter String getAge() would have &lt;getter name="age"/&gt; as a corresponding descriptor). If ignore-annotations is declared, Jakarta Bean Validation must honor the explicit value for this element.</text>
        </assertion>
        <assertion id="b">
            <text>If not declared, the default value defined in the encapsulating bean element is considered.</text>
        </assertion>
        <assertion id="c">
            <text>When ignore-annotations is true, property-level Jakarta Bean Validation annotations on the targeted property are ignored (including @Valid and @ConvertGroup).</text>
        </assertion>
        <assertion id="d">
            <text>Constraints declared in XML and constraints declared in annotations are added and form the list of property-level declared constraints.</text>
        </assertion>
        <assertion id="e">
            <text>@Valid is considered unless the valid element is explicitly used.</text>
        </assertion>
        <assertion id="f">
            <text>Group conversions declared in XML and via the @ConvertGroup annotation are added and form the list of applied conversions. Note that the rules for the declaration of group conversions as outlined in 5.4.5 apply, in particular it is not legal to declare several conversions for the same source group.</text>
        </assertion>
        <assertion id="g">
            <text>If the name of the property does not correspond to a property in the given bean a ValidationException is raised.</text>
        </assertion>
    </section>
    <section id="xml-mapping-constraintdeclarationinxml-constructorleveloverriding" title="Constructor-level overriding" level="4">
        <!-- 9.1.1.4 - XML_MAPPING_CONSTRAINTDECLARATIONINXML_CONSTRUCTORLEVELOVERRIDING -->
        <assertion id="a">
            <text>To identify a constructor to be configured, zero or more parameter elements are used, matching the number and types of parameters of the configured constructor. When configuring the default constructor, no parameter element is to be used. The parameter types are specified using their fully qualified name using the syntax described in the documentation of java.lang.Class.getName().</text>
        </assertion>
        <assertion id="b">
            <text>Varargs parameters are specified using the corresponding array type, e.g. a parameter String... must be specified as "[Ljava.lang.String;".</text>
        </assertion>
        <assertion id="c">
            <text>If the default-package element is configured for the mapping file, any unqualified class names will be resolved using the given default package.</text>
        </assertion>
        <assertion id="d">
            <text>If no constructor with the specified parameter types exists in the given bean a ValidationException is raised.</text>
        </assertion>
        <assertion id="e">
            <text>The optional return-value element is used to change the configuration of a constructor's return value if required.</text>
        </assertion>
        <assertion id="f">
            <text>The optional cross-parameter element is used to change the configuration of a constructor's cross-parameter constraints if required.</text>
        </assertion>
        <assertion id="g">
            <text>The constraints applying for a constructor's parameters and its return value are specified by adding constraint elements to the parameter and return-value elements respectively.</text>
        </assertion>
        <assertion id="h">
            <text>Whether or not to perform cascaded validation is controlled using the valid element</text>
        </assertion>
        <assertion id="i">
            <text>Group conversion rules for cascaded validation are specified using the convert-group element.</text>
        </assertion>
        <assertion id="j">
            <text>The cross-parameter constraints applied on a constructor parameter list are specified by adding constraint elements to the cross-parameter element.</text>
        </assertion>
        <assertion id="k">
            <text>If ignore-annotations is declared on the parameter, cross-parameter or return-value element, Jakarta Bean Validation must honor the explicit value for this element. Otherwise, if ignore-annotations is declared for the constructor element, Jakarta Bean Validation must honor this value. Otherwise, the default value declared in the encapsulating bean element is considered.</text>
        </assertion>
        <assertion id="l">
            <text>When ignore-annotations is true, Jakarta Bean Validation annotations on the targeted constructor or parameter are ignored (including @Valid and @ConvertGroup).</text>
        </assertion>
        <assertion id="m">
            <text>Constraints declared in XML and constraints declared in annotations are added and form the list of declared parameter, cross-parameter or return value constraints respectively.</text>
        </assertion>
        <assertion id="n">
            <text>@Valid is considered unless the valid element is explicitly used.</text>
        </assertion>
        <assertion id="o">
            <text>Group conversions declared in XML and via the @ConvertGroup annotation are added and form the list of applied conversions. Note that the rules for the declaration of group conversions as outlined in 5.4.5 apply, in particular it is not legal to declare several conversions for the same source group. This does not apply to cross-parameter elements as cascading does not make sense in this situation.</text>
        </assertion>
    </section>
    <section id="xml-mapping-constraintdeclarationinxml-methodleveloverriding" title="Method-level overriding" level="4">
        <!-- 9.1.1.5 - XML_MAPPING_CONSTRAINTDECLARATIONINXML_METHODLEVELOVERRIDING -->
        <assertion id="a">
            <text>To identify a method to be configured, zero or more parameter elements are used, matching the number and types of parameters of the configured method. The parameter types are specified using their fully qualified name using the syntax described in the documentation of java.lang.Class.getName().</text>
        </assertion>
        <assertion id="b">
            <text>Varargs parameters are specified using the corresponding array type, e.g. a parameter String... must be specified as "[Ljava.lang.String;".</text>
        </assertion>
        <assertion id="c">
            <text>If the default-package element is configured for the mapping file, any unqualified class names will be resolved using the given default package.</text>
        </assertion>
        <assertion id="d">
            <text>A given getter method representing a JavaBeans property may either be configured using the getter or the method element, but not both. If a getter element and a method element referring to the same method are detected by the Jakarta Bean Validation provider, a ValidationException is raised.</text>
        </assertion>
        <assertion id="e">
            <text>If no method with the specified name and parameter types exists in the given bean a ValidationException is raised.</text>
        </assertion>
        <assertion id="f">
            <text>The optional return-value element is used to change the configuration of a method's return value if required.</text>
        </assertion>
        <assertion id="g">
            <text>The optional cross-parameter element is used to change the configuration of a method's cross-parameter constraints if required.</text>
        </assertion>
        <assertion id="h">
            <text>The constraints applying for a method's parameters and its return value are specified by adding constraint elements to the parameter and return-value elements respectively.</text>
        </assertion>
        <assertion id="i">
            <text>Whether or not to perform cascaded validation is controlled using the valid element.</text>
        </assertion>
        <assertion id="j">
            <text>Group conversion rules for cascaded validation are specified using the convert-group element.</text>
        </assertion>
        <assertion id="k">
            <text>The cross-parameter constraints applied on a method parameter list are specified by adding constraint elements to the cross-parameter element.</text>
        </assertion>
        <assertion id="l">
            <text>If ignore-annotations is declared on the parameter, cross-parameter or return-value element, Jakarta Bean Validation must honor the explicit value for this element. Otherwise, if ignore-annotations is declared for the method element, Jakarta Bean Validation must honor this value. Otherwise, the default value declared in the encapsulating bean element is considered.</text>
        </assertion>
        <assertion id="m">
            <text>When ignore-annotations is true, Jakarta Bean Validation annotations on the targeted method or parameter are ignored (including @Valid and @ConvertGroup).</text>
        </assertion>
        <assertion id="n">
            <text>Constraints declared in XML and constraints declared in annotations are added and form the list of declared parameter, cross-parameter or return value constraints respectively.</text>
        </assertion>
        <assertion id="o">
            <text>@Valid is considered unless the valid element is explicitly used.</text>
        </assertion>
        <assertion id="p">
            <text>Group conversions declared in XML and via the @ConvertGroup annotation are added and form the list of applied conversions. Note that the rules for the declaration of group conversions as outlined in 5.4.5 apply, in particular it is not legal to declare several conversions for the same source group. This does not apply to cross-parameter elements as cascading does not make sense in this situation.</text>
        </assertion>
    </section>
    <section id="xml-mapping-constraintdeclarationinxml-containerelementconstraints" title="Container-element overriding" level="4">
        <!-- 9.1.1.6 - XML_MAPPING_CONSTRAINTDECLARATIONINXML_CONTAINERELEMENTCONSTRAINTS -->
        <assertion id="a">
            <text>To apply constraints to the elements of generic container types or to mark them for cascaded validation, the container-element-type element is used.</text>
        </assertion>
        <assertion id="b">
            <text>container-element-type can be used within the field, getter, parameter and return-value elements.</text>
        </assertion>
        <assertion id="c">
            <text>The type-argument-index is used to specify the index of the configured type argument.</text>
        </assertion>
        <assertion id="d">
            <text>The type-argument-index can be omitted, if the container type has exactly one type argument.</text>
        </assertion>
        <assertion id="e">
            <text>The ignore-annotations settings effectively applying to the encapsulating element (field, getter etc.) are applied to container-element-type, too.</text>
        </assertion>
        <assertion id="f">
            <text>The container-element-type element can be nested for configuring nested generic containers such as List&lt;List&lt;String&gt;&gt;.</text>
        </assertion>
        <assertion id="g">
            <text>Constraints are applied by adding constraint elements to container-element-type.</text>
        </assertion>
        <assertion id="h">
            <text>Whether or not to perform cascaded validation is controlled using the valid element.</text>
        </assertion>
        <assertion id="i">
            <text>Group conversion rules for cascaded validation are specified using the convert-group element.</text>
        </assertion>
        <assertion id="j">
            <text>The type of the surrounding element (field, getter etc.) has no type arguments.</text>
        </assertion>
        <assertion id="k">
            <text>The type of the surrounding element has no type argument with the index given via type-argument-index.</text>
        </assertion>
        <assertion id="l">
            <text>The type of the surrounding element has multiple type arguments and no index is given via type-argument-index.</text>
        </assertion>
        <assertion id="m">
            <text>The same type argument of the surrounding element is configured multiple times.</text>
        </assertion>
    </section>
    <section id="xml-mapping-constraintdeclarationinxml-constraintdeclaration" title="Constraint declaration" level="4">
        <!-- 9.1.1.7 - XML_MAPPING_CONSTRAINTDECLARATIONINXML_CONSTRAINTDECLARATION -->
        <assertion id="a">
            <text>The annotation attribute is the class name of the annotation representing the constraint. Message, groups and payload are defined respectively by the message, groups and payload elements.</text>
        </assertion>
        <assertion id="b">
            <text>The name attribute is mandatory and represents the name of the element in the constraint declaration.</text>
        </assertion>
        <assertion id="c">
            <text>Message, groups and payload are not permitted names, use the message, groups or payload elements instead. Otherwise a ValidationException is raised.</text>
        </assertion>
        <assertion id="d">
            <text>If the element represents a primitive type, a class or an enum, the string representation of its value is placed in the element itself.</text>
        </assertion>
        <assertion id="e">
            <text>If the element represents a primitive type array, a class array or an enum array, the string representation of each value is placed in a value element placed under the element itself.</text>
        </assertion>
        <assertion id="f">
            <text>If the element represents an annotation, the annotation element is used to represent the annotation and placed under element.</text>
        </assertion>
        <assertion id="g">
            <text>If the element represents an array of annotations, one or more annotation elements are placed under element.</text>
        </assertion>
        <assertion id="h">
            <text>Elements with default values in the annotation definition do not have to be represented in XML: the default value will be used in this case.</text>
        </assertion>
        <assertion id="i">
            <text>If an XML constraint declaration is missing mandatory elements, or if it contains elements not part of the constraint definition, a ValidationException is raised.</text>
        </assertion>
    </section>
    <section id="xml-mapping-constraintdeclarationinxml-groupconversions" title="Declaration of group conversions" level="4">
        <!-- 9.1.1.8 - XML_MAPPING_CONSTRAINTDECLARATIONINXML_GROUPCONVERSIONS -->
        <assertion id="a">
            <text>Group conversion rules are declared by specifying one or more convert-group elements within the field, getter, parameter, return-value and container-element-type elements.</text>
        </assertion>
        <assertion id="b">
            <text>Source and target group of a conversion rule are given by specifying their fully-qualified names within the from and to attribute respectively. If the default-package element is configured for the mapping file, any unqualified class names will be resolved using the given default package.</text>
        </assertion>
    </section>
    <section id="xml-mapping-constraintdefinition" title="Overriding constraint definitions in XML" level="3">
        <!-- 9.1.2 - XML_MAPPING_CONSTRAINTDEFINITION -->
        <assertion id="a">
            <text>A constraint definition is represented by a constraint-definition element.</text>
        </assertion>
        <assertion id="b">
            <text>If include-existing-validator is set to false, ConstraintValidator defined on the constraint annotation are ignored.</text>
        </assertion>
        <assertion id="c">
            <text>If set to true, the list of ConstraintValidators described in XML are concatenated to the list of ConstraintValidator described on the annotation to form a new array of ConstraintValidator evaluated.</text>
        </assertion>
        <assertion id="d">
            <text>Annotation based ConstraintValidators come before XML based ConstraintValidators in the array.</text>
        </assertion>
        <assertion id="e">
            <text>The new list is returned by ConstraintDescriptor.getConstraintValidatorClasses().</text>
        </assertion>
    </section>
    <section id="xml-mapping-typeconversion" title="Converting the string representation of a value" level="3">
        <!-- 9.1.3 - XML_MAPPING_TYPECONVERSION -->
        <assertion id="a">
            <text>Primitive types, Class and Enum are represented as strings in the XML descriptor. Elements of an array are represented by the value element.</text>
        </assertion>
        <assertion id="b">
            <text>A byte is represented according to the rules defined in Byte.parseByte(String).</text>
        </assertion>
        <assertion id="c">
            <text>A short is represented according to the rules defined in Short.parseShort(String).</text>
        </assertion>
        <assertion id="d">
            <text>An int is represented according to the rules defined in Integer.parseInt(String).</text>
        </assertion>
        <assertion id="e">
            <text>A long is represented according to the rules defined in Long.parseLong(String).</text>
        </assertion>
        <assertion id="f">
            <text>A float is represented according to the rules defined in Float.parseFloat(String).</text>
        </assertion>
        <assertion id="g">
            <text>A double is represented according to the rules defined in Double.parseDouble(String).</text>
        </assertion>
        <assertion id="h">
            <text>A boolean is represented according to the rules defined in Boolean.parseBoolean(String).</text>
        </assertion>
        <assertion id="i">
            <text>A char is represented according to the following rules: the string must be of one character long the character extracted from the string is the returned char</text>
        </assertion>
        <assertion id="j">
            <text>A Class is represented by the fully qualified class name of the class or more precisely according to the syntax described in the documentation of java.lang.Class.getName(). Note that if the raw string is unqualified, default package is taken into account.</text>
        </assertion>
        <assertion id="k">
            <text>An enum is represented by its enum.name() value.</text>
        </assertion>
        <assertion id="l">
            <text>If any of the string representation does not match its type counterpart, a ValidationException is raised.</text>
        </assertion>
    </section>
    <section id="xml-mapping-xsd" title="XML Schema" level="3">
        <!-- 9.1.4 - XML_MAPPING_XSD -->
        <assertion id="a">
            <text>Implementations supporting Jakarta Bean Validation 2.0 must properly parse mapping descriptors of Jakarta Bean Validation 1.0, 1.1 and 2.0.</text>
        </assertion>
        <assertion id="b" testable="false">
            <text>If the version attribute attribute is not given, schema version 1.0 is to be assumed by the Jakarta Bean Validation provider.</text>
        </assertion>
        <assertion id="c">
            <text>In case an unknown version is given (e.g. if a mapping descriptor adhering to a future schema version is parsed by a Jakarta Bean Validation 2.0 provider) a ValidationException is raised.</text>
        </assertion>
    </section>
    <section id="xml-config-xsd" title="Configuration schema" level="2">
        <!-- 9.2 - XML_CONFIG_XSD -->
        <assertion id="a">
            <text>Implementations supporting Jakarta Bean Validation 2.0 must properly parse configuration descriptors of Jakarta Bean Validation 1.0, 1.1 and 2.0.</text>
        </assertion>
        <assertion id="b" testable="false">
            <text>If the version attribute attribute is not given, schema version 1.0 is to be assumed by the Jakarta Bean Validation Provider.</text>
        </assertion>
        <assertion id="c">
            <text>In case an unknown version is given a ValidationException is raised.</text>
        </assertion>
    </section>
    <section id="exception" title="Exception model" level="1">
        <!-- 10 - EXCEPTION -->
        <assertion id="a">
            <text>Every (runtime) exception raised either at initialization time or execution time by any of the extension interfaces (ConstraintValidator, ConstraintValidatorFactory, MessageInterpolator, TraversableResolver, ValidationProviderResolver, ParameterNameProvider, ClockProvider, ValueExtractor) is wrapped in a ValidationException.</text>
        </assertion>
    </section>
    <section id="exception-errorreport" title="Error report: ConstraintViolationException" level="2">
        <!-- 10.1 - EXCEPTION_ERRORREPORT -->
    </section>
    <section id="exception-constraintdefinition" title="Constraint definition: ConstraintDefinitionException" level="2">
        <!-- 10.2 - EXCEPTION_CONSTRAINTDEFINITION -->
        <assertion id="a">
            <text>If a constraint definition does not respect the Jakarta Bean Validation rules or is inconsistent, a ConstraintDefinitionException is raised.</text>
        </assertion>
    </section>
    <section id="exception-constraintdeclaration" title="Constraint declaration: ConstraintDeclarationException and UnexpectedTypeException" level="2">
        <!-- 10.3 - EXCEPTION_CONSTRAINTDECLARATION -->
        <assertion id="a" testable="false">
            <text>When a constraint declaration is illegal, ConstraintDeclarationException is raised.</text>
        </assertion>
        <assertion id="b">
            <text>When the return type of a property cannot be processed for a given constraint, an UnexpectedTypeException is raised.</text>
        </assertion>
    </section>
    <section id="exception-groupdefinition" title="Group definition: GroupDefinitionException" level="2">
        <!-- 10.4 - EXCEPTION_GROUPDEFINITION -->
        <assertion id="a">
            <text>When a group definition is illegal, a GroupDefinitionException is raised.</text>
        </assertion>
    </section>
    <section id="exception-valueextractordefinition" title="Value extractor definition: ValueExtractorDefinitionException" level="2">
        <!-- 10.5 - EXCEPTION_VALUEEXTRACTORDEFINITION -->
        <assertion id="a">
            <text>When detecting an illegal value extractor definition, a ValueExtractorDefinitionException will be raised.</text>
        </assertion>
    </section>
    <section id="exception-valueextractordeclaration" title="Value extractor declaration: ValueExtractorDeclarationException" level="2">
        <!-- 10.6 - EXCEPTION_VALUEEXTRACTORDECLARATION -->
        <assertion id="a">
            <text>When detecting an illegal configuration of value extractors, a ValueExtractorDeclarationException will be raised.</text>
        </assertion>
    </section>
    <section id="exception-noprovider" title="No Jakarta Bean Validation Provider detected: NoProviderFoundException" level="2">
        <!-- 10.7 - EXCEPTION_NOPROVIDER -->
        <assertion id="a" testable="false">
            <text>When trying to bootstrap Jakarta Bean Validation via Validation.buildDefaultValidatorFactory() or Validation.byDefaultProvider().configure() and no Jakarta Bean Validation provider could be found, a NoProviderFoundException is raised.</text>
        </assertion>
    </section>
    <section id="integration" title="Integration" level="1">
        <!-- 11 - INTEGRATION -->
    </section>
    <section id="integration-general" title="General requirements" level="2">
        <!-- 11.1 - INTEGRATION_GENERAL -->
    </section>
    <section id="integration-general-objectslifecycle" title="Objects lifecycle" level="3">
        <!-- 11.1.1 - INTEGRATION_GENERAL_OBJECTSLIFECYCLE -->
        <assertion id="a">
            <text>Build and bootstrap the ValidatorFactory instance for an application.</text>
        </assertion>
        <assertion id="b">
            <text>Provide access to the ValidatorFactory instance as well as Validator instances in their default configuration using the paradigm of the container: for example, such instances would be injectable in other objects via a dependency injection framework.</text>
        </assertion>
        <assertion id="c">
            <text>Configure ValidatorFactory with a custom ConstraintValidatorFactory instance that returns managed ConstraintValidator instances, unless a custom ConstraintValidatorFactory is requested by the user. The scope of ConstraintValidator instances is still fully controlled by the Jakarta Bean Validation provider as described in 3.5, but as managed beans they can receive expected services like injection of other objects.</text>
        </assertion>
        <assertion id="d">
            <text>Configure ValidatorFactory with managed instances of ConstraintValidatorFactory, MessageInterpolator, ParameterNameProvider, ClockProvider and TraversableResolver, if such instances are defined in the XML deployment descriptor. Services provided by the container (like dependency injection) should thus be available to these instances.</text>
        </assertion>
        <assertion id="e" testable="false">
            <text>Invoke ValidatorFactory.close() when the ValidatorFactory instance is no longer needed.</text>
        </assertion>
        <assertion id="f" testable="false">
            <text>Dispose of managed instances provided to the Jakarta Bean Validation bootstrap process after ValidatorFactory.close() has been invoked.</text>
        </assertion>
    </section>
    <section id="integration-general-executable" title="Method and constructor validation" level="3">
        <!-- 11.1.2 - INTEGRATION_GENERAL_EXECUTABLE -->
        <assertion id="a">
            <text>Method interception frameworks (such as AOP or interceptor frameworks) enable interception of constrained methods following the steps defined in 6.4.</text>
        </assertion>
        <assertion id="b">
            <text>Method validation execution is implicit for any method or constructor annotated with constraints.</text>
        </assertion>
        <assertion id="c">
            <text>By default, method validation is applied to all constrained methods or constructors provided the integration technology can intercept the call. By default, getters (as defined in 5.1) are not considered constrained methods.</text>
        </assertion>
        <assertion id="d" testable="false">
            <text>Static methods are ignored by validation. Putting constraints on a static method is not portable.</text>
        </assertion>
        <assertion id="e">
            <text>The executable is validated if it is annotated with @ValidateOnExecution and the type attribute contains the executable type or IMPLICIT. If the type attribute does neither contain the executable type nor IMPLICIT, the executable is not validated.</text>
            <note>Needs update</note>
        </assertion>
        <assertion id="f">
            <text>Otherwise the executable is validated if the type (class, interface) on which it is declared is annotated with @ValidateOnExecution and the type attribute contains the executable type. If the type attribute contains IMPLICIT, then this rule is ignored and the behavior is equivalent to @ValidateOnExecution not being present. If the type attribute does not contain the executable type, the executable is not validated.</text>
        </assertion>
        <assertion id="g">
            <text>Otherwise the executable is validated if the global executable validation setting contains the executable type. If the global setting does not contain the executable type, the executable is not validated.</text>
        </assertion>
        <assertion id="h">
            <text>The rules above do not apply to methods overriding a superclass method or implementing an interface method. In this case, the method inherits the behavior of the method it overrides / implements. Out of the box, a conforming integration implementation raises a ValidationException if the overriding / implementing method hosts the @ValidateOnExecution annotation.</text>
        </assertion>
        <assertion id="i">
            <text>NONE: parameters and return values are not validated upon execution. This option is equivalent to an empty list of executable types and is present to improve readability. A list containing NONE and other types of executables is equivalent to a list containing the types of executables without NONE.</text>
        </assertion>
        <assertion id="j">
            <text>CONSTRUCTORS: parameters and return values are validated provided the executable is a constructor.</text>
        </assertion>
        <assertion id="k">
            <text>NON_GETTER_METHODS: parameters and return values are validated provided the executable is a method but not a getter.</text>
        </assertion>
        <assertion id="l">
            <text>GETTER_METHODS: return values are validated provided the executable is a getter method.</text>
        </assertion>
        <assertion id="m">
            <text>ALL: parameters and return values are validated for all executables (getters, non getters and constructors). This option is equivalent to a list of all executable types and is present to improve readability. A list containing ALL and other types of executables is equivalent to a list containing only ALL.</text>
        </assertion>
        <assertion id="n">
            <text>IMPLICIT: if @ValidateOnExecution is on a type (class or interface), then it is equivalent to @ValidateOnExecution not being present; if @ValidateOnExecution is on a an executable, the following applies</text>
        </assertion>
        <assertion id="o" testable="false">
            <text>Mixing IMPLICIT and other executable types is illegal.</text>
        </assertion>
        <assertion id="p" testable="false">
            <text>If a sub type overrides/implements a method originally defined in several parallel types of the hierarchy (e.g. two interfaces not extending each other, or a class and an interface not implemented by said class), @ValidateOnExecution cannot be placed in the parallel types of the hierarchy.</text>
        </assertion>
        <assertion id="q">
            <text>You can globally disable executable validation by using &lt;executable-validation enabled="false"/&gt;, in this case, &lt;default-validated-executable-types/&gt; and @ValidateOnExecution are ignored.</text>
        </assertion>
    </section>
    <section id="integration-general-executable-examples" title="Examples" level="4">
        <!-- 11.1.2.1 - INTEGRATION_GENERAL_EXECUTABLE_EXAMPLES -->
    </section>
    <section id="integration-jakartaee" title="Jakarta EE" level="2">
        <!-- 11.2 - INTEGRATION_JAKARTAEE -->
        <assertion id="a">
            <text>Jakarta EE must obey the rules defined above and make the following instances available under JNDI: ValidatorFactory under java:comp/ValidatorFactory Validator under java:comp/Validator</text>
        </assertion>
        <assertion id="b">
            <text>Instead of looking the instances up via JNDI, the user can request them to be injected via the Resource annotation</text>
        </assertion>
        <assertion id="c">
            <text>When the application is Jakarta Context and Dependency Injection enabled, the ValidatorFactory and Validator instances returned by JNDI or @Resource injection are Jakarta Context and Dependency Injection enhanced as defined in 11.3.</text>
        </assertion>
    </section>
    <section id="integration-dependencyinjection" title="Jakarta Context and Dependency Injection integration" level="2">
        <!-- 11.3 - INTEGRATION_DEPENDENCYINJECTION -->
        <assertion id="a">
            <text>Jakarta Bean Validation provider must integrate with Jakarta Context and Dependency Injection.</text>
        </assertion>
    </section>
    <section id="integration-dependencyinjection-validatorfactory" title="ValidatorFactory and Validator" level="3">
        <!-- 11.3.1 - INTEGRATION_DEPENDENCYINJECTION_VALIDATORFACTORY -->
        <assertion id="a">
            <text>Similar to the Jakarta EE integration via @Resource (see 11.2), a Jakarta Context and Dependency Injection container must support injection of built-in default ValidatorFactory and Validator beans via @Inject. These default beans are injectable via the @Default qualifier.</text>
        </assertion>
    </section>
    <section id="integration-dependencyinjection-customconfiguration" title="ConstraintValidatorFactory, MessageInterpolator, ParameterNameProvider, ClockProvider, TraversableResolver and ValueExtractor" level="3">
        <!-- 11.3.2 - INTEGRATION_DEPENDENCYINJECTION_CUSTOMCONFIGURATION -->
        <assertion id="a">
            <text>If custom ConstraintValidatorFactory, MessageInterpolator, ParameterNameProvider, ClockProvider, TraversableResolver or ValueExtractor classes are defined in the XML deployment descriptor (see 6.5.6), the ValidatorFactory must be configured with Jakarta Context and Dependency Injection managed beans representing the requested classes. Services like dependency injection, interception and decoration must thus be made available to these instances by the container.</text>
        </assertion>
        <assertion id="b">
            <text>The same applies to value extractors discovered through the service loader mechanism (see 5.7.5.1).</text>
        </assertion>
        <assertion id="c">
            <text>If no custom ConstraintValidatorFactory is requested by the user, the ValidatorFactory must be configured with a custom ConstraintValidatorFactory instance that returns Jakarta Context and Dependency Injection managed beans representing the requested ConstraintValidator types. The factory creates non-contextual ConstraintValidator instances for each ConstraintValidatorFactory.getInstance() call. To inject dependencies into the ConstraintValidator instance, the Jakarta Context and Dependency Injection InjectionTarget API should be used. Before returning the instance the following calls should be made: InjectionTarget.produce(), InjectionTarget.inject() and InjectionTarget.postConstruct(). calls InjectionTarget.preDestroy() and InjectionTarget.dispose() upon ConstraintValidatorFactory.releaseInstance (see also 3.5 for more information about the lifecycle of a ConstraintValidator).</text>
        </assertion>
        <assertion id="d" testable="false">
            <text>Using directly or indirectly a Jakarta Persistence EntityManager that might call back Jakarta Bean Validation for validation is not allowed in the Jakarta Bean Validation extension points and in ConstraintValidator instances. This would lead to infinite flush or unexpected behavior.</text>
        </assertion>
    </section>
    <section id="integration-dependencyinjection-methodconstructorvalidation" title="Method and constructor validation" level="3">
        <!-- 11.3.3 - INTEGRATION_DEPENDENCYINJECTION_METHODCONSTRUCTORVALIDATION -->
        <assertion id="a">
            <text>Jakarta Bean Validation requires that Jakarta Context and Dependency Injection beans support constructor and method validation as defined in 11.1.2. Validation must happen at the equivalent time an interceptor occurs when having priority Interceptor.Priority.PLATFORM_AFTER+800, in other words priority of 4800.</text>
        </assertion>
        <assertion id="b" testable="false">
            <text>For maximum portability, it is recommended to mark Jakarta Context and Dependency Injection bean interfaces and classes involved in executable validation with @ValidateOnExecution (defaults to IMPLICIT). This helps some implementations to bind the method validation interceptor. Most Jakarta Context and Dependency Injection - Jakarta Bean Validation integration implementations do not need such marker. In particular this marker should not be needed on validated beans annotated with constraint annotations, @Valid or @ValidateOnExecution anywhere in the class. Such limitation will be removed in a future version of this specification.</text>
        </assertion>
    </section>
    <section id="integration-persistence" title="Jakarta Persistence 2.0 integration" level="2">
        <!-- 11.4 - INTEGRATION_PERSISTENCE -->
    </section>
    <section id="integration-faces" title="Jakarta Server Faces 2.0 integration" level="2">
        <!-- 11.5 - INTEGRATION_FACES -->
    </section>
    <section id="integration-restfulws" title="Jakarta RESTful Web Services 2 integration" level="2">
        <!-- 11.6 - INTEGRATION_RESTFULWS -->
    </section>
</specification>




© 2015 - 2024 Weber Informatics LLC | Privacy Policy