• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

TAKETODAY / today-infrastructure / 18154768944

01 Oct 2025 07:26AM UTC coverage: 81.882% (-0.005%) from 81.887%
18154768944

push

github

web-flow
Merge pull request #290 from TAKETODAY/dev/jspecify

jspecify

59788 of 78013 branches covered (76.64%)

Branch coverage included in aggregate %.

141239 of 167496 relevant lines covered (84.32%)

3.6 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

32.14
today-context/src/main/java/infra/validation/method/ParameterValidationResult.java
1
/*
2
 * Copyright 2017 - 2025 the original author or authors.
3
 *
4
 * This program is free software: you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation, either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program. If not, see [https://www.gnu.org/licenses/]
16
 */
17

18
package infra.validation.method;
19

20
import org.jspecify.annotations.Nullable;
21

22
import java.util.Collection;
23
import java.util.List;
24
import java.util.function.BiFunction;
25

26
import infra.context.MessageSourceResolvable;
27
import infra.core.MethodParameter;
28
import infra.lang.Assert;
29
import infra.util.ObjectUtils;
30
import infra.validation.Errors;
31
import infra.validation.FieldError;
32

33
/**
34
 * Store and expose the results of method validation for a method parameter.
35
 * <ul>
36
 * <li>Validation errors directly on method parameter values are exposed as a
37
 * list of {@link MessageSourceResolvable}s.
38
 * <li>Nested validation errors on an Object method parameter are exposed as
39
 * {@link Errors} by the subclass
40
 * {@link ParameterErrors}.
41
 * </ul>
42
 *
43
 * @author Rossen Stoyanchev
44
 * @author <a href="https://github.com/TAKETODAY">Harry Yang</a>
45
 * @since 4.0
46
 */
47
public class ParameterValidationResult {
48

49
  private final MethodParameter methodParameter;
50

51
  @Nullable
52
  private final Object argument;
53

54
  private final List<MessageSourceResolvable> resolvableErrors;
55

56
  @Nullable
57
  private final Object container;
58

59
  @Nullable
60
  private final Integer containerIndex;
61

62
  @Nullable
63
  private final Object containerKey;
64

65
  private final BiFunction<MessageSourceResolvable, Class<?>, Object> sourceLookup;
66

67
  /**
68
   * Create a {@code ParameterValidationResult}.
69
   */
70
  public ParameterValidationResult(MethodParameter param, @Nullable Object arg, Collection<? extends MessageSourceResolvable> errors,
71
          @Nullable Object container, @Nullable Integer index, @Nullable Object key,
72
          BiFunction<MessageSourceResolvable, Class<?>, Object> sourceLookup) {
2✔
73

74
    Assert.notNull(param, "MethodParameter is required");
3✔
75
    Assert.notEmpty(errors, "`resolvableErrors` must not be empty");
3✔
76
    this.methodParameter = param;
3✔
77
    this.argument = arg;
3✔
78
    this.resolvableErrors = List.copyOf(errors);
4✔
79
    this.container = container;
3✔
80
    this.containerIndex = index;
3✔
81
    this.containerKey = key;
3✔
82
    this.sourceLookup = sourceLookup;
3✔
83
  }
1✔
84

85
  /**
86
   * The method parameter the validation results are for.
87
   */
88
  public MethodParameter getMethodParameter() {
89
    return this.methodParameter;
3✔
90
  }
91

92
  /**
93
   * The method argument value that was validated.
94
   */
95
  @Nullable
96
  public Object getArgument() {
97
    return this.argument;
3✔
98
  }
99

100
  /**
101
   * List of {@link MessageSourceResolvable} representations adapted from the
102
   * validation errors of the validation library.
103
   * <ul>
104
   * <li>For a constraints directly on a method parameter, error codes are
105
   * based on the names of the constraint annotation, the object, the method,
106
   * the parameter, and parameter type, e.g.
107
   * {@code ["Max.myObject#myMethod.myParameter", "Max.myParameter", "Max.int", "Max"]}.
108
   * Arguments include the parameter itself as a {@link MessageSourceResolvable}, e.g.
109
   * {@code ["myObject#myMethod.myParameter", "myParameter"]}, followed by actual
110
   * constraint annotation attributes (i.e. excluding "message", "groups" and
111
   * "payload") in alphabetical order of attribute names.
112
   * <li>For cascaded constraints via {@link jakarta.validation.Validator @Valid}
113
   * on a bean method parameter, this method returns
114
   * {@link FieldError field errors} that you
115
   * can also access more conveniently through methods of the
116
   * {@link ParameterErrors} sub-class.
117
   * </ul>
118
   */
119
  public List<MessageSourceResolvable> getResolvableErrors() {
120
    return this.resolvableErrors;
3✔
121
  }
122

123
  /**
124
   * When {@code @Valid} is declared on a container of elements such as
125
   * {@link java.util.Collection}, {@link java.util.Map},
126
   * {@link java.util.Optional}, and others, this method returns the container
127
   * of the validated {@link #getArgument() argument}, while
128
   * {@link #getContainerIndex()} and {@link #getContainerKey()} provide
129
   * information about the index or key if applicable.
130
   */
131
  @Nullable
132
  public Object getContainer() {
133
    return this.container;
3✔
134
  }
135

136
  /**
137
   * When {@code @Valid} is declared on an indexed container of elements such as
138
   * {@link List} or array, this method returns the index of the validated
139
   * {@link #getArgument() argument}.
140
   */
141
  @Nullable
142
  public Integer getContainerIndex() {
143
    return this.containerIndex;
3✔
144
  }
145

146
  /**
147
   * When {@code @Valid} is declared on a container of elements referenced by
148
   * key such as {@link java.util.Map}, this method returns the key of the
149
   * validated {@link #getArgument() argument}.
150
   */
151
  @Nullable
152
  public Object getContainerKey() {
153
    return this.containerKey;
3✔
154
  }
155

156
  /**
157
   * Unwrap the source behind the given error. For Jakarta Bean validation the
158
   * source is a {@link jakarta.validation.ConstraintViolation}.
159
   *
160
   * @param sourceType the expected source type
161
   * @return the source object of the given type
162
   * @since 5.0
163
   */
164
  @SuppressWarnings("unchecked")
165
  public <T> T unwrap(MessageSourceResolvable error, Class<T> sourceType) {
166
    return (T) this.sourceLookup.apply(error, sourceType);
6✔
167
  }
168

169
  @Override
170
  public boolean equals(@Nullable Object other) {
171
    if (this == other) {
×
172
      return true;
×
173
    }
174
    if (!super.equals(other)) {
×
175
      return false;
×
176
    }
177
    return other instanceof ParameterValidationResult otherResult
×
178
            && getMethodParameter().equals(otherResult.getMethodParameter())
×
179
            && ObjectUtils.nullSafeEquals(getArgument(), otherResult.getArgument())
×
180
            && ObjectUtils.nullSafeEquals(getContainerIndex(), otherResult.getContainerIndex())
×
181
            && ObjectUtils.nullSafeEquals(getContainerKey(), otherResult.getContainerKey());
×
182
  }
183

184
  @Override
185
  public int hashCode() {
186
    int hashCode = super.hashCode();
×
187
    hashCode = 29 * hashCode + getMethodParameter().hashCode();
×
188
    hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(getArgument());
×
189
    hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(getContainerIndex());
×
190
    hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(getContainerKey());
×
191
    return hashCode;
×
192
  }
193

194
  @Override
195
  public String toString() {
196
    return getClass().getSimpleName() + " for " + this.methodParameter +
×
197
            ", argument value '" + ObjectUtils.nullSafeConciseToString(this.argument) + "'," +
×
198
            (this.containerIndex != null ? "containerIndex[" + this.containerIndex + "]," : "") +
×
199
            (this.containerKey != null ? "containerKey['" + this.containerKey + "']," : "") +
×
200
            " errors: " + getResolvableErrors();
×
201
  }
202

203
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc