1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package gov.nist.secauto.metaschema.core.model.constraint;
28
29 import gov.nist.secauto.metaschema.core.metapath.DynamicContext;
30 import gov.nist.secauto.metaschema.core.metapath.ISequence;
31 import gov.nist.secauto.metaschema.core.metapath.MetapathException;
32 import gov.nist.secauto.metaschema.core.metapath.format.IPathFormatter;
33 import gov.nist.secauto.metaschema.core.metapath.item.node.INodeItem;
34 import gov.nist.secauto.metaschema.core.model.constraint.IConstraint.Level;
35 import gov.nist.secauto.metaschema.core.model.validation.IValidationResult;
36 import gov.nist.secauto.metaschema.core.util.CollectionUtil;
37
38 import java.util.LinkedList;
39 import java.util.List;
40 import java.util.Objects;
41
42 import edu.umd.cs.findbugs.annotations.NonNull;
43
44 public class FindingCollectingConstraintValidationHandler
45 extends AbstractConstraintValidationHandler
46 implements IValidationResult {
47 @NonNull
48 private final List<ConstraintValidationFinding> findings = new LinkedList<>();
49 @NonNull
50 private IPathFormatter pathFormatter = IPathFormatter.METAPATH_PATH_FORMATER;
51 @NonNull
52 private Level highestLevel = IConstraint.Level.INFORMATIONAL;
53
54 @Override
55 @NonNull
56 public IPathFormatter getPathFormatter() {
57 return pathFormatter;
58 }
59
60 public void setPathFormatter(@NonNull IPathFormatter pathFormatter) {
61 this.pathFormatter = Objects.requireNonNull(pathFormatter, "pathFormatter");
62 }
63
64 @Override
65 @NonNull
66 public List<ConstraintValidationFinding> getFindings() {
67 return CollectionUtil.unmodifiableList(findings);
68 }
69
70 @Override
71 @NonNull
72 public Level getHighestSeverity() {
73 return highestLevel;
74 }
75
76 protected void addFinding(@NonNull ConstraintValidationFinding finding) {
77 findings.add(finding);
78
79 Level severity = finding.getSeverity();
80 if (severity.ordinal() > highestLevel.ordinal()) {
81 highestLevel = severity;
82 }
83 }
84
85 @Override
86 public void handleCardinalityMinimumViolation(
87 @NonNull ICardinalityConstraint constraint,
88 @NonNull INodeItem node,
89 @NonNull ISequence<? extends INodeItem> targets) {
90 addFinding(ConstraintValidationFinding.builder(constraint, node)
91 .targets(targets.asList())
92 .message(newCardinalityMinimumViolationMessage(constraint, node, targets))
93 .build());
94 }
95
96 @Override
97 public void handleCardinalityMaximumViolation(
98 @NonNull ICardinalityConstraint constraint,
99 @NonNull INodeItem node,
100 @NonNull ISequence<? extends INodeItem> targets) {
101 addFinding(ConstraintValidationFinding.builder(constraint, node)
102 .targets(targets.asList())
103 .message(newCardinalityMaximumViolationMessage(constraint, node, targets))
104 .build());
105 }
106
107 @Override
108 public void handleIndexDuplicateKeyViolation(
109 @NonNull IIndexConstraint constraint,
110 @NonNull INodeItem node,
111 @NonNull INodeItem oldItem,
112 @NonNull INodeItem target) {
113 addFinding(ConstraintValidationFinding.builder(constraint, node)
114 .target(target)
115 .message(newIndexDuplicateKeyViolationMessage(constraint, node, oldItem, target))
116 .build());
117 }
118
119 @Override
120 public void handleUniqueKeyViolation(
121 @NonNull IUniqueConstraint constraint,
122 @NonNull INodeItem node,
123 @NonNull INodeItem oldItem,
124 @NonNull INodeItem target) {
125 addFinding(ConstraintValidationFinding.builder(constraint, node)
126 .target(target)
127 .message(newUniqueKeyViolationMessage(constraint, node, oldItem, target))
128 .build());
129 }
130
131 @SuppressWarnings("null")
132 @Override
133 public void handleKeyMatchError(
134 @NonNull IKeyConstraint constraint,
135 @NonNull INodeItem node,
136 @NonNull INodeItem target,
137 @NonNull MetapathException cause) {
138 addFinding(ConstraintValidationFinding.builder(constraint, node)
139 .target(target)
140 .message(cause.getLocalizedMessage())
141 .cause(cause)
142 .build());
143 }
144
145 @Override
146 public void handleMatchPatternViolation(
147 @NonNull IMatchesConstraint constraint,
148 @NonNull INodeItem node,
149 @NonNull INodeItem target,
150 @NonNull String value) {
151 addFinding(ConstraintValidationFinding.builder(constraint, node)
152 .target(target)
153 .message(newMatchPatternViolationMessage(constraint, node, target, value))
154 .build());
155 }
156
157 @Override
158 public void handleMatchDatatypeViolation(
159 @NonNull IMatchesConstraint constraint,
160 @NonNull INodeItem node,
161 @NonNull INodeItem target,
162 @NonNull String value,
163 @NonNull IllegalArgumentException cause) {
164 addFinding(ConstraintValidationFinding.builder(constraint, node)
165 .target(target)
166 .message(newMatchDatatypeViolationMessage(constraint, node, target, value))
167 .cause(cause)
168 .build());
169 }
170
171 @Override
172 public void handleExpectViolation(
173 @NonNull IExpectConstraint constraint,
174 @NonNull INodeItem node,
175 @NonNull INodeItem target,
176 @NonNull DynamicContext dynamicContext) {
177 addFinding(ConstraintValidationFinding.builder(constraint, node)
178 .target(target)
179 .message(newExpectViolationMessage(constraint, node, target, dynamicContext))
180 .build());
181 }
182
183 @Override
184 public void handleAllowedValuesViolation(@NonNull List<IAllowedValuesConstraint> failedConstraints,
185 @NonNull INodeItem target) {
186 addFinding(ConstraintValidationFinding.builder(failedConstraints, target)
187 .target(target)
188 .message(newAllowedValuesViolationMessage(failedConstraints, target))
189 .build());
190 }
191
192 @Override
193 public void handleIndexDuplicateViolation(IIndexConstraint constraint, INodeItem node) {
194 addFinding(ConstraintValidationFinding.builder(constraint, node)
195 .message(newIndexDuplicateViolationMessage(constraint, node))
196 .severity(Level.CRITICAL)
197 .build());
198 }
199
200 @Override
201 public void handleIndexMiss(IIndexHasKeyConstraint constraint, INodeItem node, INodeItem target, List<String> key) {
202 addFinding(ConstraintValidationFinding.builder(constraint, node)
203 .message(newIndexMissMessage(constraint, node, target, key))
204 .build());
205 }
206
207 }