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
021package org.granite.tide.ejb;
022
023import java.lang.reflect.Method;
024import java.util.HashMap;
025import java.util.HashSet;
026import java.util.Map;
027import java.util.Set;
028
029import javax.ejb.Local;
030import javax.ejb.Remote;
031import javax.ejb.Stateful;
032import javax.ejb.Stateless;
033
034import org.granite.logging.Logger;
035import org.granite.scan.ScannedItem;
036import org.granite.scan.ScannedItemHandler;
037import org.granite.tide.util.Observer;
038
039/**
040 * @author Franck WOLFF
041 */
042public 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}