1
2
3
4
5
6 package gov.nist.secauto.metaschema.core.qname;
7
8 import gov.nist.secauto.metaschema.core.util.ObjectUtils;
9
10 import java.net.URI;
11 import java.util.Map;
12 import java.util.Optional;
13 import java.util.concurrent.ConcurrentHashMap;
14 import java.util.concurrent.atomic.AtomicInteger;
15
16 import edu.umd.cs.findbugs.annotations.NonNull;
17 import nl.talsmasoftware.lazy4j.Lazy;
18
19
20
21
22
23 public final class NamespaceCache {
24 @NonNull
25 private static final Lazy<NamespaceCache> INSTANCE = ObjectUtils.notNull(Lazy.lazy(NamespaceCache::new));
26
27 private final Map<String, Integer> nsToIndex = new ConcurrentHashMap<>();
28 private final Map<Integer, String> indexToNs = new ConcurrentHashMap<>();
29 private final Map<Integer, URI> indexToNsUri = new ConcurrentHashMap<>();
30
31
32
33
34
35 private final AtomicInteger indexCounter = new AtomicInteger();
36
37
38
39
40
41
42 @NonNull
43 public static NamespaceCache instance() {
44 return ObjectUtils.notNull(INSTANCE.get());
45 }
46
47 private NamespaceCache() {
48
49 int noNamespaceIndex = indexOf("");
50 assert noNamespaceIndex == 0;
51 }
52
53
54
55
56
57
58
59
60 @SuppressWarnings("PMD.ShortMethodName")
61 public int indexOf(@NonNull String namespace) {
62 return nsToIndex.computeIfAbsent(namespace, key -> {
63 int nextIndex = indexCounter.getAndIncrement();
64 indexToNs.put(nextIndex, namespace);
65 return nextIndex;
66 });
67 }
68
69
70
71
72
73
74
75
76 @NonNull
77 public Optional<Integer> get(@NonNull String namespace) {
78 return ObjectUtils.notNull(Optional.ofNullable(nsToIndex.get(namespace)));
79 }
80
81
82
83
84
85
86
87
88 @NonNull
89 public Optional<String> get(int index) {
90 return ObjectUtils.notNull(Optional.ofNullable(indexToNs.get(index)));
91 }
92
93
94
95
96
97
98
99
100
101 @NonNull
102 public Optional<URI> getAsURI(int index) {
103 return ObjectUtils.notNull(Optional.ofNullable(indexToNsUri.computeIfAbsent(index, key -> {
104 Optional<String> namespace = get(key);
105 URI nsUri = null;
106 if (namespace.isPresent()) {
107 nsUri = URI.create(namespace.get());
108 indexToNsUri.put(key, nsUri);
109 }
110 return nsUri;
111 })));
112 }
113 }