001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
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    
025    /**
026     * @author Shuyang Zhou
027     */
028    public class DistributedRegistry {
029    
030            public static boolean isDistributed(String name, Direction direction) {
031                    Direction registeredDirection = _exactDirections.get(name);
032    
033                    if ((registeredDirection == direction) ||
034                            (registeredDirection == Direction.DUPLEX)) {
035    
036                            return true;
037                    }
038    
039                    if (registeredDirection != null) {
040                            return false;
041                    }
042    
043                    for (Map.Entry<String, Direction> entry :
044                                    _postfixDirections.entrySet()) {
045    
046                            String postfix = entry.getKey();
047    
048                            if (name.endsWith(postfix)) {
049                                    registeredDirection = entry.getValue();
050    
051                                    if ((registeredDirection == direction) ||
052                                            (registeredDirection == Direction.DUPLEX)) {
053    
054                                            return true;
055                                    }
056                            }
057                    }
058    
059                    for (Map.Entry<String, Direction> entry :
060                                    _prefixDirections.entrySet()) {
061    
062                            String prefix = entry.getKey();
063    
064                            if (name.startsWith(prefix)) {
065                                    registeredDirection = entry.getValue();
066    
067                                    if ((registeredDirection == direction) ||
068                                            (registeredDirection == Direction.DUPLEX)) {
069    
070                                            return true;
071                                    }
072                            }
073                    }
074    
075                    return false;
076            }
077    
078            public static void registerDistributed(Class<?> clazz) {
079                    Queue<Class<?>> queue = new LinkedList<Class<?>>();
080    
081                    queue.offer(clazz);
082    
083                    Class<?> currentClass = null;
084    
085                    while ((currentClass = queue.poll()) != null) {
086                            Field[] fields = currentClass.getDeclaredFields();
087    
088                            for (Field field : fields) {
089                                    Distributed distributed = field.getAnnotation(
090                                            Distributed.class);
091    
092                                    if (distributed == null) {
093                                            continue;
094                                    }
095    
096                                    int modifiers = field.getModifiers();
097    
098                                    if (!Modifier.isPublic(modifiers) ||
099                                            !Modifier.isStatic(modifiers) ||
100                                            !Modifier.isFinal(modifiers) ||
101                                            (field.getType() != String.class)) {
102    
103                                            continue;
104                                    }
105    
106                                    try {
107                                            String name = (String)field.get(null);
108    
109                                            registerDistributed(
110                                                    name, distributed.direction(), distributed.matchType());
111                                    }
112                                    catch (Throwable t) {
113                                            throw new RuntimeException(t);
114                                    }
115                            }
116    
117                            Class<?> supperClass = currentClass.getSuperclass();
118    
119                            if ((supperClass != null) && (supperClass != Object.class)) {
120                                    queue.offer(supperClass);
121                            }
122    
123                            Class<?>[] interfaceClasses = currentClass.getInterfaces();
124    
125                            for (Class<?> interfaceClass : interfaceClasses) {
126                                    if (!queue.contains(interfaceClass)) {
127                                            queue.offer(interfaceClass);
128                                    }
129                            }
130                    }
131            }
132    
133            public static void registerDistributed(
134                    String name, Direction direction, MatchType matchType) {
135    
136                    if (matchType.equals(MatchType.POSTFIX)) {
137                            _postfixDirections.put(name, direction);
138                    }
139                    else if (matchType.equals(MatchType.PREFIX)) {
140                            _prefixDirections.put(name, direction);
141                    }
142                    else {
143                            _exactDirections.put(name, direction);
144                    }
145            }
146    
147            private static Map<String, Direction> _exactDirections =
148                    new ConcurrentHashMap<String, Direction>();
149            private static Map<String, Direction> _postfixDirections =
150                    new ConcurrentHashMap<String, Direction>();
151            private static Map<String, Direction> _prefixDirections =
152                    new ConcurrentHashMap<String, Direction>();
153    
154    }