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