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