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.item.node.INodeItem;
30 import gov.nist.secauto.metaschema.core.model.constraint.IConstraint.Level;
31 import gov.nist.secauto.metaschema.core.model.validation.IValidationFinding;
32 import gov.nist.secauto.metaschema.core.util.CollectionUtil;
33
34 import java.net.URI;
35 import java.util.Collections;
36 import java.util.Comparator;
37 import java.util.List;
38
39 import edu.umd.cs.findbugs.annotations.NonNull;
40 import edu.umd.cs.findbugs.annotations.Nullable;
41
42
43
44
45 public class ConstraintValidationFinding implements IValidationFinding {
46 @NonNull
47 private final List<? extends IConstraint> constraints;
48 @NonNull
49 private final CharSequence message;
50 @NonNull
51 private final INodeItem node;
52 @NonNull
53 private final List<? extends INodeItem> targets;
54 private final Throwable cause;
55 private final Level severity;
56
57 private ConstraintValidationFinding(
58 @NonNull List<? extends IConstraint> constraints,
59 @NonNull INodeItem node,
60 @NonNull CharSequence message,
61 @NonNull List<? extends INodeItem> targets,
62 @NonNull Level severity,
63 @Nullable Throwable cause) {
64 this.constraints = constraints;
65 this.node = node;
66 this.message = message;
67 this.targets = targets;
68 this.severity = severity;
69 this.cause = cause;
70 }
71
72 public List<? extends IConstraint> getConstraints() {
73 return constraints;
74 }
75
76 @Override
77 public CharSequence getMessage() {
78 return message;
79 }
80
81 public INodeItem getNode() {
82 return node;
83 }
84
85 public List<? extends INodeItem> getTargets() {
86 return targets;
87 }
88
89 @Override
90 public Throwable getCause() {
91 return cause;
92 }
93
94 @SuppressWarnings("null")
95 @Override
96 public Level getSeverity() {
97 return severity;
98 }
99
100 @SuppressWarnings("null")
101 @Override
102 public @NonNull URI getDocumentUri() {
103 return getNode().getBaseUri();
104 }
105
106 @NonNull
107 public static Builder builder(@NonNull List<? extends IConstraint> constraints, @NonNull INodeItem node) {
108 return new Builder(constraints, node);
109 }
110
111 @NonNull
112 public static Builder builder(@NonNull IConstraint constraint, @NonNull INodeItem node) {
113 return new Builder(CollectionUtil.singletonList(constraint), node);
114 }
115
116 public static final class Builder {
117 @NonNull
118 private final List<? extends IConstraint> constraints;
119 @NonNull
120 private final INodeItem node;
121 private CharSequence message;
122 private List<? extends INodeItem> targets;
123 private Throwable cause;
124 private Level severity;
125
126 private Builder(@NonNull List<? extends IConstraint> constraints, @NonNull INodeItem node) {
127 this.constraints = constraints;
128 this.node = node;
129 }
130
131 @NonNull
132 public Builder message(@NonNull CharSequence message) {
133 this.message = message;
134 return this;
135 }
136
137 @NonNull
138 public Builder target(@NonNull INodeItem target) {
139 this.targets = Collections.singletonList(target);
140 return this;
141 }
142
143 @NonNull
144 public Builder targets(@NonNull List<? extends INodeItem> targets) {
145 this.targets = CollectionUtil.unmodifiableList(targets);
146 return this;
147 }
148
149 @NonNull
150 public Builder cause(@NonNull Throwable cause) {
151 this.cause = cause;
152 return this;
153 }
154
155 @NonNull
156 public Builder severity(@NonNull Level severity) {
157 this.severity = severity;
158 return this;
159 }
160
161 @NonNull
162 public ConstraintValidationFinding build() {
163 if (message == null) {
164 throw new IllegalStateException("Missing message");
165 }
166
167 Level severity = this.severity == null ? constraints.stream()
168 .map(IConstraint::getLevel)
169 .max(Comparator.comparing(Level::ordinal))
170 .get() : this.severity;
171
172 List<? extends INodeItem> targets = this.targets == null ? CollectionUtil.emptyList() : this.targets;
173
174 assert message != null;
175 assert targets != null;
176 assert severity != null;
177
178 return new ConstraintValidationFinding(
179 constraints,
180 node,
181 message,
182 targets,
183 severity,
184 cause);
185 }
186 }
187 }