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

[[constraintmetadata]]

== Constraint metadata request APIs

The Bean Validation specification provides a way to query the constraint repository. This API is expected to be used for tooling support as well as integration with other frameworks, libraries and JSRs. The Bean Validation specification aims to provide both a validation engine and a metadata repository for object constraints. Frameworks (EE or SE) in need for constraint definition, validation and metadata will be able to rely on the Bean Validation specification for these services avoiding any unnecessary duplication work from an application and infrastructure point of view.

[[constraintmetadata-validator]]
=== Validator

The main API to access all metadata related to a given object is [classname]`Validator` (see <<validationapi-bootstrapping>> for more information on how to retrieve a [classname]`Validator` instance).

A [classname]`Validator` instance hosts the method to access to the metadata repository for a given class. It is recommended to leave the caching of [classname]`Validator` instances to the [classname]`ValidatorFactory`. [classname]`Validator` implementations are thread-safe.

.Validator interface (metadata request API)
====

[source, JAVA]
----
/**
 * Validates bean instances. Implementations of this interface must be thread-safe.
 *
 * @author <NAME>
 * @author <NAME>
 * @author <NAME>
 */
public interface Validator {

    [...] //See 5.1

    /**
     * Returns the descriptor object describing bean constraints.
     * <p/>
     * The returned object (and associated objects including
     * {@link ConstraintDescriptor}s) are immutable.
     *
     * @param clazz class or interface type evaluated
     * @return the bean descriptor for the specified class
     * @throws IllegalArgumentException if clazz is {@code null}
     * @throws ValidationException if a non recoverable error happens
     *         during the metadata discovery or if some
     *         constraints are invalid.
     */
    BeanDescriptor getConstraintsForClass(Class<?> clazz);
}
----

====

[tck-testable]#[methodname]`getConstraintsForClass()` returns a [classname]`BeanDescriptor` object describing the bean level constraints (see <<constraintdeclarationvalidationprocess-requirements-objectvalidation>>) and providing access to the property level constraints metadata.# [tck-testable]#An [classname]`IllegalArgumentException` is raised if the [varname]`clazz` parameter is null.#

[tck-testable]#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 [classname]`ValidationException` is raised.# This can be a subclass of [classname]`ValidationException` like [classname]`ConstraintDefinitionException`, [classname]`ConstraintDeclarationException` or [classname]`UnexpectedTypeException`.

All descriptor types accessible via [methodname]`getConstraintsForClass()` and introduced in the following sections are located in the package [classname]`javax.validation.metadata`.

[[constraintmetadata-elementdescriptor]]

=== ElementDescriptor

[classname]`ElementDescriptor` is the root interface describing elements hosting constraints. It is used to describe the list of constraints for a given element (whether it be a class, property, method etc.).

.ElementDescriptor interface
====

[source, JAVA, indent=0]
----
include::{validation-api-source-dir}javax/validation/metadata/ElementDescriptor.java[lines=7..8;13..-1]
----

====

[source, JAVA, indent=0]
----
include::{validation-api-source-dir}javax/validation/metadata/Scope.java[lines=7..-1]
----

[tck-testable]
--
[methodname]`getElementClass()` returns

* the object type when invoked on [classname]`BeanDescriptor`,
* the type of a property or parameter when invoked on [classname]`PropertyDescriptor` or [classname]`ParameterDescriptor` respectively,
* `Object[].class` when invoked on [classname]`CrossParameterDescriptor`,
* the return type when invoked on [classname]`ConstructorDescriptor`, [classname]`MethodDescriptor` or [classname]`ReturnValueDescriptor`.
--

[tck-testable]#[classname]`getConstraintDescriptors()` returns all the [classname]``ConstraintDescriptor``s (see <<constraintmetadata-constraintdescriptor>>) hosted on the given element in the class hierarchy, each [classname]`ConstraintDescriptor` describing one of the constraints declared on the given element.#

[tck-testable]#[methodname]`hasConstraints()` returns `true` if the given element in the class hierarchy holds at least one constraint declaration.#

[tck-testable]#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 [classname]`ConstraintFinder` fluent API by calling [methodname]`findConstraints()`.#

[tck-testable]#[classname]`unorderedAndMatchingGroups()` restricts the results to the [classname]``ConstraintDescriptor``s (see <<constraintmetadata-constraintdescriptor>>) matching the given groups. Order is not respected but group inheritance and inheritance via sequence (including the [classname]`Default` group overriding at the class level) are honored.#

[tck-testable]#[methodname]`declaredOn()` lets you restrict the list of element types constraints are hosted on.# This is particularly useful to retrieve property constraints only hosted on fields ([classname]`ElementType.FIELD`) or only hosted on getters ([classname]`ElementType.METHOD`).

[tck-testable]#[methodname]`lookingAt()` lets you restrict which constraints are considered. Either constraints belonging to the element but hosted on the class represented by the given descriptor ([classname]`Scope.LOCAL_ELEMENT`), or constraints belonging to the element but hosted anywhere in the class hierarchy ([classname]`Scope.HIERARCHY`).#

Here is an example restricting the list of constraints on getters, matching the default group and declared physically on the `name` getter of [classname]`Customer` (and not any of the getters on the super classes).

.Using the fluent API to restrict matching constraints
====

[source, JAVA]
----
public class User {

    @Size(max=50)
    String getName() {
        [...]
    }

    [...]
}
<commit_msg>BVAL-660 Defining behavior of ElementDescriptor#getElementClass() for container element type descriptors<commit_after>// Bean Validation
//
// License: Apache License, Version 2.0
// See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.

[[constraintmetadata]]

== Constraint metadata request APIs

The Bean Validation specification provides a way to query the constraint repository. This API is expected to be used for tooling support as well as integration with other frameworks, libraries and JSRs. The Bean Validation specification aims to provide both a validation engine and a metadata repository for object constraints. Frameworks (EE or SE) in need for constraint definition, validation and metadata will be able to rely on the Bean Validation specification for these services avoiding any unnecessary duplication work from an application and infrastructure point of view.

[[constraintmetadata-validator]]
=== Validator

The main API to access all metadata related to a given object is [classname]`Validator` (see <<validationapi-bootstrapping>> for more information on how to retrieve a [classname]`Validator` instance).

A [classname]`Validator` instance hosts the method to access to the metadata repository for a given class. It is recommended to leave the caching of [classname]`Validator` instances to the [classname]`ValidatorFactory`. [classname]`Validator` implementations are thread-safe.

.Validator interface (metadata request API)
====

[source, JAVA]
----
/**
 * Validates bean instances. Implementations of this interface must be thread-safe.
 *
 * @author <NAME>
 * @author <NAME>
 * @author <NAME>
 */
public interface Validator {

    [...] //See 5.1

    /**
     * Returns the descriptor object describing bean constraints.
     * <p/>
     * The returned object (and associated objects including
     * {@link ConstraintDescriptor}s) are immutable.
     *
     * @param clazz class or interface type evaluated
     * @return the bean descriptor for the specified class
     * @throws IllegalArgumentException if clazz is {@code null}
     * @throws ValidationException if a non recoverable error happens
     *         during the metadata discovery or if some
     *         constraints are invalid.
     */
    BeanDescriptor getConstraintsForClass(Class<?> clazz);
}
----

====

[tck-testable]#[methodname]`getConstraintsForClass()` returns a [classname]`BeanDescriptor` object describing the bean level constraints (see <<constraintdeclarationvalidationprocess-requirements-objectvalidation>>) and providing access to the property level constraints metadata.# [tck-testable]#An [classname]`IllegalArgumentException` is raised if the [varname]`clazz` parameter is null.#

[tck-testable]#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 [classname]`ValidationException` is raised.# This can be a subclass of [classname]`ValidationException` like [classname]`ConstraintDefinitionException`, [classname]`ConstraintDeclarationException` or [classname]`UnexpectedTypeException`.

All descriptor types accessible via [methodname]`getConstraintsForClass()` and introduced in the following sections are located in the package [classname]`javax.validation.metadata`.

[[constraintmetadata-elementdescriptor]]

=== ElementDescriptor

[classname]`ElementDescriptor` is the root interface describing elements hosting constraints. It is used to describe the list of constraints for a given element (whether it be a class, property, method etc.).

.ElementDescriptor interface
====

[source, JAVA, indent=0]
----
include::{validation-api-source-dir}javax/validation/metadata/ElementDescriptor.java[lines=7..8;13..-1]
----

====

[source, JAVA, indent=0]
----
include::{validation-api-source-dir}javax/validation/metadata/Scope.java[lines=7..-1]
----

[tck-testable]
--
[methodname]`getElementClass()` returns

* the object type when invoked on [classname]`BeanDescriptor`,
* the type of a property or parameter when invoked on [classname]`PropertyDescriptor` or [classname]`ParameterDescriptor` respectively,
* `Object[].class` when invoked on [classname]`CrossParameterDescriptor`,
* the return type when invoked on [classname]`ConstructorDescriptor`, [classname]`MethodDescriptor` or [classname]`ReturnValueDescriptor`,
* the container element type when invoked on `ContainerElementTypeDescriptor` (e.g. when invoked on a descriptor representing the container element type of `List<String>`, `String.class` will be returned).
--

[tck-testable]#[classname]`getConstraintDescriptors()` returns all the [classname]``ConstraintDescriptor``s (see <<constraintmetadata-constraintdescriptor>>) hosted on the given element in the class hierarchy, each [classname]`ConstraintDescriptor` describing one of the constraints declared on the given element.#

[tck-testable]#[methodname]`hasConstraints()` returns `true` if the given element in the class hierarchy holds at least one constraint declaration.#

[tck-testable]#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 [classname]`ConstraintFinder` fluent API by calling [methodname]`findConstraints()`.#

[tck-testable]#[classname]`unorderedAndMatchingGroups()` restricts the results to the [classname]``ConstraintDescriptor``s (see <<constraintmetadata-constraintdescriptor>>) matching the given groups. Order is not respected but group inheritance and inheritance via sequence (including the [classname]`Default` group overriding at the class level) are honored.#

[tck-testable]#[methodname]`declaredOn()` lets you restrict the list of element types constraints are hosted on.# This is particularly useful to retrieve property constraints only hosted on fields ([classname]`ElementType.FIELD`) or only hosted on getters ([classname]`ElementType.METHOD`).

[tck-testable]#[methodname]`lookingAt()` lets you restrict which constraints are considered. Either constraints belonging to the element but hosted on the class represented by the given descriptor ([classname]`Scope.LOCAL_ELEMENT`), or constraints belonging to the element but hosted anywhere in the class hierarchy ([classname]`Scope.HIERARCHY`).#

Here is an example restricting the list of constraints on getters, matching the default group and declared physically on the `name` getter of [classname]`Customer` (and not any of the getters on the super classes).

.Using the fluent API to restrict matching constraints
====

[source, JAVA]
----
public class User {

    @Size(max=50)
    String getName() {
        [...]
    }

    [...]
}

{'fraction_non_alphanumeric': 0.09129878920057155, 'fraction_numerical': 0.0027825825374144545, 'mean_word_length': 5.278564683663834, 'pattern_counts': {'":': 0, '<': 32, '<?xml version=': 0, '>': 32, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6327933', 'n_tokens_mistral': 3316, 'n_tokens_neox': 3240, 'n_words': 1400}