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 return direction != null;
109 }
110
111 return _postfixDirections.remove(name, direction);
112 }
113 else if (matchType.equals(MatchType.PREFIX)) {
114 if (direction == null) {
115 direction = _prefixDirections.remove(name);
116
117 return direction != null;
118 }
119
120 return _prefixDirections.remove(name, direction);
121 }
122 else {
123 if (direction == null) {
124 direction = _exactDirections.remove(name);
125
126 return direction != null;
127 }
128
129 return _exactDirections.remove(name, direction);
130 }
131 }
132
133 protected static void processDistributed(Class<?> clazz, boolean register) {
134 Queue<Class<?>> queue = new LinkedList<Class<?>>();
135
136 queue.offer(clazz);
137
138 Class<?> currentClass = null;
139
140 while ((currentClass = queue.poll()) != null) {
141 Field[] fields = currentClass.getDeclaredFields();
142
143 for (Field field : fields) {
144 Distributed distributed = field.getAnnotation(
145 Distributed.class);
146
147 if (distributed == null) {
148 continue;
149 }
150
151 int modifiers = field.getModifiers();
152
153 if (!Modifier.isPublic(modifiers) ||
154 !Modifier.isStatic(modifiers) ||
155 !Modifier.isFinal(modifiers) ||
156 (field.getType() != String.class)) {
157
158 continue;
159 }
160
161 try {
162 String name = (String)field.get(null);
163
164 if (register) {
165 registerDistributed(
166 name, distributed.direction(),
167 distributed.matchType());
168 }
169 else {
170 unregisterDistributed(
171 name, distributed.direction(),
172 distributed.matchType());
173 }
174 }
175 catch (Throwable t) {
176 throw new RuntimeException(t);
177 }
178 }
179
180 Class<?> supperClass = currentClass.getSuperclass();
181
182 if ((supperClass != null) && (supperClass != Object.class)) {
183 queue.offer(supperClass);
184 }
185
186 Class<?>[] interfaceClasses = currentClass.getInterfaces();
187
188 for (Class<?> interfaceClass : interfaceClasses) {
189 if (!queue.contains(interfaceClass)) {
190 queue.offer(interfaceClass);
191 }
192 }
193 }
194 }
195
196 private static ConcurrentMap<String, Direction> _exactDirections =
197 new ConcurrentHashMap<String, Direction>();
198 private static ConcurrentMap<String, Direction> _postfixDirections =
199 new ConcurrentHashMap<String, Direction>();
200 private static ConcurrentMap<String, Direction> _prefixDirections =
201 new ConcurrentHashMap<String, Direction>();
202
203 }