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