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.xml;
28
29 import gov.nist.secauto.metaschema.core.metapath.MetapathException;
30 import gov.nist.secauto.metaschema.core.model.constraint.DefaultAllowedValuesConstraint;
31 import gov.nist.secauto.metaschema.core.model.constraint.DefaultExpectConstraint;
32 import gov.nist.secauto.metaschema.core.model.constraint.DefaultIndexHasKeyConstraint;
33 import gov.nist.secauto.metaschema.core.model.constraint.DefaultMatchesConstraint;
34 import gov.nist.secauto.metaschema.core.model.constraint.IAllowedValuesConstraint;
35 import gov.nist.secauto.metaschema.core.model.constraint.IConstraint;
36 import gov.nist.secauto.metaschema.core.model.constraint.IConstraint.ISource;
37 import gov.nist.secauto.metaschema.core.model.constraint.IExpectConstraint;
38 import gov.nist.secauto.metaschema.core.model.constraint.IIndexHasKeyConstraint;
39 import gov.nist.secauto.metaschema.core.model.constraint.IMatchesConstraint;
40 import gov.nist.secauto.metaschema.core.model.constraint.IValueConstrained;
41 import gov.nist.secauto.metaschema.core.model.xml.xmlbeans.AllowedValuesType;
42 import gov.nist.secauto.metaschema.core.model.xml.xmlbeans.DefineFieldConstraintsType;
43 import gov.nist.secauto.metaschema.core.model.xml.xmlbeans.DefineFlagConstraintsType;
44 import gov.nist.secauto.metaschema.core.model.xml.xmlbeans.ExpectConstraintType;
45 import gov.nist.secauto.metaschema.core.model.xml.xmlbeans.IndexHasKeyConstraintType;
46 import gov.nist.secauto.metaschema.core.model.xml.xmlbeans.MatchesConstraintType;
47
48 import org.apache.xmlbeans.XmlCursor;
49 import org.apache.xmlbeans.XmlObject;
50 import org.apache.xmlbeans.impl.values.XmlValueNotSupportedException;
51
52 import java.util.LinkedList;
53 import java.util.List;
54
55 import edu.umd.cs.findbugs.annotations.NonNull;
56
57 class ValueConstraintSupport implements IValueConstrained {
58 private static final String PATH = "declare namespace m='http://csrc.nist.gov/ns/oscal/metaschema/1.0';"
59 + "$this/m:allowed-values|$this/m:matches|$this/m:index-has-key|$this/m:expect";
60
61 @NonNull
62 private final List<IConstraint> constraints = new LinkedList<>();
63 @NonNull
64 private final List<IAllowedValuesConstraint> allowedValuesConstraints = new LinkedList<>();
65 @NonNull
66 private final List<IMatchesConstraint> matchesConstraints = new LinkedList<>();
67 @NonNull
68 private final List<IIndexHasKeyConstraint> indexHasKeyConstraints = new LinkedList<>();
69 @NonNull
70 private final List<IExpectConstraint> expectConstraints = new LinkedList<>();
71
72 public ValueConstraintSupport() {
73
74 }
75
76
77
78
79
80
81
82
83
84 @SuppressWarnings("PMD.ConstructorCallsOverridableMethod")
85 public ValueConstraintSupport(
86 @NonNull DefineFlagConstraintsType xmlConstraints,
87 @NonNull ISource source) {
88 try (XmlCursor cursor = xmlConstraints.newCursor()) {
89 assert cursor != null;
90 parse(source, cursor, PATH);
91 }
92 }
93
94
95
96
97
98
99
100
101
102 @SuppressWarnings("PMD.ConstructorCallsOverridableMethod")
103 public ValueConstraintSupport(
104 @NonNull DefineFieldConstraintsType xmlConstraints,
105 @NonNull ISource source) {
106 try (XmlCursor cursor = xmlConstraints.newCursor()) {
107 assert cursor != null;
108 parse(source, cursor, PATH);
109 }
110 }
111
112 protected final void parse(
113 @NonNull ISource source,
114 @NonNull XmlCursor cursor,
115 @NonNull String path) {
116 try {
117 assert cursor != null;
118 cursor.selectPath(path);
119 while (cursor.toNextSelection()) {
120 XmlObject obj = cursor.getObject();
121 assert obj != null;
122 parseXmlObject(source, obj);
123 }
124 } catch (MetapathException | XmlValueNotSupportedException ex) {
125 if (ex.getCause() instanceof MetapathException) {
126 throw new MetapathException(
127 String.format("Unable to compile a Metapath in '%s'. %s",
128 source.getSource(),
129 ex.getLocalizedMessage()),
130 ex);
131 }
132 throw ex;
133 }
134 }
135
136 protected boolean parseXmlObject(
137 @NonNull ISource source,
138 @NonNull XmlObject obj) {
139 boolean handled = false;
140 if (obj instanceof AllowedValuesType) {
141 DefaultAllowedValuesConstraint constraint
142 = ModelFactory.newAllowedValuesConstraint((AllowedValuesType) obj, source);
143 addConstraint(constraint);
144 handled = true;
145 } else if (obj instanceof MatchesConstraintType) {
146 DefaultMatchesConstraint constraint
147 = ModelFactory.newMatchesConstraint((MatchesConstraintType) obj, source);
148 addConstraint(constraint);
149 handled = true;
150 } else if (obj instanceof IndexHasKeyConstraintType) {
151 DefaultIndexHasKeyConstraint constraint
152 = ModelFactory.newIndexHasKeyConstraint((IndexHasKeyConstraintType) obj, source);
153 addConstraint(constraint);
154 handled = true;
155 } else if (obj instanceof ExpectConstraintType) {
156 DefaultExpectConstraint constraint = ModelFactory.newExpectConstraint((ExpectConstraintType) obj, source);
157 addConstraint(constraint);
158 handled = true;
159 }
160 return handled;
161 }
162
163 @Override
164 public List<IConstraint> getConstraints() {
165 synchronized (this) {
166 return constraints;
167 }
168 }
169
170 @Override
171 public List<IAllowedValuesConstraint> getAllowedValuesConstraints() {
172 synchronized (this) {
173 return allowedValuesConstraints;
174 }
175 }
176
177 @Override
178 public List<IMatchesConstraint> getMatchesConstraints() {
179 synchronized (this) {
180 return matchesConstraints;
181 }
182 }
183
184 @Override
185 public List<IIndexHasKeyConstraint> getIndexHasKeyConstraints() {
186 synchronized (this) {
187 return indexHasKeyConstraints;
188 }
189 }
190
191 @Override
192 public List<IExpectConstraint> getExpectConstraints() {
193 synchronized (this) {
194 return expectConstraints;
195 }
196 }
197
198 @Override
199 public final void addConstraint(@NonNull IAllowedValuesConstraint constraint) {
200 synchronized (this) {
201 constraints.add(constraint);
202 allowedValuesConstraints.add(constraint);
203 }
204 }
205
206 @Override
207 public final void addConstraint(@NonNull IMatchesConstraint constraint) {
208 synchronized (this) {
209 constraints.add(constraint);
210 matchesConstraints.add(constraint);
211 }
212 }
213
214 @Override
215 public final void addConstraint(@NonNull IIndexHasKeyConstraint constraint) {
216 synchronized (this) {
217 constraints.add(constraint);
218 indexHasKeyConstraints.add(constraint);
219 }
220 }
221
222 @Override
223 public final void addConstraint(@NonNull IExpectConstraint constraint) {
224 synchronized (this) {
225 constraints.add(constraint);
226 expectConstraints.add(constraint);
227 }
228 }
229 }