0
# Validation Metadata
1
2
Comprehensive metadata API providing descriptors and introspection capabilities for validation constraints, bean structure, and executable validation configuration.
3
4
## Capabilities
5
6
### Bean Descriptor
7
8
Describes validation metadata for a bean class including properties, methods, and constructors.
9
10
```java { .api }
11
/**
12
* Describes validation metadata for a bean
13
*/
14
interface BeanDescriptor extends ElementDescriptor {
15
/**
16
* Check if the bean has any validation constraints
17
* @return true if bean has constraints or cascaded properties
18
*/
19
boolean isBeanConstrained();
20
21
/**
22
* Get descriptor for a specific property
23
* @param propertyName property name
24
* @return PropertyDescriptor or null if property doesn't exist
25
*/
26
PropertyDescriptor getPropertyDescriptor(String propertyName);
27
28
/**
29
* Get all constrained properties
30
* @return set of PropertyDescriptor for constrained properties
31
*/
32
Set<PropertyDescriptor> getConstrainedProperties();
33
34
/**
35
* Get descriptor for a specific method
36
* @param methodName method name
37
* @param parameterTypes parameter types
38
* @return MethodDescriptor or null if method doesn't exist
39
*/
40
MethodDescriptor getMethodDescriptor(String methodName, Class<?>... parameterTypes);
41
42
/**
43
* Get all constrained methods of specified types
44
* @param methodType first method type to include
45
* @param methodTypes additional method types
46
* @return set of MethodDescriptor for constrained methods
47
*/
48
Set<MethodDescriptor> getConstrainedMethods(MethodType methodType, MethodType... methodTypes);
49
50
/**
51
* Get descriptor for a specific constructor
52
* @param parameterTypes parameter types
53
* @return ConstructorDescriptor or null if constructor doesn't exist
54
*/
55
ConstructorDescriptor getConstructorDescriptor(Class<?>... parameterTypes);
56
57
/**
58
* Get all constrained constructors
59
* @return set of ConstructorDescriptor for constrained constructors
60
*/
61
Set<ConstructorDescriptor> getConstrainedConstructors();
62
}
63
```
64
65
### Constraint Descriptor
66
67
Describes metadata for a specific constraint including annotation details and validator classes.
68
69
```java { .api }
70
/**
71
* Describes a single constraint and its metadata
72
* @param <T> the constraint annotation type
73
*/
74
interface ConstraintDescriptor<T extends Annotation> {
75
/**
76
* Get the constraint annotation instance
77
* @return annotation instance
78
*/
79
T getAnnotation();
80
81
/**
82
* Get the constraint message template
83
* @return message template string
84
*/
85
String getMessageTemplate();
86
87
/**
88
* Get the groups the constraint belongs to
89
* @return set of group classes
90
*/
91
Set<Class<?>> getGroups();
92
93
/**
94
* Get the constraint payload
95
* @return set of payload classes
96
*/
97
Set<Class<? extends Payload>> getPayload();
98
99
/**
100
* Get constraint validator classes
101
* @return list of ConstraintValidator classes
102
*/
103
List<Class<? extends ConstraintValidator<T, ?>>> getConstraintValidatorClasses();
104
105
/**
106
* Get constraint attributes (annotation element values)
107
* @return map of attribute names to values
108
*/
109
Map<String, Object> getAttributes();
110
111
/**
112
* Get composing constraints for composed constraints
113
* @return set of composing constraint descriptors
114
*/
115
Set<ConstraintDescriptor<?>> getComposingConstraints();
116
117
/**
118
* Check if composed constraint reports as single violation
119
* @return true if @ReportAsSingleViolation is present
120
*/
121
boolean isReportAsSingleViolation();
122
123
/**
124
* Get validation applies to setting (parameters vs return value)
125
* @return ConstraintTarget value
126
*/
127
ConstraintTarget getValidationAppliesTo();
128
129
/**
130
* Get value unwrapping setting
131
* @return ValidateUnwrappedValue enum value
132
*/
133
ValidateUnwrappedValue getValueUnwrapping();
134
}
135
```
136
137
### Element Descriptors
138
139
Base descriptor interface and specialized descriptors for different validation elements.
140
141
```java { .api }
142
/**
143
* Base interface for validation element descriptors
144
*/
145
interface ElementDescriptor {
146
/**
147
* Check if element has any constraints
148
* @return true if element has constraints
149
*/
150
boolean hasConstraints();
151
152
/**
153
* Get the element class
154
* @return class of the element
155
*/
156
Class<?> getElementClass();
157
158
/**
159
* Get all constraint descriptors for this element
160
* @return set of ConstraintDescriptor instances
161
*/
162
Set<ConstraintDescriptor<?>> getConstraintDescriptors();
163
164
/**
165
* Find constraints matching criteria
166
* @return ConstraintFinder for building constraint queries
167
*/
168
ConstraintFinder findConstraints();
169
170
/**
171
* Builder for finding constraints with various criteria
172
*/
173
interface ConstraintFinder {
174
ConstraintFinder unorderedAndMatchingGroups(Class<?>... groups);
175
ConstraintFinder lookingAt(Scope scope);
176
ConstraintFinder declaredOn(ElementType... types);
177
Set<ConstraintDescriptor<?>> getConstraintDescriptors();
178
}
179
}
180
181
/**
182
* Describes property validation metadata
183
*/
184
interface PropertyDescriptor extends ElementDescriptor, CascadableDescriptor, ContainerDescriptor {
185
/**
186
* Get the property name
187
* @return property name
188
*/
189
String getPropertyName();
190
}
191
192
/**
193
* Describes method validation metadata
194
*/
195
interface MethodDescriptor extends ExecutableDescriptor {
196
/**
197
* Get methods this method overrides
198
* @return set of overridden method descriptors
199
*/
200
Set<MethodDescriptor> getOverriddenMethods();
201
}
202
203
/**
204
* Describes constructor validation metadata
205
*/
206
interface ConstructorDescriptor extends ExecutableDescriptor {
207
// Inherits all methods from ExecutableDescriptor
208
}
209
210
/**
211
* Base descriptor for executables (methods and constructors)
212
*/
213
interface ExecutableDescriptor extends ElementDescriptor {
214
/**
215
* Get the executable name
216
* @return method name or "<init>" for constructors
217
*/
218
String getName();
219
220
/**
221
* Get parameter descriptors
222
* @return list of parameter descriptors
223
*/
224
List<ParameterDescriptor> getParameterDescriptors();
225
226
/**
227
* Get cross-parameter descriptor
228
* @return CrossParameterDescriptor for cross-parameter constraints
229
*/
230
CrossParameterDescriptor getCrossParameterDescriptor();
231
232
/**
233
* Get return value descriptor
234
* @return ReturnValueDescriptor for return value constraints
235
*/
236
ReturnValueDescriptor getReturnValueDescriptor();
237
238
/**
239
* Check if executable has constrained parameters
240
* @return true if any parameters have constraints
241
*/
242
boolean hasConstrainedParameters();
243
244
/**
245
* Check if executable has constrained return value
246
* @return true if return value has constraints
247
*/
248
boolean hasConstrainedReturnValue();
249
}
250
```
251
252
### Supporting Enums
253
254
Enums used by the metadata API for classification and configuration.
255
256
```java { .api }
257
/**
258
* Method types for descriptor queries
259
*/
260
enum MethodType {
261
/** Getter methods (following JavaBean naming conventions) */
262
GETTER,
263
264
/** Non-getter methods */
265
NON_GETTER
266
}
267
268
/**
269
* Scope for constraint searches
270
*/
271
enum Scope {
272
/** Include inherited constraints */
273
HIERARCHY,
274
275
/** Only local constraints */
276
LOCAL_ELEMENT
277
}
278
279
/**
280
* Settings for validating unwrapped values
281
*/
282
enum ValidateUnwrappedValue {
283
/** Use default unwrapping behavior */
284
DEFAULT,
285
286
/** Force unwrapping */
287
UNWRAP,
288
289
/** Skip unwrapping */
290
SKIP
291
}
292
```
293
294
**Usage Examples:**
295
296
```java
297
import jakarta.validation.*;
298
import jakarta.validation.metadata.*;
299
import java.util.Set;
300
301
public class MetadataInspectionExample {
302
private Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
303
304
public void inspectBeanMetadata() {
305
// Get bean descriptor
306
BeanDescriptor beanDescriptor = validator.getConstraintsForClass(User.class);
307
308
System.out.println("Bean constrained: " + beanDescriptor.isBeanConstrained());
309
System.out.println("Element class: " + beanDescriptor.getElementClass().getSimpleName());
310
311
// Inspect constrained properties
312
Set<PropertyDescriptor> properties = beanDescriptor.getConstrainedProperties();
313
for (PropertyDescriptor property : properties) {
314
System.out.println("\nProperty: " + property.getPropertyName());
315
System.out.println(" Has constraints: " + property.hasConstraints());
316
System.out.println(" Is cascaded: " + property.isCascaded());
317
318
// Get constraints for this property
319
Set<ConstraintDescriptor<?>> constraints = property.getConstraintDescriptors();
320
for (ConstraintDescriptor<?> constraint : constraints) {
321
System.out.println(" Constraint: " +
322
constraint.getAnnotation().annotationType().getSimpleName());
323
System.out.println(" Message: " + constraint.getMessageTemplate());
324
System.out.println(" Groups: " + constraint.getGroups());
325
System.out.println(" Attributes: " + constraint.getAttributes());
326
}
327
}
328
329
// Inspect constrained methods
330
Set<MethodDescriptor> methods = beanDescriptor.getConstrainedMethods(
331
MethodType.NON_GETTER, MethodType.GETTER);
332
for (MethodDescriptor method : methods) {
333
System.out.println("\nMethod: " + method.getName());
334
System.out.println(" Constrained parameters: " + method.hasConstrainedParameters());
335
System.out.println(" Constrained return: " + method.hasConstrainedReturnValue());
336
337
// Inspect parameters
338
List<ParameterDescriptor> parameters = method.getParameterDescriptors();
339
for (int i = 0; i < parameters.size(); i++) {
340
ParameterDescriptor param = parameters.get(i);
341
System.out.println(" Parameter " + i + ": " + param.getName());
342
System.out.println(" Has constraints: " + param.hasConstraints());
343
}
344
345
// Inspect return value
346
ReturnValueDescriptor returnValue = method.getReturnValueDescriptor();
347
if (returnValue.hasConstraints()) {
348
System.out.println(" Return value constraints: " +
349
returnValue.getConstraintDescriptors().size());
350
}
351
}
352
}
353
354
public void findSpecificConstraints() {
355
BeanDescriptor beanDescriptor = validator.getConstraintsForClass(User.class);
356
357
// Find constraints for a specific property
358
PropertyDescriptor emailProperty = beanDescriptor.getPropertyDescriptor("email");
359
if (emailProperty != null) {
360
// Find only @Email constraints
361
Set<ConstraintDescriptor<?>> emailConstraints = emailProperty
362
.findConstraints()
363
.lookingAt(Scope.LOCAL_ELEMENT)
364
.getConstraintDescriptors();
365
366
for (ConstraintDescriptor<?> constraint : emailConstraints) {
367
if (constraint.getAnnotation().annotationType().equals(Email.class)) {
368
System.out.println("Found @Email constraint");
369
System.out.println("Validator classes: " +
370
constraint.getConstraintValidatorClasses());
371
}
372
}
373
}
374
}
375
376
public void inspectComposedConstraints() {
377
// Assuming we have a composed constraint @ValidName
378
BeanDescriptor beanDescriptor = validator.getConstraintsForClass(User.class);
379
PropertyDescriptor nameProperty = beanDescriptor.getPropertyDescriptor("name");
380
381
if (nameProperty != null) {
382
for (ConstraintDescriptor<?> constraint : nameProperty.getConstraintDescriptors()) {
383
System.out.println("Constraint: " +
384
constraint.getAnnotation().annotationType().getSimpleName());
385
386
// Check if it's a composed constraint
387
Set<ConstraintDescriptor<?>> composingConstraints =
388
constraint.getComposingConstraints();
389
if (!composingConstraints.isEmpty()) {
390
System.out.println(" Composed of:");
391
for (ConstraintDescriptor<?> composing : composingConstraints) {
392
System.out.println(" - " +
393
composing.getAnnotation().annotationType().getSimpleName());
394
}
395
System.out.println(" Reports as single violation: " +
396
constraint.isReportAsSingleViolation());
397
}
398
}
399
}
400
}
401
}
402
```