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.model.IAssemblyDefinition;
30 import gov.nist.secauto.metaschema.core.model.IFieldDefinition;
31 import gov.nist.secauto.metaschema.core.model.IFlagContainer;
32 import gov.nist.secauto.metaschema.core.model.IFlagContainerSupport;
33 import gov.nist.secauto.metaschema.core.model.IFlagInstance;
34 import gov.nist.secauto.metaschema.core.model.xml.xmlbeans.FlagReferenceType;
35 import gov.nist.secauto.metaschema.core.model.xml.xmlbeans.GlobalAssemblyDefinitionType;
36 import gov.nist.secauto.metaschema.core.model.xml.xmlbeans.GlobalFieldDefinitionType;
37 import gov.nist.secauto.metaschema.core.model.xml.xmlbeans.InlineAssemblyDefinitionType;
38 import gov.nist.secauto.metaschema.core.model.xml.xmlbeans.InlineFieldDefinitionType;
39 import gov.nist.secauto.metaschema.core.model.xml.xmlbeans.InlineFlagDefinitionType;
40 import gov.nist.secauto.metaschema.core.util.CollectionUtil;
41
42 import org.apache.xmlbeans.XmlCursor;
43 import org.apache.xmlbeans.XmlObject;
44
45 import java.util.Collections;
46 import java.util.LinkedHashMap;
47 import java.util.Map;
48
49 import edu.umd.cs.findbugs.annotations.NonNull;
50 import edu.umd.cs.findbugs.annotations.Nullable;
51
52 @SuppressWarnings("PMD.NullAssignment")
53 class XmlFlagContainerSupport implements IFlagContainerSupport<IFlagInstance> {
54
55 @NonNull
56 private final Map<String, IFlagInstance> flagInstances;
57 @Nullable
58 private final IFlagInstance jsonKeyFlag;
59
60
61
62
63
64
65
66
67
68 public XmlFlagContainerSupport(
69 @NonNull GlobalFieldDefinitionType xmlField,
70 @NonNull IFieldDefinition container) {
71
72 if (xmlField.getFlagList().size() > 0 || xmlField.getDefineFlagList().size() > 0) {
73 this.flagInstances = parseLocalFlags(xmlField, container);
74 } else {
75 this.flagInstances = CollectionUtil.emptyMap();
76 }
77 this.jsonKeyFlag = xmlField.isSetJsonKey() ? flagInstances.get(xmlField.getJsonKey().getFlagRef()) : null;
78 }
79
80
81
82
83
84
85
86
87
88 public XmlFlagContainerSupport(
89 @NonNull InlineFieldDefinitionType xmlField,
90 @NonNull IFieldDefinition container) {
91
92 if (xmlField.getFlagList().size() > 0 || xmlField.getDefineFlagList().size() > 0) {
93 this.flagInstances = parseLocalFlags(xmlField, container);
94 } else {
95 this.flagInstances = CollectionUtil.emptyMap();
96 }
97 this.jsonKeyFlag = xmlField.isSetJsonKey() ? flagInstances.get(xmlField.getJsonKey().getFlagRef()) : null;
98 }
99
100
101
102
103
104
105
106
107
108 public XmlFlagContainerSupport(
109 @NonNull GlobalAssemblyDefinitionType xmlAssembly,
110 @NonNull IAssemblyDefinition container) {
111
112 if (xmlAssembly.getFlagList().size() > 0 || xmlAssembly.getDefineFlagList().size() > 0) {
113 this.flagInstances = parseLocalFlags(xmlAssembly, container);
114 } else {
115 this.flagInstances = CollectionUtil.emptyMap();
116 }
117 this.jsonKeyFlag = xmlAssembly.isSetJsonKey() ? flagInstances.get(xmlAssembly.getJsonKey().getFlagRef()) : null;
118 }
119
120
121
122
123
124
125
126
127
128 public XmlFlagContainerSupport(
129 @NonNull InlineAssemblyDefinitionType xmlAssembly,
130 @NonNull IAssemblyDefinition container) {
131
132 if (xmlAssembly.getFlagList().size() > 0 || xmlAssembly.getDefineFlagList().size() > 0) {
133 this.flagInstances = parseLocalFlags(xmlAssembly, container);
134 } else {
135 this.flagInstances = CollectionUtil.emptyMap();
136 }
137 this.jsonKeyFlag = xmlAssembly.isSetJsonKey() ? flagInstances.get(xmlAssembly.getJsonKey().getFlagRef()) : null;
138 }
139
140
141
142
143
144
145 @Override
146 @NonNull
147 public Map<String, ? extends IFlagInstance> getFlagInstanceMap() {
148 return flagInstances;
149 }
150
151 @Override
152 public IFlagInstance getJsonKeyFlagInstance() {
153 return jsonKeyFlag;
154 }
155
156 @NonNull
157 private static Map<String, IFlagInstance> parseLocalFlags(@NonNull XmlObject xmlObject,
158 @NonNull IFlagContainer parent) {
159
160 Map<String, IFlagInstance> flagInstances = new LinkedHashMap<>();
161 try (XmlCursor cursor = xmlObject.newCursor()) {
162 cursor.selectPath(
163 "declare namespace m='http://csrc.nist.gov/ns/oscal/metaschema/1.0';" + "$this/m:flag|$this/m:define-flag");
164
165 while (cursor.toNextSelection()) {
166 XmlObject obj = cursor.getObject();
167 if (obj instanceof FlagReferenceType) {
168 XmlFlagInstance flagInstance = new XmlFlagInstance((FlagReferenceType) obj, parent);
169 flagInstances.put(flagInstance.getEffectiveName(), flagInstance);
170 } else if (obj instanceof InlineFlagDefinitionType) {
171 XmlInlineFlagDefinition flagInstance
172 = new XmlInlineFlagDefinition((InlineFlagDefinitionType) obj, parent);
173 flagInstances.put(flagInstance.getEffectiveName(), flagInstance);
174 }
175 }
176 }
177
178 @SuppressWarnings("null")
179 @NonNull Map<String, IFlagInstance> retval
180 = flagInstances.isEmpty() ? Collections.emptyMap() : Collections.unmodifiableMap(flagInstances);
181 return retval;
182 }
183 }