1 /*
2 * SPDX-FileCopyrightText: none
3 * SPDX-License-Identifier: CC0-1.0
4 */
5
6 package gov.nist.secauto.metaschema.core.model.constraint;
7
8 import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline;
9 import gov.nist.secauto.metaschema.core.metapath.DynamicContext;
10 import gov.nist.secauto.metaschema.core.metapath.IMetapathExpression;
11 import gov.nist.secauto.metaschema.core.metapath.MetapathException;
12 import gov.nist.secauto.metaschema.core.metapath.item.ISequence;
13 import gov.nist.secauto.metaschema.core.metapath.item.node.IDefinitionNodeItem;
14 import gov.nist.secauto.metaschema.core.model.IAttributable;
15 import gov.nist.secauto.metaschema.core.model.IDescribable;
16 import gov.nist.secauto.metaschema.core.model.ISource;
17 import gov.nist.secauto.metaschema.core.util.ObjectUtils;
18
19 import edu.umd.cs.findbugs.annotations.NonNull;
20 import edu.umd.cs.findbugs.annotations.Nullable;
21
22 /**
23 * Represents a rule constraining the model of a Metaschema assembly, field or
24 * flag. Provides a common interface for all constraint definitions.
25 */
26 public interface IConstraint extends IAttributable, IDescribable {
27 /**
28 * The type of constraint.
29 */
30 enum Type {
31 ALLOWED_VALUES("allowed-values"),
32 CARDINALITY("cardinality"),
33 EXPECT("expect"),
34 INDEX("index"),
35 UNIQUE("unique"),
36 INDEX_HAS_KEY("index-has-key"),
37 MATCHES("matches");
38
39 @NonNull
40 private final String name;
41
42 Type(@NonNull String name) {
43 this.name = name;
44 }
45
46 @NonNull
47 public String getName() {
48 return name;
49 }
50 }
51
52 /**
53 * The degree to which a constraint violation is significant.
54 * <p>
55 * These values are ordered from least significant to most significant.
56 */
57 enum Level {
58 /**
59 * No violation.
60 */
61 NONE,
62 /**
63 * A violation of the constraint represents a point of interest.
64 */
65 INFORMATIONAL,
66 /**
67 * A violation of the constraint represents a fault in the content that may
68 * warrant review by a developer when performing model or tool development.
69 */
70 DEBUG,
71 /**
72 * A violation of the constraint represents a potential issue with the content.
73 */
74 WARNING,
75 /**
76 * A violation of the constraint represents a fault in the content. This may
77 * include issues around compatibility, integrity, consistency, etc.
78 */
79 ERROR,
80 /**
81 * A violation of the constraint represents a serious fault in the content that
82 * will prevent typical use of the content.
83 */
84 CRITICAL;
85 }
86
87 /**
88 * Get the default level to use if no level is provided.
89 *
90 * @return the default level
91 */
92 @NonNull
93 static Level defaultLevel() {
94 return Level.ERROR;
95 }
96
97 /**
98 * Get the Metapath to use if no target is provided.
99 *
100 * @return the expression
101 */
102 @NonNull
103 static IMetapathExpression defaultTarget() {
104 return IMetapathExpression.contextNode();
105 }
106
107 /**
108 * Get a string that identifies the provided constraint using the most specific
109 * information available.
110 *
111 * @param constraint
112 * the constraint to identify
113 * @return the constraint identification statement
114 */
115 @NonNull
116 static String getConstraintIdentity(@NonNull IConstraint constraint) {
117 String identity;
118 if (constraint.getId() != null) {
119 identity = String.format("with id '%s'", constraint.getId());
120 } else if (constraint.getFormalName() != null) {
121 identity = String.format("with the formal name '%s'", constraint.getFormalName());
122 } else {
123 identity = String.format("targeting '%s'", constraint.getTarget().getPath());
124 }
125 return ObjectUtils.notNull(identity);
126 }
127
128 /**
129 * Get the constraint type.
130 *
131 * @return the constraint type
132 */
133 @NonNull
134 Type getType();
135
136 /**
137 * Retrieve the unique identifier for the constraint.
138 *
139 * @return the identifier or {@code null} if no identifier is defined
140 */
141 @Nullable
142 String getId();
143
144 /**
145 * Get information about the source of the constraint.
146 *
147 * @return the source information
148 */
149 @NonNull
150 ISource getSource();
151
152 /**
153 * The significance of a violation of this constraint.
154 *
155 * @return the level
156 */
157 @NonNull
158 Level getLevel();
159
160 /**
161 * Retrieve the Metapath expression to use to query the targets of the
162 * constraint.
163 *
164 * @return a Metapath expression
165 */
166 @NonNull
167 IMetapathExpression getTarget();
168
169 /**
170 * Based on the provided {@code contextNodeItem}, find all nodes matching the
171 * target expression.
172 *
173 * @param item
174 * the node item to evaluate the target expression against
175 * @param dynamicContext
176 * the Metapath evaluation context to use
177 * @return the matching nodes as a sequence
178 * @throws MetapathException
179 * if an error occurred during evaluation
180 * @see #getTarget()
181 */
182 @NonNull
183 ISequence<? extends IDefinitionNodeItem<?, ?>> matchTargets(
184 @NonNull IDefinitionNodeItem<?, ?> item,
185 @NonNull DynamicContext dynamicContext);
186
187 /**
188 * Retrieve the remarks associated with the constraint.
189 *
190 * @return the remarks or {@code null} if no remarks are defined
191 */
192 MarkupMultiline getRemarks();
193
194 /**
195 * Used for double dispatch supporting the visitor pattern provided by
196 * implementations of {@link IConstraintVisitor}.
197 *
198 * @param <T>
199 * the Java type of a state object passed to the visitor
200 * @param <R>
201 * the Java type of the result returned by the visitor methods
202 * @param visitor
203 * the visitor implementation
204 * @param state
205 * the state object passed to the visitor
206 * @return the visitation result
207 * @see IConstraintVisitor
208 */
209 <T, R> R accept(@NonNull IConstraintVisitor<T, R> visitor, T state);
210 }