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
021 package org.granite.messaging.service;
022
023 import flex.messaging.messages.RemotingMessage;
024
025 import org.granite.config.flex.Destination;
026 import org.granite.config.flex.DestinationRemoveListener;
027 import org.granite.context.GraniteContext;
028
029 import java.util.Collections;
030 import java.util.HashSet;
031 import java.util.Map;
032 import java.util.Set;
033
034 /**
035 * @author Franck WOLFF
036 */
037 public 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 }