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.datatype.markup.MarkupLine;
30 import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline;
31 import gov.nist.secauto.metaschema.core.model.AbstractModule;
32 import gov.nist.secauto.metaschema.core.model.IAssemblyDefinition;
33 import gov.nist.secauto.metaschema.core.model.IFieldDefinition;
34 import gov.nist.secauto.metaschema.core.model.IFlagContainer;
35 import gov.nist.secauto.metaschema.core.model.IFlagDefinition;
36 import gov.nist.secauto.metaschema.core.model.IModule;
37 import gov.nist.secauto.metaschema.core.model.MetaschemaException;
38 import gov.nist.secauto.metaschema.core.model.xml.xmlbeans.GlobalAssemblyDefinitionType;
39 import gov.nist.secauto.metaschema.core.model.xml.xmlbeans.GlobalFieldDefinitionType;
40 import gov.nist.secauto.metaschema.core.model.xml.xmlbeans.GlobalFlagDefinitionType;
41 import gov.nist.secauto.metaschema.core.model.xml.xmlbeans.METASCHEMADocument;
42 import gov.nist.secauto.metaschema.core.model.xml.xmlbeans.METASCHEMADocument.METASCHEMA;
43 import gov.nist.secauto.metaschema.core.util.ObjectUtils;
44
45 import org.apache.logging.log4j.LogManager;
46 import org.apache.logging.log4j.Logger;
47 import org.apache.xmlbeans.XmlCursor;
48
49 import java.net.URI;
50 import java.util.Collection;
51 import java.util.Collections;
52 import java.util.LinkedHashMap;
53 import java.util.List;
54 import java.util.Map;
55 import java.util.Objects;
56 import java.util.stream.Collectors;
57 import java.util.stream.Stream;
58
59 import edu.umd.cs.findbugs.annotations.NonNull;
60
61 @SuppressWarnings("PMD.CouplingBetweenObjects")
62 class XmlModule
63 extends AbstractModule {
64 private static final Logger LOGGER = LogManager.getLogger(XmlModule.class);
65
66 @NonNull
67 private final URI location;
68 @NonNull
69 private final METASCHEMADocument module;
70 private final Map<String, ? extends IFlagDefinition> flagDefinitions;
71 private final Map<String, ? extends IFieldDefinition> fieldDefinitions;
72 private final Map<String, ? extends IAssemblyDefinition> assemblyDefinitions;
73 private final Map<String, ? extends IAssemblyDefinition> rootAssemblyDefinitions;
74
75
76
77
78
79
80
81
82
83
84
85
86
87 XmlModule(
88 @NonNull URI resource,
89 @NonNull METASCHEMADocument moduleXml,
90 @NonNull List<IModule> importedModules) throws MetaschemaException {
91 super(importedModules);
92 this.location = ObjectUtils.requireNonNull(resource, "resource");
93 Objects.requireNonNull(moduleXml.getMETASCHEMA());
94 this.module = moduleXml;
95
96 METASCHEMA metaschemaNode = module.getMETASCHEMA();
97
98
99 {
100
101 try (XmlCursor cursor = metaschemaNode.newCursor()) {
102 cursor.selectPath("declare namespace m='http://csrc.nist.gov/ns/oscal/metaschema/1.0';$this/m:define-flag");
103
104 Map<String, IFlagDefinition> flagDefinitions = new LinkedHashMap<>();
105 while (cursor.toNextSelection()) {
106 GlobalFlagDefinitionType obj = ObjectUtils.notNull((GlobalFlagDefinitionType) cursor.getObject());
107 XmlGlobalFlagDefinition flag = new XmlGlobalFlagDefinition(obj, this);
108 if (LOGGER.isTraceEnabled()) {
109 LOGGER.trace("New flag definition '{}'", flag.toCoordinates());
110 }
111 flagDefinitions.put(flag.getName(), flag);
112 }
113 this.flagDefinitions
114 = flagDefinitions.isEmpty() ? Collections.emptyMap() : Collections.unmodifiableMap(flagDefinitions);
115 }
116 }
117
118 {
119
120 try (XmlCursor cursor = metaschemaNode.newCursor()) {
121 cursor.selectPath("declare namespace m='http://csrc.nist.gov/ns/oscal/metaschema/1.0';$this/m:define-field");
122
123 Map<String, IFieldDefinition> fieldDefinitions = new LinkedHashMap<>();
124 while (cursor.toNextSelection()) {
125 GlobalFieldDefinitionType obj = ObjectUtils.notNull((GlobalFieldDefinitionType) cursor.getObject());
126 XmlGlobalFieldDefinition field = new XmlGlobalFieldDefinition(obj, this);
127 if (LOGGER.isTraceEnabled()) {
128 LOGGER.trace("New field definition '{}'", field.toCoordinates());
129 }
130 fieldDefinitions.put(field.getName(), field);
131 }
132 this.fieldDefinitions
133 = fieldDefinitions.isEmpty() ? Collections.emptyMap() : Collections.unmodifiableMap(fieldDefinitions);
134 }
135 }
136
137 {
138
139 Map<String, IAssemblyDefinition> assemblyDefinitions = new LinkedHashMap<>();
140 Map<String, IAssemblyDefinition> rootAssemblyDefinitions = new LinkedHashMap<>();
141
142 try (XmlCursor cursor = metaschemaNode.newCursor()) {
143 cursor.selectPath(
144 "declare namespace m='http://csrc.nist.gov/ns/oscal/metaschema/1.0';$this/m:define-assembly");
145
146 while (cursor.toNextSelection()) {
147 GlobalAssemblyDefinitionType obj = ObjectUtils.notNull((GlobalAssemblyDefinitionType) cursor.getObject());
148 XmlGlobalAssemblyDefinition assembly = new XmlGlobalAssemblyDefinition(obj, this);
149 if (LOGGER.isTraceEnabled()) {
150 LOGGER.trace("New assembly definition '{}'", assembly.toCoordinates());
151 }
152 assemblyDefinitions.put(assembly.getName(), assembly);
153 if (assembly.isRoot()) {
154 rootAssemblyDefinitions.put(ObjectUtils.notNull(assembly.getRootName()), assembly);
155 }
156 }
157
158 this.assemblyDefinitions
159 = assemblyDefinitions.isEmpty() ? Collections.emptyMap() : Collections.unmodifiableMap(assemblyDefinitions);
160 this.rootAssemblyDefinitions = rootAssemblyDefinitions.isEmpty() ? Collections.emptyMap()
161 : Collections.unmodifiableMap(rootAssemblyDefinitions);
162 }
163 }
164 }
165
166 @NonNull
167 @Override
168 public URI getLocation() {
169 return location;
170 }
171
172
173
174
175
176
177 @NonNull
178 protected METASCHEMADocument.METASCHEMA getXmlModule() {
179 return ObjectUtils.notNull(module.getMETASCHEMA());
180 }
181
182 @SuppressWarnings("null")
183 @Override
184 public MarkupLine getName() {
185 return MarkupStringConverter.toMarkupString(getXmlModule().getSchemaName());
186 }
187
188 @SuppressWarnings("null")
189 @Override
190 public String getVersion() {
191 return getXmlModule().getSchemaVersion();
192 }
193
194 @SuppressWarnings("null")
195 @Override
196 public MarkupMultiline getRemarks() {
197 return getXmlModule().isSetRemarks() ? MarkupStringConverter.toMarkupString(getXmlModule().getRemarks())
198 : null;
199 }
200
201 @SuppressWarnings("null")
202 @Override
203 public String getShortName() {
204 return getXmlModule().getShortName();
205 }
206
207 @SuppressWarnings("null")
208 @Override
209 public URI getXmlNamespace() {
210 return URI.create(getXmlModule().getNamespace());
211 }
212
213 @SuppressWarnings("null")
214 @Override
215 public URI getJsonBaseUri() {
216 return URI.create(getXmlModule().getJsonBaseUri());
217 }
218
219 private Map<String, ? extends IAssemblyDefinition> getAssemblyDefinitionMap() {
220 return assemblyDefinitions;
221 }
222
223 @SuppressWarnings("null")
224 @Override
225 public Collection<? extends IAssemblyDefinition> getAssemblyDefinitions() {
226 return getAssemblyDefinitionMap().values();
227 }
228
229 @Override
230 public IAssemblyDefinition getAssemblyDefinitionByName(@NonNull String name) {
231 return getAssemblyDefinitionMap().get(name);
232 }
233
234 private Map<String, ? extends IFieldDefinition> getFieldDefinitionMap() {
235 return fieldDefinitions;
236 }
237
238 @SuppressWarnings("null")
239 @Override
240 public Collection<? extends IFieldDefinition> getFieldDefinitions() {
241 return getFieldDefinitionMap().values();
242 }
243
244 @Override
245 public IFieldDefinition getFieldDefinitionByName(@NonNull String name) {
246 return getFieldDefinitionMap().get(name);
247 }
248
249 @SuppressWarnings("null")
250 @Override
251 public List<? extends IFlagContainer> getAssemblyAndFieldDefinitions() {
252 return Stream.concat(getAssemblyDefinitions().stream(), getFieldDefinitions().stream())
253 .collect(Collectors.toList());
254 }
255
256 private Map<String, ? extends IFlagDefinition> getFlagDefinitionMap() {
257 return flagDefinitions;
258 }
259
260 @SuppressWarnings("null")
261 @Override
262 public Collection<? extends IFlagDefinition> getFlagDefinitions() {
263 return getFlagDefinitionMap().values();
264 }
265
266 @Override
267 public IFlagDefinition getFlagDefinitionByName(@NonNull String name) {
268 return getFlagDefinitionMap().get(name);
269 }
270
271 private Map<String, ? extends IAssemblyDefinition> getRootAssemblyDefinitionMap() {
272 return rootAssemblyDefinitions;
273 }
274
275 @SuppressWarnings("null")
276 @Override
277 public Collection<? extends IAssemblyDefinition> getRootAssemblyDefinitions() {
278 return getRootAssemblyDefinitionMap().values();
279 }
280 }