1 package cn.home1.oss.lib.errorhandle.internal.resolver;
2
3 import static com.google.common.collect.Lists.newArrayList;
4 import static com.google.common.collect.Lists.newLinkedList;
5 import static org.springframework.util.StringUtils.isEmpty;
6
7 import cn.home1.oss.lib.errorhandle.api.AbstractConcreteExceptionResolver;
8 import cn.home1.oss.lib.errorhandle.api.ValidationError;
9
10 import lombok.extern.slf4j.Slf4j;
11
12 import org.springframework.core.convert.ConversionException;
13 import org.springframework.core.convert.ConversionService;
14
15 import java.util.Collections;
16 import java.util.List;
17 import java.util.Optional;
18
19 import javax.validation.ConstraintViolation;
20 import javax.validation.ConstraintViolationException;
21 import javax.validation.ElementKind;
22 import javax.validation.Path;
23 import javax.validation.Path.Node;
24
25 @Slf4j
26 public class ConstraintViolationExceptionResolver
27 extends AbstractConcreteExceptionResolver<ConstraintViolationException> {
28
29 static String convertToString(
30 final ConversionService conversionService,
31 final Object value
32 ) {
33 String reuslt;
34 if (value == null) {
35 reuslt = null;
36 } else if (conversionService == null) {
37 reuslt = value.toString();
38 } else {
39 try {
40 reuslt = conversionService.convert(value, String.class);
41 } catch (final ConversionException ex) {
42 if (log.isDebugEnabled()) {
43 log.debug("failed to convert value '{}' to String.class.", value, ex);
44 }
45 reuslt = value.toString();
46 }
47 }
48 return reuslt;
49 }
50
51 static Node findLastNonEmptyPathNode(final Path path) {
52 Node found = null;
53 final List<Node> list = newArrayList(path.iterator());
54 Collections.reverse(list);
55 for (final Node node : list) {
56 if (!isEmpty(node.getName())) {
57 found = node;
58 break;
59 }
60 }
61 return found;
62 }
63
64 @Override
65 public Optional<List<ValidationError>> validationErrors(
66 final ConstraintViolationException exception
67 ) {
68 final List<ValidationError> validationErrors = newLinkedList();
69
70 for (final ConstraintViolation<?> violation : exception.getConstraintViolations()) {
71 final Node pathNode = findLastNonEmptyPathNode(violation.getPropertyPath());
72
73
74 if (pathNode != null && pathNode.getKind() == ElementKind.PROPERTY) {
75 validationErrors.add(
76 ValidationError.validationErrorBuilder()
77 .field(pathNode.getName())
78 .rejected(convertToString(this.conversionService, violation.getInvalidValue()))
79 .message(violation.getMessage())
80 .build()
81 );
82
83 } else {
84 validationErrors.add(
85 ValidationError.validationErrorBuilder()
86 .message(violation.getMessage())
87 .build()
88 );
89 }
90 }
91
92 return Optional.of(validationErrors);
93 }
94 }