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