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 javax.ejb.NoSuchEJBException; 025import javax.naming.NamingException; 026 027import org.granite.config.flex.Destination; 028import org.granite.logging.Logger; 029 030/** 031 * @author Franck WOLFF 032 */ 033public class EjbServiceInvoker extends ServiceInvoker<EjbServiceFactory> { 034 035 private static final Logger log = Logger.getLogger(EjbServiceInvoker.class); 036 037 public static final String CAPITALIZED_DESTINATION_ID = "{capitalized.destination.id}"; 038 public static final String DESTINATION_ID = "{destination.id}"; 039 040 private final EjbServiceMetadata metadata; 041 042 public EjbServiceInvoker(Destination destination, EjbServiceFactory factory) throws ServiceException { 043 super(destination, factory); 044 045 String lookup = factory.getLookup(); 046 if (destination.getProperties().containsKey("lookup")) 047 lookup = destination.getProperties().get("lookup"); 048 049 // Compute EJB JNDI binding. 050 String name = destination.getId(); 051 if (lookup != null) { 052 name = lookup; 053 if (lookup.contains(CAPITALIZED_DESTINATION_ID)) 054 name = lookup.replace(CAPITALIZED_DESTINATION_ID, capitalize(destination.getId())); 055 if (lookup.contains(DESTINATION_ID)) 056 name = lookup.replace(DESTINATION_ID, destination.getId()); 057 } 058 059 log.debug(">> New EjbServiceInvoker looking up: %s", name); 060 061 try { 062 invokee = factory.lookup(name); 063 } catch (NamingException e) { 064 throw new ServiceException("Could not lookup for: " + name, e); 065 } 066 067 this.metadata = destination.getScannedClass() != null ? 068 new EjbServiceMetadata(destination.getScannedClass(), invokee.getClass()) : 069 new EjbServiceMetadata(destination.getProperties(), invokee.getClass()); 070 } 071 072 public EjbServiceMetadata getMetadata() { 073 return metadata; 074 } 075 076 @Override 077 protected void afterInvocationError(ServiceInvocationContext context, Throwable error) { 078 // "A NoSuchEJBException is thrown if an attempt is made to invoke a method 079 // on an object that no longer exists" (javadoc on NoSuchEJBException). 080 if (error instanceof NoSuchEJBException || ( 081 metadata.isStateful() && 082 metadata.isRemoveMethod(context.getMethod()) && 083 !metadata.getRetainIfException(context.getMethod()) 084 )) 085 factory.removeFromCache(destination.getId()); 086 } 087 088 @Override 089 protected Object afterInvocation(ServiceInvocationContext context, Object result) { 090 if (metadata.isStateful() && metadata.isRemoveMethod(context.getMethod())) 091 factory.removeFromCache(destination.getId()); 092 return result; 093 } 094 095 private String capitalize(String s) { 096 if (s == null || s.length() == 0) 097 return s; 098 if (s.length() == 1) 099 return s.toUpperCase(); 100 return s.substring(0, 1).toUpperCase() + s.substring(1); 101 } 102}