001    /**
002     *   GRANITE DATA SERVICES
003     *   Copyright (C) 2006-2013 GRANITE DATA SERVICES S.A.S.
004     *
005     *   This file is part of the Granite Data Services Platform.
006     *
007     *   Granite Data Services is free software; you can redistribute it and/or
008     *   modify it under the terms of the GNU Lesser General Public
009     *   License as published by the Free Software Foundation; either
010     *   version 2.1 of the License, or (at your option) any later version.
011     *
012     *   Granite Data Services is distributed in the hope that it will be useful,
013     *   but WITHOUT ANY WARRANTY; without even the implied warranty of
014     *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
015     *   General Public License for more details.
016     *
017     *   You should have received a copy of the GNU Lesser General Public
018     *   License along with this library; if not, write to the Free Software
019     *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
020     *   USA, or see <http://www.gnu.org/licenses/>.
021     */
022    package org.granite.tide.ejb;
023    
024    import java.lang.reflect.Method;
025    import java.util.HashMap;
026    import java.util.HashSet;
027    import java.util.Map;
028    import java.util.Set;
029    
030    import javax.ejb.Local;
031    import javax.ejb.Remote;
032    import javax.ejb.Stateful;
033    import javax.ejb.Stateless;
034    
035    import org.granite.logging.Logger;
036    import org.granite.scan.ScannedItem;
037    import org.granite.scan.ScannedItemHandler;
038    import org.granite.tide.util.Observer;
039    
040    /**
041     * @author Franck WOLFF
042     */
043    public class EjbScannedItemHandler implements ScannedItemHandler {
044    
045            private static final Logger log = Logger.getLogger(EjbScannedItemHandler.class);
046            private static final EjbScannedItemHandler instance = new EjbScannedItemHandler();
047            
048            private final Map<Class<?>, Class<?>> scannedClasses = new HashMap<Class<?>, Class<?>>();
049            private final Map<String, Set<Method>> observers = new HashMap<String, Set<Method>>();
050            
051            public static EjbScannedItemHandler instance() {
052                    return instance;
053            }
054            
055            static EjbScannedItemHandler instance(boolean reset) {
056                    instance.scannedClasses.clear();
057                    instance.observers.clear();
058                    return instance;
059            }
060            
061            private EjbScannedItemHandler() {
062            }
063            
064            public boolean handleMarkerItem(ScannedItem item) {
065                    return false;
066            }
067    
068            public void handleScannedItem(ScannedItem item) {
069                    if ("class".equals(item.getExtension()) && item.getName().indexOf('$') == -1) {
070                            try {
071                                    Class<?> clazz = item.loadAsClass();
072                                    if (clazz.isAnnotationPresent(Stateless.class) || clazz.isAnnotationPresent(Stateful.class)) {
073                                            scannedClasses.put(clazz, clazz);       // Interface-less EJB 3.1
074                                            if (clazz.isAnnotationPresent(Local.class)) {
075                                                    for (Class<?> i : clazz.getAnnotation(Local.class).value())
076                                                            scannedClasses.put(i, clazz);
077                                            }
078                                            if (clazz.isAnnotationPresent(Remote.class)) {
079                                                    for (Class<?> i : clazz.getAnnotation(Remote.class).value())
080                                                            scannedClasses.put(i, clazz);
081                                            }
082                                for (Class<?> i : clazz.getInterfaces()) {
083                                    if (i.isAnnotationPresent(Local.class))
084                                            scannedClasses.put(i, clazz);
085                                    if (i.isAnnotationPresent(Remote.class))
086                                            scannedClasses.put(i, clazz);
087                                }
088                                            
089                                            for (Method method : clazz.getMethods()) {
090                                                    if (method.isAnnotationPresent(Observer.class)) {
091                                                            Observer o = method.getAnnotation(Observer.class);
092                                                            Set<Method> methods = observers.get(o.value());
093                                                            if (methods == null) {
094                                                                    methods = new HashSet<Method>();
095                                                                    observers.put(o.value(), methods);
096                                                            }
097                                                            methods.add(method);
098                                                    }
099                                            }
100                                    }
101                            }
102                            catch (Exception e) {
103                                    log.debug(e, "Could not introspect scanned item: %s", item);
104                            }
105                    }
106            }
107            
108            public Map<Class<?>, Class<?>> getScannedClasses() {
109                    return scannedClasses;
110            }
111            
112            public Map<String, Set<Method>> getObservers() {
113                    return observers;
114            }
115    }