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 return baseUri;
139 }
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159 @Nullable
160 public URI lookupNamespaceURIForPrefix(@NonNull String prefix) {
161 URI retval = knownNamespaces.get(prefix);
162 if (retval == null) {
163
164 retval = WELL_KNOWN_NAMESPACES.get(prefix);
165 }
166 return retval;
167 }
168
169
170
171
172
173
174
175
176
177
178 @Nullable
179 public String lookupNamespaceForPrefix(@NonNull String prefix) {
180 URI result = lookupNamespaceURIForPrefix(prefix);
181 return result == null ? null : result.toASCIIString();
182 }
183
184
185
186
187
188
189
190 @Nullable
191 public URI getDefaultModelNamespace() {
192 return defaultModelNamespace;
193 }
194
195
196
197
198
199
200
201 @Nullable
202 public URI getDefaultFunctionNamespace() {
203 return defaultFunctionNamespace;
204 }
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222 @NonNull
223 public IEQNamePrefixResolver getFunctionPrefixResolver() {
224 return this::resolveFunctionPrefix;
225 }
226
227 @NonNull
228 private String resolveFunctionPrefix(@NonNull String prefix) {
229 String ns = lookupNamespaceForPrefix(prefix);
230 if (ns == null) {
231 URI uri = getDefaultFunctionNamespace();
232 if (uri != null) {
233 ns = uri.toASCIIString();
234 }
235 }
236 return ns == null ? XMLConstants.NULL_NS_URI : ns;
237 }
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253 @NonNull
254 public IEQNamePrefixResolver getFlagPrefixResolver() {
255 return this::resolveFlagReferencePrefix;
256 }
257
258 @NonNull
259 private String resolveFlagReferencePrefix(@NonNull String prefix) {
260 String ns = lookupNamespaceForPrefix(prefix);
261 return ns == null ? XMLConstants.NULL_NS_URI : ns;
262 }
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280 @NonNull
281 public IEQNamePrefixResolver getModelPrefixResolver() {
282 return this::resolveModelReferencePrefix;
283 }
284
285 @NonNull
286 private String resolveModelReferencePrefix(@NonNull String prefix) {
287 String ns = lookupNamespaceForPrefix(prefix);
288 if (ns == null) {
289 URI uri = getDefaultModelNamespace();
290 if (uri != null) {
291 ns = uri.toASCIIString();
292 }
293 }
294 return ns == null ? XMLConstants.NULL_NS_URI : ns;
295 }
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311 @NonNull
312 public IEQNamePrefixResolver getVariablePrefixResolver() {
313 return this::resolveVariablePrefix;
314 }
315
316 @NonNull
317 private String resolveVariablePrefix(@NonNull String prefix) {
318 String ns = lookupNamespaceForPrefix(prefix);
319 return ns == null ? XMLConstants.NULL_NS_URI : ns;
320 }
321
322
323
324
325
326
327
328 @NonNull
329 public Builder buildFrom() {
330 Builder builder = builder();
331 builder.baseUri = this.baseUri;
332 builder.namespaces.putAll(this.knownNamespaces);
333 builder.defaultModelNamespace = this.defaultModelNamespace;
334 builder.defaultFunctionNamespace = this.defaultFunctionNamespace;
335 return builder;
336 }
337
338
339
340
341
342
343
344
345
346 public boolean isUseWildcardWhenNamespaceNotDefaulted() {
347 return useWildcardWhenNamespaceNotDefaulted && getDefaultModelNamespace() == null;
348 }
349
350
351
352
353
354
355
356 @NonNull
357 public static Builder builder() {
358 return new Builder();
359 }
360
361
362
363
364 public static final class Builder {
365 public boolean useWildcardWhenNamespaceNotDefaulted;
366 @Nullable
367 private URI baseUri;
368 @NonNull
369 private final Map<String, URI> namespaces = new ConcurrentHashMap<>();
370 @Nullable
371 private URI defaultModelNamespace;
372 @Nullable
373 private URI defaultFunctionNamespace = MetapathConstants.NS_METAPATH_FUNCTIONS;
374
375 private Builder() {
376 namespaces.put(
377 MetapathConstants.PREFIX_METAPATH,
378 MetapathConstants.NS_METAPATH);
379 namespaces.put(
380 MetapathConstants.PREFIX_XML_SCHEMA,
381 MetapathConstants.NS_XML_SCHEMA);
382 namespaces.put(
383 MetapathConstants.PREFIX_XPATH_FUNCTIONS,
384 MetapathConstants.NS_METAPATH_FUNCTIONS);
385 namespaces.put(
386 MetapathConstants.PREFIX_XPATH_FUNCTIONS_MATH,
387 MetapathConstants.NS_METAPATH_FUNCTIONS_MATH);
388 }
389
390
391
392
393
394
395
396
397
398
399 @NonNull
400 public Builder baseUri(@NonNull URI uri) {
401 this.baseUri = uri;
402 return this;
403 }
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425 @NonNull
426 public Builder namespace(@NonNull String prefix, @NonNull URI uri) {
427 this.namespaces.put(prefix, uri);
428 return this;
429 }
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445 @NonNull
446 public Builder namespace(@NonNull String prefix, @NonNull String uri) {
447 return namespace(prefix, ObjectUtils.notNull(URI.create(uri)));
448 }
449
450
451
452
453
454
455
456
457
458
459 @NonNull
460 public Builder defaultModelNamespace(@NonNull URI uri) {
461 this.defaultModelNamespace = uri;
462 return this;
463 }
464
465
466
467
468
469
470
471
472
473
474
475 @NonNull
476 public Builder defaultModelNamespace(@NonNull String uri) {
477 return defaultModelNamespace(ObjectUtils.notNull(URI.create(uri)));
478 }
479
480
481
482
483
484
485
486
487
488
489 @NonNull
490 public Builder defaultFunctionNamespace(@NonNull URI uri) {
491 this.defaultFunctionNamespace = uri;
492 return this;
493 }
494
495
496
497
498
499
500
501
502
503
504
505 @NonNull
506 public Builder defaultFunctionNamespace(@NonNull String uri) {
507 return defaultFunctionNamespace(ObjectUtils.notNull(URI.create(uri)));
508 }
509
510
511
512
513
514
515
516
517 public Builder useWildcardWhenNamespaceNotDefaulted(boolean value) {
518 this.useWildcardWhenNamespaceNotDefaulted = value;
519 return this;
520 }
521
522
523
524
525
526
527 @NonNull
528 public StaticContext build() {
529 return new StaticContext(this);
530 }
531 }
532 }