1
2
3
4
5
6 package gov.nist.secauto.metaschema.core.metapath;
7
8 import gov.nist.secauto.metaschema.core.metapath.EQNameUtils.IEQNamePrefixResolver;
9 import gov.nist.secauto.metaschema.core.util.CollectionUtil;
10 import gov.nist.secauto.metaschema.core.util.ObjectUtils;
11
12 import java.net.URI;
13 import java.util.Map;
14 import java.util.concurrent.ConcurrentHashMap;
15 import java.util.stream.Collectors;
16
17 import javax.xml.XMLConstants;
18
19 import edu.umd.cs.findbugs.annotations.NonNull;
20 import edu.umd.cs.findbugs.annotations.Nullable;
21 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
22
23
24
25
26
27
28 public final class StaticContext {
29 @NonNull
30 private static final Map<String, URI> WELL_KNOWN_NAMESPACES;
31 @NonNull
32 private static final Map<String, String> WELL_KNOWN_URI_TO_PREFIX;
33
34 static {
35 Map<String, URI> knownNamespaces = new ConcurrentHashMap<>();
36 knownNamespaces.put(
37 MetapathConstants.PREFIX_METAPATH,
38 MetapathConstants.NS_METAPATH);
39 knownNamespaces.put(
40 MetapathConstants.PREFIX_XML_SCHEMA,
41 MetapathConstants.NS_XML_SCHEMA);
42 knownNamespaces.put(
43 MetapathConstants.PREFIX_XPATH_FUNCTIONS,
44 MetapathConstants.NS_METAPATH_FUNCTIONS);
45 knownNamespaces.put(
46 MetapathConstants.PREFIX_XPATH_FUNCTIONS_MATH,
47 MetapathConstants.NS_METAPATH_FUNCTIONS_MATH);
48 knownNamespaces.put(
49 MetapathConstants.PREFIX_XPATH_FUNCTIONS_ARRAY,
50 MetapathConstants.NS_METAPATH_FUNCTIONS_ARRAY);
51 knownNamespaces.put(
52 MetapathConstants.PREFIX_XPATH_FUNCTIONS_MAP,
53 MetapathConstants.NS_METAPATH_FUNCTIONS_MAP);
54 WELL_KNOWN_NAMESPACES = CollectionUtil.unmodifiableMap(knownNamespaces);
55
56 WELL_KNOWN_URI_TO_PREFIX = ObjectUtils.notNull(WELL_KNOWN_NAMESPACES.entrySet().stream()
57 .collect(Collectors.toUnmodifiableMap(
58 entry -> entry.getValue().toASCIIString(),
59 Map.Entry::getKey,
60 (v1, v2) -> v2)));
61 }
62
63 @Nullable
64 private final URI baseUri;
65 @NonNull
66 private final Map<String, URI> knownNamespaces;
67 @Nullable
68 private final URI defaultModelNamespace;
69 @Nullable
70 private final URI defaultFunctionNamespace;
71 private final boolean useWildcardWhenNamespaceNotDefaulted;
72
73
74
75
76
77
78
79
80
81
82 @SuppressFBWarnings("MS_EXPOSE_REP")
83 public static Map<String, URI> getWellKnownNamespacesMap() {
84 return WELL_KNOWN_NAMESPACES;
85 }
86
87
88
89
90
91
92
93 @SuppressFBWarnings("MS_EXPOSE_REP")
94 public static Map<String, String> getWellKnownURIToPrefixMap() {
95 return WELL_KNOWN_URI_TO_PREFIX;
96 }
97
98
99
100
101
102
103
104
105
106 @Nullable
107 public static String getWellKnownPrefixForUri(@NonNull String uri) {
108 return WELL_KNOWN_URI_TO_PREFIX.get(uri);
109 }
110
111
112
113
114
115
116 @NonNull
117 public static StaticContext instance() {
118 return builder().build();
119 }
120
121 private StaticContext(Builder builder) {
122 this.baseUri = builder.baseUri;
123 this.knownNamespaces = CollectionUtil.unmodifiableMap(ObjectUtils.notNull(Map.copyOf(builder.namespaces)));
124 this.defaultModelNamespace = builder.defaultModelNamespace;
125 this.defaultFunctionNamespace = builder.defaultFunctionNamespace;
126 this.useWildcardWhenNamespaceNotDefaulted = builder.useWildcardWhenNamespaceNotDefaulted;
127 }
128
129
130
131
132
133
134
135
136 @Nullable
137 public URI getBaseUri() {
138 synchronized (this) {
139 return baseUri;
140 }
141 }
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161 @Nullable
162 public URI lookupNamespaceURIForPrefix(@NonNull String prefix) {
163 URI retval = knownNamespaces.get(prefix);
164 if (retval == null) {
165
166 retval = WELL_KNOWN_NAMESPACES.get(prefix);
167 }
168 return retval;
169 }
170
171
172
173
174
175
176
177
178
179
180 @Nullable
181 public String lookupNamespaceForPrefix(@NonNull String prefix) {
182 URI result = lookupNamespaceURIForPrefix(prefix);
183 return result == null ? null : result.toASCIIString();
184 }
185
186
187
188
189
190
191
192 @Nullable
193 public URI getDefaultModelNamespace() {
194 return defaultModelNamespace;
195 }
196
197
198
199
200
201
202
203 @Nullable
204 public URI getDefaultFunctionNamespace() {
205 return defaultFunctionNamespace;
206 }
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224 @NonNull
225 public IEQNamePrefixResolver getFunctionPrefixResolver() {
226 return this::resolveFunctionPrefix;
227 }
228
229 @NonNull
230 private String resolveFunctionPrefix(@NonNull String prefix) {
231 String ns = lookupNamespaceForPrefix(prefix);
232 if (ns == null) {
233 URI uri = getDefaultFunctionNamespace();
234 if (uri != null) {
235 ns = uri.toASCIIString();
236 }
237 }
238 return ns == null ? XMLConstants.NULL_NS_URI : ns;
239 }
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255 @NonNull
256 public IEQNamePrefixResolver getFlagPrefixResolver() {
257 return this::resolveFlagReferencePrefix;
258 }
259
260 @NonNull
261 private String resolveFlagReferencePrefix(@NonNull String prefix) {
262 String ns = lookupNamespaceForPrefix(prefix);
263 return ns == null ? XMLConstants.NULL_NS_URI : ns;
264 }
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282 @NonNull
283 public IEQNamePrefixResolver getModelPrefixResolver() {
284 return this::resolveModelReferencePrefix;
285 }
286
287 @NonNull
288 private String resolveModelReferencePrefix(@NonNull String prefix) {
289 String ns = lookupNamespaceForPrefix(prefix);
290 if (ns == null) {
291 URI uri = getDefaultModelNamespace();
292 if (uri != null) {
293 ns = uri.toASCIIString();
294 }
295 }
296 return ns == null ? XMLConstants.NULL_NS_URI : ns;
297 }
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313 @NonNull
314 public IEQNamePrefixResolver getVariablePrefixResolver() {
315 return this::resolveVariablePrefix;
316 }
317
318 @NonNull
319 private String resolveVariablePrefix(@NonNull String prefix) {
320 String ns = lookupNamespaceForPrefix(prefix);
321 return ns == null ? XMLConstants.NULL_NS_URI : ns;
322 }
323
324
325
326
327
328
329
330 @NonNull
331 public Builder buildFrom() {
332 Builder builder = builder();
333 builder.baseUri = this.baseUri;
334 builder.namespaces.putAll(this.knownNamespaces);
335 builder.defaultModelNamespace = this.defaultModelNamespace;
336 builder.defaultFunctionNamespace = this.defaultFunctionNamespace;
337 return builder;
338 }
339
340
341
342
343
344
345
346
347
348 public boolean isUseWildcardWhenNamespaceNotDefaulted() {
349 return useWildcardWhenNamespaceNotDefaulted && getDefaultModelNamespace() == null;
350 }
351
352
353
354
355
356
357
358 @NonNull
359 public static Builder builder() {
360 return new Builder();
361 }
362
363
364
365
366 public static final class Builder {
367 public boolean useWildcardWhenNamespaceNotDefaulted;
368 @Nullable
369 private URI baseUri;
370 @NonNull
371 private final Map<String, URI> namespaces = new ConcurrentHashMap<>();
372 @Nullable
373 private URI defaultModelNamespace;
374 @Nullable
375 private URI defaultFunctionNamespace = MetapathConstants.NS_METAPATH_FUNCTIONS;
376
377 private Builder() {
378 namespaces.put(
379 MetapathConstants.PREFIX_METAPATH,
380 MetapathConstants.NS_METAPATH);
381 namespaces.put(
382 MetapathConstants.PREFIX_XML_SCHEMA,
383 MetapathConstants.NS_XML_SCHEMA);
384 namespaces.put(
385 MetapathConstants.PREFIX_XPATH_FUNCTIONS,
386 MetapathConstants.NS_METAPATH_FUNCTIONS);
387 namespaces.put(
388 MetapathConstants.PREFIX_XPATH_FUNCTIONS_MATH,
389 MetapathConstants.NS_METAPATH_FUNCTIONS_MATH);
390 }
391
392
393
394
395
396
397
398
399
400
401 @NonNull
402 public Builder baseUri(@NonNull URI uri) {
403 this.baseUri = uri;
404 return this;
405 }
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427 @NonNull
428 public Builder namespace(@NonNull String prefix, @NonNull URI uri) {
429 this.namespaces.put(prefix, uri);
430 return this;
431 }
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447 @NonNull
448 public Builder namespace(@NonNull String prefix, @NonNull String uri) {
449 return namespace(prefix, ObjectUtils.notNull(URI.create(uri)));
450 }
451
452
453
454
455
456
457
458
459
460
461 @NonNull
462 public Builder defaultModelNamespace(@NonNull URI uri) {
463 this.defaultModelNamespace = uri;
464 return this;
465 }
466
467
468
469
470
471
472
473
474
475
476
477 @NonNull
478 public Builder defaultModelNamespace(@NonNull String uri) {
479 return defaultModelNamespace(ObjectUtils.notNull(URI.create(uri)));
480 }
481
482
483
484
485
486
487
488
489
490
491 @NonNull
492 public Builder defaultFunctionNamespace(@NonNull URI uri) {
493 this.defaultFunctionNamespace = uri;
494 return this;
495 }
496
497
498
499
500
501
502
503
504
505
506
507 @NonNull
508 public Builder defaultFunctionNamespace(@NonNull String uri) {
509 return defaultFunctionNamespace(ObjectUtils.notNull(URI.create(uri)));
510 }
511
512
513
514
515
516
517
518
519 public Builder useWildcardWhenNamespaceNotDefaulted(boolean value) {
520 this.useWildcardWhenNamespaceNotDefaulted = value;
521 return this;
522 }
523
524
525
526
527
528
529 @NonNull
530 public StaticContext build() {
531 return new StaticContext(this);
532 }
533 }
534 }