001
014
015 package com.liferay.portal.kernel.resiliency.spi.agent.annotation;
016
017 import java.lang.reflect.Field;
018 import java.lang.reflect.Modifier;
019
020 import java.util.LinkedList;
021 import java.util.Map;
022 import java.util.Queue;
023 import java.util.concurrent.ConcurrentHashMap;
024 import java.util.concurrent.ConcurrentMap;
025
026
029 public class DistributedRegistry {
030
031 public static boolean isDistributed(String name, Direction direction) {
032 Direction registeredDirection = _exactDirections.get(name);
033
034 if ((registeredDirection == direction) ||
035 (registeredDirection == Direction.DUPLEX)) {
036
037 return true;
038 }
039
040 if (registeredDirection != null) {
041 return false;
042 }
043
044 for (Map.Entry<String, Direction> entry :
045 _postfixDirections.entrySet()) {
046
047 String postfix = entry.getKey();
048
049 if (name.endsWith(postfix)) {
050 registeredDirection = entry.getValue();
051
052 if ((registeredDirection == direction) ||
053 (registeredDirection == Direction.DUPLEX)) {
054
055 return true;
056 }
057 }
058 }
059
060 for (Map.Entry<String, Direction> entry :
061 _prefixDirections.entrySet()) {
062
063 String prefix = entry.getKey();
064
065 if (name.startsWith(prefix)) {
066 registeredDirection = entry.getValue();
067
068 if ((registeredDirection == direction) ||
069 (registeredDirection == Direction.DUPLEX)) {
070
071 return true;
072 }
073 }
074 }
075
076 return false;
077 }
078
079 public static void registerDistributed(Class<?> clazz) {
080 processDistributed(clazz, true);
081 }
082
083 public static void registerDistributed(
084 String name, Direction direction, MatchType matchType) {
085
086 if (matchType.equals(MatchType.POSTFIX)) {
087 _postfixDirections.put(name, direction);
088 }
089 else if (matchType.equals(MatchType.PREFIX)) {
090 _prefixDirections.put(name, direction);
091 }
092 else {
093 _exactDirections.put(name, direction);
094 }
095 }
096
097 public static void unregisterDistributed(Class<?> clazz) {
098 processDistributed(clazz, false);
099 }
100
101 public static boolean unregisterDistributed(
102 String name, Direction direction, MatchType matchType) {
103
104 if (matchType.equals(MatchType.POSTFIX)) {
105 if (direction == null) {
106 direction = _postfixDirections.remove(name);
107
108 if (direction != null) {
109 return true;
110 }
111
112 return false;
113 }
114
115 return _postfixDirections.remove(name, direction);
116 }
117 else if (matchType.equals(MatchType.PREFIX)) {
118 if (direction == null) {
119 direction = _prefixDirections.remove(name);
120
121 if (direction != null) {
122 return true;
123 }
124
125 return false;
126 }
127
128 return _prefixDirections.remove(name, direction);
129 }
130 else {
131 if (direction == null) {
132 direction = _exactDirections.remove(name);
133
134 if (direction != null) {
135 return true;
136 }
137
138 return false;
139 }
140
141 return _exactDirections.remove(name, direction);
142 }
143 }
144
145 protected static void processDistributed(Class<?> clazz, boolean register) {
146 Queue<Class<?>> queue = new LinkedList<>();
147
148 queue.offer(clazz);
149
150 Class<?> currentClass = null;
151
152 while ((currentClass = queue.poll()) != null) {
153 Field[] fields = currentClass.getDeclaredFields();
154
155 for (Field field : fields) {
156 Distributed distributed = field.getAnnotation(
157 Distributed.class);
158
159 if (distributed == null) {
160 continue;
161 }
162
163 int modifiers = field.getModifiers();
164
165 if (!Modifier.isPublic(modifiers) ||
166 !Modifier.isStatic(modifiers) ||
167 !Modifier.isFinal(modifiers) ||
168 (field.getType() != String.class)) {
169
170 continue;
171 }
172
173 try {
174 String name = (String)field.get(null);
175
176 if (register) {
177 registerDistributed(
178 name, distributed.direction(),
179 distributed.matchType());
180 }
181 else {
182 unregisterDistributed(
183 name, distributed.direction(),
184 distributed.matchType());
185 }
186 }
187 catch (Throwable t) {
188 throw new RuntimeException(t);
189 }
190 }
191
192 Class<?> supperClass = currentClass.getSuperclass();
193
194 if ((supperClass != null) && (supperClass != Object.class)) {
195 queue.offer(supperClass);
196 }
197
198 Class<?>[] interfaceClasses = currentClass.getInterfaces();
199
200 for (Class<?> interfaceClass : interfaceClasses) {
201 if (!queue.contains(interfaceClass)) {
202 queue.offer(interfaceClass);
203 }
204 }
205 }
206 }
207
208 private static final ConcurrentMap<String, Direction> _exactDirections =
209 new ConcurrentHashMap<>();
210 private static final ConcurrentMap<String, Direction> _postfixDirections =
211 new ConcurrentHashMap<>();
212 private static final ConcurrentMap<String, Direction> _prefixDirections =
213 new ConcurrentHashMap<>();
214
215 }