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.util.Map; 024 025import javax.naming.InitialContext; 026 027import org.granite.config.flex.Destination; 028import org.granite.context.GraniteContext; 029import org.granite.messaging.service.ExtendedServiceExceptionHandler; 030import org.granite.messaging.service.ServiceException; 031import org.granite.messaging.service.ServiceFactory; 032import org.granite.messaging.service.ServiceInvoker; 033import org.granite.scan.ScannedItemHandler; 034import org.granite.tide.TideServiceInvoker; 035import org.granite.tide.data.PersistenceExceptionConverter; 036import org.granite.util.XMap; 037 038import flex.messaging.messages.RemotingMessage; 039 040 041/** 042 * @author William DRAI 043 */ 044public class EjbServiceFactory extends ServiceFactory { 045 046 public static final String ENTITY_MANAGER_FACTORY_JNDI_NAME = "entity-manager-factory-jndi-name"; 047 public static final String ENTITY_MANAGER_JNDI_NAME = "entity-manager-jndi-name"; 048 049 private String lookup = null; 050 private InitialContext initialContext = null; 051 052 public static ScannedItemHandler getScannedItemHandler() { 053 return EjbScannedItemHandler.instance(true); 054 } 055 056 public String getLookup() { 057 return lookup; 058 } 059 060 public void setInitialContext(InitialContext ic) { 061 this.initialContext = ic; 062 } 063 064 065 @Override 066 public void configure(XMap properties) throws ServiceException { 067 String sServiceExceptionHandler = properties.get("service-exception-handler"); 068 if (sServiceExceptionHandler == null) { 069 XMap props = new XMap(properties); 070 props.put("service-exception-handler", ExtendedServiceExceptionHandler.class.getName()); 071 super.configure(props); 072 } 073 else 074 super.configure(properties); 075 076 GraniteContext graniteContext = GraniteContext.getCurrentInstance(); 077 graniteContext.getGraniteConfig().registerExceptionConverter(PersistenceExceptionConverter.class); 078 graniteContext.getGraniteConfig().registerExceptionConverter(EJBAccessExceptionConverter.class); 079 080 this.lookup = properties.get("lookup"); 081 } 082 083 084 @Override 085 public ServiceInvoker<?> getServiceInstance(RemotingMessage request) throws ServiceException { 086 String messageType = request.getClass().getName(); 087 String destinationId = request.getDestination(); 088 089 GraniteContext context = GraniteContext.getCurrentInstance(); 090 Map<String, Object> cache = context.getSessionMap(); 091 Destination destination = context.getServicesConfig().findDestinationById(messageType, destinationId); 092 String key = TideServiceInvoker.class.getName() + '.' + destinationId; 093 094 return getServiceInvoker(cache, destination, key); 095 } 096 097 private ServiceInvoker<?> getServiceInvoker(Map<String, Object> cache, Destination destination, String key) { 098 GraniteContext context = GraniteContext.getCurrentInstance(); 099 synchronized (context.getSessionLock()) { 100 ServiceInvoker<?> invoker = (ServiceInvoker<?>)cache.get(key); 101 if (invoker == null) { 102 String lookup = getLookup(); 103 104 if (destination.getProperties().containsKey("lookup")) 105 lookup = destination.getProperties().get("lookup"); 106 107 EjbServiceContext tideContext = new EjbServiceContext(lookup, initialContext); 108 109 if (destination.getProperties().containsKey(ENTITY_MANAGER_FACTORY_JNDI_NAME)) { 110 tideContext.setEntityManagerFactoryJndiName(destination.getProperties().get(ENTITY_MANAGER_FACTORY_JNDI_NAME)); 111 } 112 else if (destination.getProperties().containsKey(ENTITY_MANAGER_JNDI_NAME)) { 113 tideContext.setEntityManagerJndiName(destination.getProperties().get(ENTITY_MANAGER_JNDI_NAME)); 114 } 115 116 invoker = new TideServiceInvoker<EjbServiceFactory>(destination, this, tideContext); 117 cache.put(key, invoker); 118 } 119 return invoker; 120 } 121 } 122}