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