001/*
002 * Copyright 2002-2020 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.web.bind.support;
018
019import java.beans.PropertyEditor;
020import java.util.List;
021import java.util.Map;
022
023import org.springframework.beans.PropertyEditorRegistry;
024import org.springframework.core.MethodParameter;
025import org.springframework.lang.Nullable;
026import org.springframework.util.Assert;
027import org.springframework.validation.BeanPropertyBindingResult;
028import org.springframework.validation.BindingResult;
029import org.springframework.validation.Errors;
030import org.springframework.validation.FieldError;
031import org.springframework.validation.ObjectError;
032import org.springframework.web.server.ServerWebInputException;
033
034/**
035 * A specialization of {@link ServerWebInputException} thrown when after data
036 * binding and validation failure. Implements {@link BindingResult} (and its
037 * super-interface {@link Errors}) to allow for direct analysis of binding and
038 * validation errors.
039 *
040 * @author Rossen Stoyanchev
041 * @since 5.0
042 */
043@SuppressWarnings("serial")
044public class WebExchangeBindException extends ServerWebInputException implements BindingResult {
045
046        private final BindingResult bindingResult;
047
048
049        public WebExchangeBindException(MethodParameter parameter, BindingResult bindingResult) {
050                super("Validation failure", parameter);
051                this.bindingResult = bindingResult;
052        }
053
054
055        /**
056         * Return the BindingResult that this BindException wraps.
057         * Will typically be a BeanPropertyBindingResult.
058         * @see BeanPropertyBindingResult
059         */
060        public final BindingResult getBindingResult() {
061                return this.bindingResult;
062        }
063
064
065        @Override
066        public String getObjectName() {
067                return this.bindingResult.getObjectName();
068        }
069
070        @Override
071        public void setNestedPath(String nestedPath) {
072                this.bindingResult.setNestedPath(nestedPath);
073        }
074
075        @Override
076        public String getNestedPath() {
077                return this.bindingResult.getNestedPath();
078        }
079
080        @Override
081        public void pushNestedPath(String subPath) {
082                this.bindingResult.pushNestedPath(subPath);
083        }
084
085        @Override
086        public void popNestedPath() throws IllegalStateException {
087                this.bindingResult.popNestedPath();
088        }
089
090
091        @Override
092        public void reject(String errorCode) {
093                this.bindingResult.reject(errorCode);
094        }
095
096        @Override
097        public void reject(String errorCode, String defaultMessage) {
098                this.bindingResult.reject(errorCode, defaultMessage);
099        }
100
101        @Override
102        public void reject(String errorCode, @Nullable Object[] errorArgs, @Nullable String defaultMessage) {
103                this.bindingResult.reject(errorCode, errorArgs, defaultMessage);
104        }
105
106        @Override
107        public void rejectValue(@Nullable String field, String errorCode) {
108                this.bindingResult.rejectValue(field, errorCode);
109        }
110
111        @Override
112        public void rejectValue(@Nullable String field, String errorCode, String defaultMessage) {
113                this.bindingResult.rejectValue(field, errorCode, defaultMessage);
114        }
115
116        @Override
117        public void rejectValue(
118                        @Nullable String field, String errorCode, @Nullable Object[] errorArgs, @Nullable String defaultMessage) {
119
120                this.bindingResult.rejectValue(field, errorCode, errorArgs, defaultMessage);
121        }
122
123        @Override
124        public void addAllErrors(Errors errors) {
125                this.bindingResult.addAllErrors(errors);
126        }
127
128
129        @Override
130        public boolean hasErrors() {
131                return this.bindingResult.hasErrors();
132        }
133
134        @Override
135        public int getErrorCount() {
136                return this.bindingResult.getErrorCount();
137        }
138
139        @Override
140        public List<ObjectError> getAllErrors() {
141                return this.bindingResult.getAllErrors();
142        }
143
144        @Override
145        public boolean hasGlobalErrors() {
146                return this.bindingResult.hasGlobalErrors();
147        }
148
149        @Override
150        public int getGlobalErrorCount() {
151                return this.bindingResult.getGlobalErrorCount();
152        }
153
154        @Override
155        public List<ObjectError> getGlobalErrors() {
156                return this.bindingResult.getGlobalErrors();
157        }
158
159        @Override
160        @Nullable
161        public ObjectError getGlobalError() {
162                return this.bindingResult.getGlobalError();
163        }
164
165        @Override
166        public boolean hasFieldErrors() {
167                return this.bindingResult.hasFieldErrors();
168        }
169
170        @Override
171        public int getFieldErrorCount() {
172                return this.bindingResult.getFieldErrorCount();
173        }
174
175        @Override
176        public List<FieldError> getFieldErrors() {
177                return this.bindingResult.getFieldErrors();
178        }
179
180        @Override
181        @Nullable
182        public FieldError getFieldError() {
183                return this.bindingResult.getFieldError();
184        }
185
186        @Override
187        public boolean hasFieldErrors(String field) {
188                return this.bindingResult.hasFieldErrors(field);
189        }
190
191        @Override
192        public int getFieldErrorCount(String field) {
193                return this.bindingResult.getFieldErrorCount(field);
194        }
195
196        @Override
197        public List<FieldError> getFieldErrors(String field) {
198                return this.bindingResult.getFieldErrors(field);
199        }
200
201        @Override
202        @Nullable
203        public FieldError getFieldError(String field) {
204                return this.bindingResult.getFieldError(field);
205        }
206
207        @Override
208        @Nullable
209        public Object getFieldValue(String field) {
210                return this.bindingResult.getFieldValue(field);
211        }
212
213        @Override
214        @Nullable
215        public Class<?> getFieldType(String field) {
216                return this.bindingResult.getFieldType(field);
217        }
218
219        @Override
220        @Nullable
221        public Object getTarget() {
222                return this.bindingResult.getTarget();
223        }
224
225        @Override
226        public Map<String, Object> getModel() {
227                return this.bindingResult.getModel();
228        }
229
230        @Override
231        @Nullable
232        public Object getRawFieldValue(String field) {
233                return this.bindingResult.getRawFieldValue(field);
234        }
235
236        @Override
237        @SuppressWarnings("rawtypes")
238        @Nullable
239        public PropertyEditor findEditor(@Nullable String field, @Nullable Class valueType) {
240                return this.bindingResult.findEditor(field, valueType);
241        }
242
243        @Override
244        @Nullable
245        public PropertyEditorRegistry getPropertyEditorRegistry() {
246                return this.bindingResult.getPropertyEditorRegistry();
247        }
248
249        @Override
250        public String[] resolveMessageCodes(String errorCode) {
251                return this.bindingResult.resolveMessageCodes(errorCode);
252        }
253
254        @Override
255        public String[] resolveMessageCodes(String errorCode, String field) {
256                return this.bindingResult.resolveMessageCodes(errorCode, field);
257        }
258
259        @Override
260        public void addError(ObjectError error) {
261                this.bindingResult.addError(error);
262        }
263
264        @Override
265        public void recordFieldValue(String field, Class<?> type, @Nullable Object value) {
266                this.bindingResult.recordFieldValue(field, type, value);
267        }
268
269        @Override
270        public void recordSuppressedField(String field) {
271                this.bindingResult.recordSuppressedField(field);
272        }
273
274        @Override
275        public String[] getSuppressedFields() {
276                return this.bindingResult.getSuppressedFields();
277        }
278
279
280        /**
281         * Returns diagnostic information about the errors held in this object.
282         */
283        @Override
284        public String getMessage() {
285                MethodParameter parameter = getMethodParameter();
286                Assert.state(parameter != null, "No MethodParameter");
287                StringBuilder sb = new StringBuilder("Validation failed for argument at index ")
288                                .append(parameter.getParameterIndex()).append(" in method: ")
289                                .append(parameter.getExecutable().toGenericString())
290                                .append(", with ").append(this.bindingResult.getErrorCount()).append(" error(s): ");
291                for (ObjectError error : this.bindingResult.getAllErrors()) {
292                        sb.append("[").append(error).append("] ");
293                }
294                return sb.toString();
295        }
296
297        @Override
298        public boolean equals(@Nullable Object other) {
299                return (this == other || this.bindingResult.equals(other));
300        }
301
302        @Override
303        public int hashCode() {
304                return this.bindingResult.hashCode();
305        }
306
307}