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 flex.messaging.messages.RemotingMessage; 024 025import org.granite.config.flex.Destination; 026import org.granite.config.flex.DestinationRemoveListener; 027import org.granite.context.GraniteContext; 028 029import java.util.Collections; 030import java.util.HashSet; 031import java.util.Map; 032import java.util.Set; 033 034/** 035 * @author Franck WOLFF 036 */ 037public class SimpleServiceFactory extends ServiceFactory implements DestinationRemoveListener { 038 039 private Set<String> invalidKeys = new HashSet<String>(); 040 041 042 @Override 043 public ServiceInvoker<?> getServiceInstance(RemotingMessage request) throws ServiceException { 044 String messageType = request.getClass().getName(); 045 String destinationId = request.getDestination(); 046 047 GraniteContext context = GraniteContext.getCurrentInstance(); 048 Destination destination = context.getServicesConfig().findDestinationById(messageType, destinationId); 049 if (destination == null) 050 throw new ServiceException("No matching destination: " + destinationId); 051 052 destination.addRemoveListener(this); 053 Map<String, Object> cache = getCache(destination); 054 055 String key = SimpleServiceInvoker.class.getName() + '.' + destination.getId(); 056 if (invalidKeys.contains(key)) { 057 cache.remove(key); 058 invalidKeys.remove(key); 059 } 060 061 SimpleServiceInvoker service = (SimpleServiceInvoker)cache.get(key); 062 if (service == null) { 063 service = new SimpleServiceInvoker(destination, this); 064 cache.put(key, service); 065 } 066 return service; 067 } 068 069 public void destinationRemoved(Destination destination) throws ServiceException { 070 synchronized (invalidKeys) { 071 invalidKeys.add(SimpleServiceInvoker.class.getName() + '.' + destination.getId()); 072 } 073 } 074 075 076 private Map<String, Object> getCache(Destination destination) throws ServiceException { 077 GraniteContext context = GraniteContext.getCurrentInstance(); 078 String scope = destination.getProperties().get("scope"); 079 080 Map<String, Object> cache = null; 081 if (scope == null || "request".equals(scope)) 082 cache = context.getRequestMap(); 083 else if ("session".equals(scope)) 084 cache = context.getSessionMap(); 085 else if ("application".equals(scope)) 086 cache = Collections.synchronizedMap(context.getApplicationMap()); 087 else 088 throw new ServiceException("Illegal scope in destination: " + destination); 089 090 return cache; 091 } 092}