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