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