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.gravity.adapters; 023 024import java.io.Serializable; 025import java.util.ArrayList; 026import java.util.List; 027import java.util.Map; 028import java.util.concurrent.ConcurrentHashMap; 029import java.util.concurrent.locks.ReentrantLock; 030 031import org.granite.config.flex.Adapter; 032import org.granite.config.flex.Destination; 033import org.granite.context.GraniteContext; 034import org.granite.gravity.Gravity; 035import org.granite.logging.Logger; 036import org.granite.messaging.service.ServiceException; 037import org.granite.util.TypeUtil; 038 039import flex.messaging.messages.AsyncMessage; 040import flex.messaging.messages.CommandMessage; 041import flex.messaging.messages.Message; 042 043/** 044 * @author William DRAI 045 */ 046public class AdapterFactory implements Serializable { 047 048 private static final long serialVersionUID = 1L; 049 050 051 private static final Logger log = Logger.getLogger(AdapterFactory.class); 052 private static final ReentrantLock lock = new ReentrantLock(); 053 054 private Gravity gravity; 055 private Map<String, ServiceAdapter> adaptersCache = new ConcurrentHashMap<String, ServiceAdapter>(); 056 private List<ServiceAdapter> adapters = new ArrayList<ServiceAdapter>(); 057 private static Class<SimpleServiceAdapter> defaultAdapterClass = SimpleServiceAdapter.class; 058 059 060 public AdapterFactory(Gravity gravity) { 061 this.gravity = gravity; 062 } 063 064 065 public ServiceAdapter getServiceAdapter(Message request) throws ServiceException { 066 067 String messageType = request.getClass().getName(); 068 if (request instanceof CommandMessage) 069 messageType = ((CommandMessage)request).getMessageRefType(); 070 if (messageType == null) 071 messageType = AsyncMessage.class.getName(); 072 String destinationId = request.getDestination(); 073 074 return getServiceAdapter(messageType, destinationId); 075 } 076 077 public ServiceAdapter getServiceAdapter(String messageType, String destinationId) throws ServiceException { 078 GraniteContext context = GraniteContext.getCurrentInstance(); 079 080 log.debug(">> Finding serviceAdapter for messageType: %s and destinationId: %s", messageType, destinationId); 081 082 Destination destination = context.getServicesConfig().findDestinationById(messageType, destinationId); 083 if (destination == null) { 084 log.debug(">> No destination found: %s", destinationId); 085 return null; 086 } 087 Adapter adapter = destination.getAdapter(); 088 089 String key = null; 090 091 if (adapter != null) { 092 log.debug(">> Found adapterRef: %s", adapter.getId()); 093 key = AdapterFactory.class.getName() + '@' + destination.getId() + '.' + adapter.getId(); 094 } 095 else 096 key = defaultAdapterClass.getName() + '@' + destination.getId(); 097 098 return getServiceAdapter(adaptersCache, context, destination, key, adapter != null ? adapter.getId() : null); 099 } 100 101 private ServiceAdapter getServiceAdapter(Map<String, ServiceAdapter> cache, GraniteContext context, Destination destination, String key, String adapterId) { 102 lock.lock(); 103 try { 104 ServiceAdapter serviceAdapter = cache.get(key); 105 if (serviceAdapter == null) { 106 log.debug(">> No cached factory for: %s", adapterId); 107 108 Adapter config = destination.getAdapter(); 109 try { 110 Class<? extends ServiceAdapter> clazz = (adapterId != null) 111 ? TypeUtil.forName(config.getClassName(), ServiceAdapter.class) 112 : defaultAdapterClass; 113 serviceAdapter = clazz.newInstance(); 114 serviceAdapter.setId(adapterId); 115 serviceAdapter.setGravity(gravity); 116 serviceAdapter.configure(config.getProperties(), destination.getProperties()); 117 serviceAdapter.start(); 118 119 adapters.add(serviceAdapter); 120 } 121 catch (ServiceException e) { 122 throw e; 123 } 124 catch (Exception e) { 125 throw new ServiceException("Could not instantiate serviceAdapter: " + config, e); 126 } 127 cache.put(key, serviceAdapter); 128 } 129 else 130 log.debug(">> Found a cached serviceAdapter for ref: %s", destination.getAdapter()); 131 132 log.debug("<< Returning serviceAdapter: %s", serviceAdapter); 133 134 serviceAdapter.setDestination(destination); 135 return serviceAdapter; 136 } finally { 137 lock.unlock(); 138 } 139 } 140 141 142 public void stopAll() { 143 for (ServiceAdapter adapter : adapters) { 144 adapter.stop(); 145 } 146 } 147 148 149 @Override 150 public String toString() { 151 return toString(null); 152 } 153 154 public String toString(String append) { 155 return super.toString() + " {" + 156 (append != null ? append : "") + 157 "\n}"; 158 } 159}