1
2
3
4
5
6 package gov.nist.secauto.metaschema.databind.model.metaschema.impl;
7
8 import gov.nist.secauto.metaschema.core.metapath.item.node.INodeItemFactory;
9 import gov.nist.secauto.metaschema.core.model.IAssemblyInstanceAbsolute;
10 import gov.nist.secauto.metaschema.core.model.IChoiceInstance;
11 import gov.nist.secauto.metaschema.core.model.IContainerModelSupport;
12 import gov.nist.secauto.metaschema.core.model.IFieldInstanceAbsolute;
13 import gov.nist.secauto.metaschema.core.model.IModelInstanceAbsolute;
14 import gov.nist.secauto.metaschema.core.model.INamedModelInstanceAbsolute;
15 import gov.nist.secauto.metaschema.core.util.CollectionUtil;
16 import gov.nist.secauto.metaschema.core.util.ObjectUtils;
17 import gov.nist.secauto.metaschema.databind.model.IBoundInstanceModelChoiceGroup;
18 import gov.nist.secauto.metaschema.databind.model.IBoundInstanceModelGroupedAssembly;
19 import gov.nist.secauto.metaschema.databind.model.metaschema.binding.AssemblyReference;
20 import gov.nist.secauto.metaschema.databind.model.metaschema.binding.FieldReference;
21 import gov.nist.secauto.metaschema.databind.model.metaschema.binding.InlineDefineAssembly;
22 import gov.nist.secauto.metaschema.databind.model.metaschema.binding.InlineDefineField;
23 import gov.nist.secauto.metaschema.databind.model.metaschema.binding.AssemblyModel.Choice;
24
25 import java.util.LinkedHashMap;
26 import java.util.LinkedList;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.concurrent.atomic.AtomicInteger;
30
31 import javax.xml.namespace.QName;
32
33 import edu.umd.cs.findbugs.annotations.NonNull;
34 import edu.umd.cs.findbugs.annotations.Nullable;
35 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
36
37 class ChoiceModelContainerSupport
38 extends AbstractBindingModelContainerSupport {
39 @NonNull
40 private final List<IModelInstanceAbsolute> modelInstances;
41 @NonNull
42 private final Map<QName, INamedModelInstanceAbsolute> namedModelInstances;
43 @NonNull
44 private final Map<QName, IFieldInstanceAbsolute> fieldInstances;
45 @NonNull
46 private final Map<QName, IAssemblyInstanceAbsolute> assemblyInstances;
47
48 @SuppressWarnings("PMD.ShortMethodName")
49 public static IContainerModelSupport<
50 IModelInstanceAbsolute,
51 INamedModelInstanceAbsolute,
52 IFieldInstanceAbsolute,
53 IAssemblyInstanceAbsolute> of(
54 @Nullable Choice binding,
55 @NonNull IBoundInstanceModelGroupedAssembly bindingInstance,
56 @NonNull IChoiceInstance parent,
57 @NonNull INodeItemFactory nodeItemFactory) {
58 List<Object> instances;
59 return binding == null || (instances = binding.getChoices()) == null || instances.isEmpty()
60 ? IContainerModelSupport.empty()
61 : new ChoiceModelContainerSupport(
62 binding,
63 bindingInstance,
64 parent,
65 nodeItemFactory);
66 }
67
68
69
70
71
72
73
74
75
76
77
78
79
80 @SuppressWarnings({ "PMD.AvoidInstantiatingObjectsInLoops", "PMD.UseConcurrentHashMap", "PMD.PrematureDeclaration" })
81 @SuppressFBWarnings(value = "CT_CONSTRUCTOR_THROW", justification = "Use of final fields")
82 public ChoiceModelContainerSupport(
83 @NonNull Choice binding,
84 @NonNull IBoundInstanceModelGroupedAssembly bindingInstance,
85 @NonNull IChoiceInstance parent,
86 @NonNull INodeItemFactory nodeItemFactory) {
87
88
89 final List<IModelInstanceAbsolute> modelInstances = new LinkedList<>();
90 final Map<QName, INamedModelInstanceAbsolute> namedModelInstances = new LinkedHashMap<>();
91 final Map<QName, IFieldInstanceAbsolute> fieldInstances = new LinkedHashMap<>();
92 final Map<QName, IAssemblyInstanceAbsolute> assemblyInstances = new LinkedHashMap<>();
93
94
95 AtomicInteger assemblyReferencePosition = new AtomicInteger();
96 AtomicInteger assemblyInlineDefinitionPosition = new AtomicInteger();
97 AtomicInteger fieldReferencePosition = new AtomicInteger();
98 AtomicInteger fieldInlineDefinitionPosition = new AtomicInteger();
99
100
101 IBoundInstanceModelChoiceGroup instance = ObjectUtils.requireNonNull(
102 bindingInstance.getDefinition().getChoiceGroupInstanceByName("choices"));
103
104 ObjectUtils.notNull(binding.getChoices()).forEach(obj -> {
105 assert obj != null;
106 IBoundInstanceModelGroupedAssembly objInstance
107 = (IBoundInstanceModelGroupedAssembly) instance.getItemInstance(obj);
108
109 if (obj instanceof AssemblyReference) {
110 addInstance(
111 newInstance(
112 (AssemblyReference) obj,
113 objInstance,
114 assemblyReferencePosition.getAndIncrement(),
115 parent),
116 modelInstances,
117 namedModelInstances,
118 assemblyInstances);
119 } else if (obj instanceof InlineDefineAssembly) {
120 IAssemblyInstanceAbsolute assembly = new InstanceModelAssemblyInline(
121 (InlineDefineAssembly) obj,
122 objInstance,
123 assemblyInlineDefinitionPosition.getAndIncrement(),
124 parent,
125 nodeItemFactory);
126 addInstance(assembly, modelInstances, namedModelInstances, assemblyInstances);
127 } else if (obj instanceof FieldReference) {
128 IFieldInstanceAbsolute field = newInstance(
129 (FieldReference) obj,
130 objInstance,
131 fieldReferencePosition.getAndIncrement(),
132 parent);
133 addInstance(field, modelInstances, namedModelInstances, fieldInstances);
134 } else if (obj instanceof InlineDefineField) {
135 IFieldInstanceAbsolute field = new InstanceModelFieldInline(
136 (InlineDefineField) obj,
137 objInstance,
138 fieldInlineDefinitionPosition.getAndIncrement(),
139 parent);
140 addInstance(field, modelInstances, namedModelInstances, fieldInstances);
141 } else {
142 throw new UnsupportedOperationException(String.format("Unknown model instance class: %s", obj.getClass()));
143 }
144 });
145
146 this.modelInstances = modelInstances.isEmpty()
147 ? CollectionUtil.emptyList()
148 : CollectionUtil.unmodifiableList(modelInstances);
149 this.namedModelInstances = namedModelInstances.isEmpty()
150 ? CollectionUtil.emptyMap()
151 : CollectionUtil.unmodifiableMap(namedModelInstances);
152 this.fieldInstances = fieldInstances.isEmpty()
153 ? CollectionUtil.emptyMap()
154 : CollectionUtil.unmodifiableMap(fieldInstances);
155 this.assemblyInstances = assemblyInstances.isEmpty()
156 ? CollectionUtil.emptyMap()
157 : CollectionUtil.unmodifiableMap(assemblyInstances);
158 }
159
160 @Override
161 public List<IModelInstanceAbsolute> getModelInstances() {
162 return modelInstances;
163 }
164
165 @Override
166 public Map<QName, INamedModelInstanceAbsolute> getNamedModelInstanceMap() {
167 return namedModelInstances;
168 }
169
170 @Override
171 public Map<QName, IFieldInstanceAbsolute> getFieldInstanceMap() {
172 return fieldInstances;
173 }
174
175 @Override
176 public Map<QName, IAssemblyInstanceAbsolute> getAssemblyInstanceMap() {
177 return assemblyInstances;
178 }
179 }