1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.netty.util;
18
19 import static io.netty.util.internal.ObjectUtil.checkNotNull;
20 import static io.netty.util.internal.ObjectUtil.checkNonEmpty;
21
22 import java.util.concurrent.ConcurrentHashMap;
23 import java.util.concurrent.ConcurrentMap;
24 import java.util.concurrent.atomic.AtomicInteger;
25
26
27
28
29
30
31 public abstract class ConstantPool<T extends Constant<T>> {
32
33 private final ConcurrentMap<String, T> constants = new ConcurrentHashMap<>();
34
35 private final AtomicInteger nextId = new AtomicInteger(1);
36
37
38
39
40 public T valueOf(Class<?> firstNameComponent, String secondNameComponent) {
41 return valueOf(
42 checkNotNull(firstNameComponent, "firstNameComponent").getName() +
43 '#' +
44 checkNotNull(secondNameComponent, "secondNameComponent"));
45 }
46
47
48
49
50
51
52
53
54
55 public T valueOf(String name) {
56 return getOrCreate(checkNonEmpty(name, "name"));
57 }
58
59
60
61
62
63
64 private T getOrCreate(String name) {
65 T constant = constants.get(name);
66 if (constant == null) {
67 final T tempConstant = newConstant(nextId(), name);
68 constant = constants.putIfAbsent(name, tempConstant);
69 if (constant == null) {
70 return tempConstant;
71 }
72 }
73
74 return constant;
75 }
76
77
78
79
80 public boolean exists(String name) {
81 return constants.containsKey(checkNonEmpty(name, "name"));
82 }
83
84
85
86
87
88 public T newInstance(String name) {
89 return createOrThrow(checkNonEmpty(name, "name"));
90 }
91
92
93
94
95
96
97 private T createOrThrow(String name) {
98 T constant = constants.get(name);
99 if (constant == null) {
100 final T tempConstant = newConstant(nextId(), name);
101 constant = constants.putIfAbsent(name, tempConstant);
102 if (constant == null) {
103 return tempConstant;
104 }
105 }
106
107 throw new IllegalArgumentException(String.format("'%s' is already in use", name));
108 }
109
110 protected abstract T newConstant(int id, String name);
111
112 @Deprecated
113 public final int nextId() {
114 return nextId.getAndIncrement();
115 }
116 }