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 */
022package org.granite.messaging.service;
023
024import java.lang.reflect.Method;
025import java.util.HashMap;
026import java.util.Map;
027
028import javax.ejb.Remove;
029import javax.ejb.Stateful;
030
031import org.granite.util.TypeUtil;
032import org.granite.util.XMap;
033
034/**
035 * @author Franck WOLFF
036 */
037public class EjbServiceMetadata {
038
039        private boolean stateful = false;
040        private final Map<Method, Boolean> removeMethods = new HashMap<Method, Boolean>();
041        
042        /**
043         * Default constructor. Should only be used by the externalization mechanism.
044         */
045        public EjbServiceMetadata() {
046        }
047        
048        public EjbServiceMetadata(Class<?> scannedClass, Class<?> invokeeClass) {
049                stateful = scannedClass.isAnnotationPresent(Stateful.class);
050                
051                if (stateful) {
052                        for (Method method : scannedClass.getMethods()) {
053                                Remove remove = method.getAnnotation(Remove.class);
054                                if (remove != null) {
055                                        try {
056                                                method = invokeeClass.getMethod(method.getName(), method.getParameterTypes());
057                                                removeMethods.put(method, Boolean.valueOf(remove.retainIfException()));
058                                        } catch (Exception e) {
059                                                // ignore (invokee interface may not expose this remove method)...
060                                        }
061                                }
062                        }
063                }
064        }
065        
066        public EjbServiceMetadata(XMap properties, Class<?> invokeeClass) {
067                stateful = properties.containsKey("ejb-stateful");
068                
069                if (stateful) {
070                        for (XMap removeMethod : properties.getAll("ejb-stateful/remove-method")) {
071                                
072                                String signature = removeMethod.get("signature");
073                                if (signature == null)
074                                        throw new ServiceException("Missing signature in remove-method declaration: " + properties);
075                                
076                                Boolean retainIfException = Boolean.valueOf(removeMethod.get("retain-if-exception"));
077
078                                try {
079                                        removeMethods.put(TypeUtil.getMethod(invokeeClass, signature), retainIfException);
080                                }
081                                catch (NoSuchMethodException e) {
082                                        throw new ServiceException("Could not find method: " + invokeeClass.getName() + "." + signature);
083                                }
084                        }
085                }
086        }
087
088        public boolean isStateful() {
089                return stateful;
090        }
091        
092        public boolean isRemoveMethod(Method method) {
093                return removeMethods.containsKey(method);
094        }
095        
096        public boolean getRetainIfException(Method method) {
097                return removeMethods.get(method).booleanValue();
098        }
099}