1
2
3
4
5
6 package gov.nist.secauto.metaschema.databind.model;
7
8 import gov.nist.secauto.metaschema.core.metapath.StaticContext;
9 import gov.nist.secauto.metaschema.core.model.AbstractModule;
10 import gov.nist.secauto.metaschema.core.model.IBoundObject;
11 import gov.nist.secauto.metaschema.core.model.ISource;
12 import gov.nist.secauto.metaschema.core.qname.IEnhancedQName;
13 import gov.nist.secauto.metaschema.core.util.ObjectUtils;
14 import gov.nist.secauto.metaschema.databind.IBindingContext;
15 import gov.nist.secauto.metaschema.databind.model.annotations.MetaschemaModule;
16 import gov.nist.secauto.metaschema.databind.model.annotations.NsBinding;
17
18 import java.lang.reflect.Array;
19 import java.util.Arrays;
20 import java.util.Collection;
21 import java.util.Collections;
22 import java.util.LinkedHashMap;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.function.Function;
26 import java.util.stream.Collectors;
27
28 import edu.umd.cs.findbugs.annotations.NonNull;
29 import nl.talsmasoftware.lazy4j.Lazy;
30
31 public abstract class AbstractBoundModule
32 extends AbstractModule<
33 IBoundModule,
34 IBoundDefinitionModelComplex,
35 IBoundDefinitionFlag,
36 IBoundDefinitionModelField<?>,
37 IBoundDefinitionModelAssembly>
38 implements IBoundModule {
39 @NonNull
40 private final IBindingContext bindingContext;
41 @NonNull
42 private final Lazy<Map<Integer, IBoundDefinitionModelAssembly>> assemblyDefinitions;
43 @NonNull
44 private final Lazy<Map<Integer, IBoundDefinitionModelField<?>>> fieldDefinitions;
45 @NonNull
46 private final Lazy<StaticContext> staticContext;
47 @NonNull
48 private final ISource source;
49
50
51
52
53
54
55
56
57
58 protected AbstractBoundModule(
59 @NonNull List<? extends IBoundModule> importedModules,
60 @NonNull IBindingContext bindingContext) {
61 super(importedModules);
62 this.bindingContext = bindingContext;
63 this.assemblyDefinitions = ObjectUtils.notNull(Lazy.lazy(() -> Arrays.stream(getAssemblyClasses())
64 .map(clazz -> {
65 assert clazz != null;
66 return (IBoundDefinitionModelAssembly) ObjectUtils
67 .requireNonNull(bindingContext.getBoundDefinitionForClass(clazz));
68 })
69 .collect(Collectors.toUnmodifiableMap(
70 def -> def.getDefinitionQName().getIndexPosition(),
71 Function.identity()))));
72 this.fieldDefinitions = ObjectUtils.notNull(Lazy.lazy(() -> Arrays.stream(getFieldClasses())
73 .map(clazz -> {
74 assert clazz != null;
75 return (IBoundDefinitionModelField<?>) ObjectUtils
76 .requireNonNull(bindingContext.getBoundDefinitionForClass(clazz));
77 })
78 .collect(Collectors.toUnmodifiableMap(
79 def -> def.getDefinitionQName().getIndexPosition(),
80 Function.identity()))));
81 this.staticContext = ObjectUtils.notNull(Lazy.lazy(() -> {
82 StaticContext.Builder builder = StaticContext.builder()
83 .defaultModelNamespace(getXmlNamespace());
84
85 getNamespaceBindings()
86 .forEach(
87 (prefix, ns) -> builder.namespace(
88 ObjectUtils.requireNonNull(prefix),
89 ObjectUtils.requireNonNull(ns)));
90 return builder.build();
91 }));
92 this.source = ISource.moduleSource(this);
93 }
94
95 @Override
96 public ISource getSource() {
97 return source;
98 }
99
100 @Override
101 public String getLocationHint() {
102 return ObjectUtils.notNull(getClass().getName());
103 }
104
105 @Override
106 public StaticContext getModuleStaticContext() {
107 return ObjectUtils.notNull(staticContext.get());
108 }
109
110 @Override
111 @NonNull
112 public IBindingContext getBindingContext() {
113 return bindingContext;
114 }
115
116 @Override
117 public Map<String, String> getNamespaceBindings() {
118 return ObjectUtils.notNull(Arrays.stream(getNsBindings())
119 .collect(Collectors.toMap(
120 NsBinding::prefix,
121 NsBinding::uri,
122 (v1, v2) -> v2,
123 LinkedHashMap::new)));
124 }
125
126 @SuppressWarnings({ "null" })
127 @NonNull
128 protected NsBinding[] getNsBindings() {
129 return getClass().isAnnotationPresent(MetaschemaModule.class)
130 ? getClass().getAnnotation(MetaschemaModule.class).nsBindings()
131 : (NsBinding[]) Array.newInstance(NsBinding.class, 0);
132 }
133
134
135
136
137
138
139
140 @SuppressWarnings({ "null", "unchecked" })
141 @NonNull
142 protected Class<? extends IBoundObject>[] getAssemblyClasses() {
143 return getClass().isAnnotationPresent(MetaschemaModule.class)
144 ? getClass().getAnnotation(MetaschemaModule.class).assemblies()
145 : (Class<? extends IBoundObject>[]) Array.newInstance(Class.class, 0);
146 }
147
148
149
150
151
152
153 @SuppressWarnings({ "null", "unchecked" })
154 @NonNull
155 protected Class<? extends IBoundObject>[] getFieldClasses() {
156 return getClass().isAnnotationPresent(MetaschemaModule.class)
157 ? getClass().getAnnotation(MetaschemaModule.class).fields()
158 : (Class<? extends IBoundObject>[]) Array.newInstance(Class.class, 0);
159 }
160
161
162
163
164
165
166 protected Map<Integer, IBoundDefinitionModelAssembly> getAssemblyDefinitionMap() {
167 return assemblyDefinitions.get();
168 }
169
170 @SuppressWarnings("null")
171 @Override
172 public Collection<IBoundDefinitionModelAssembly> getAssemblyDefinitions() {
173 return getAssemblyDefinitionMap().values();
174 }
175
176 @Override
177 public IBoundDefinitionModelAssembly getAssemblyDefinitionByName(@NonNull Integer name) {
178 return getAssemblyDefinitionMap().get(name);
179 }
180
181
182
183
184
185
186 protected Map<Integer, IBoundDefinitionModelField<?>> getFieldDefinitionMap() {
187 return fieldDefinitions.get();
188 }
189
190 @SuppressWarnings("null")
191 @Override
192 public Collection<IBoundDefinitionModelField<?>> getFieldDefinitions() {
193 return getFieldDefinitionMap().values();
194 }
195
196 @Override
197 public IBoundDefinitionModelField<?> getFieldDefinitionByName(@NonNull Integer name) {
198 return getFieldDefinitionMap().get(name);
199 }
200
201 @SuppressWarnings("null")
202 @Override
203 public Collection<IBoundDefinitionFlag> getFlagDefinitions() {
204
205 return Collections.emptyList();
206 }
207
208 @Override
209 public IBoundDefinitionFlag getFlagDefinitionByName(@NonNull IEnhancedQName name) {
210
211 return null;
212 }
213 }