/** * GRANITE DATA SERVICES * Copyright (C) 2006-2015 GRANITE DATA SERVICES S.A.S. * * This file is part of the Granite Data Services Platform. * * Granite Data Services is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * Granite Data Services is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser * General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA, or see <http://www.gnu.org/licenses/>. */ package org.granite.clustering; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.servlet.http.HttpSession; import flex.messaging.messages.AsyncMessage; import flex.messaging.messages.CommandMessage; /** * @author Franck WOLFF */ public class SessionDistributedData implements DistributedData { private static final String KEY_PREFIX = "__GDD__"; private static final String CREDENTIALS_KEY = KEY_PREFIX + "CREDENTIALS"; private static final String CREDENTIALS_CHARSET_KEY = KEY_PREFIX + "CREDENTIALS_CHARSET"; private static final String CHANNELID_KEY_PREFIX = KEY_PREFIX + "CHANNELID."; private static final String CHANNEL_CLIENTTYPE_KEY_PREFIX = KEY_PREFIX + "CHANNELCLIENTTYPE."; private static final String SUBSCRIPTION_KEY_PREFIX = KEY_PREFIX + "SUBSCRIPTION."; private static final String DESTINATION_CLIENTID_KEY_PREFIX = "org.granite.gravity.channel.clientId."; private static final String DESTINATION_SUBSCRIPTIONID_KEY_PREFIX = "org.granite.gravity.channel.subscriptionId."; private static final String DESTINATION_SELECTOR_KEY_PREFIX = KEY_PREFIX + "org.granite.gravity.selector."; private static final String DESTINATION_DATA_SELECTORS_KEY_PREFIX = KEY_PREFIX + "org.granite.gravity.dataSelectors."; private final HttpSession session; public SessionDistributedData(HttpSession session) { if (session == null) throw new NullPointerException("HTTP session cannot be null"); this.session = session; } public Object getCredentials() { return session.getAttribute(CREDENTIALS_KEY); } public boolean hasCredentials() { return (getCredentials() != null); } public void setCredentials(Object credentials) { if (credentials != null) session.setAttribute(CREDENTIALS_KEY, credentials); else removeCredentials(); } public void removeCredentials() { session.removeAttribute(CREDENTIALS_KEY); } public String getCredentialsCharset() { return (String)session.getAttribute(CREDENTIALS_CHARSET_KEY); } public boolean hasCredentialsCharset() { return (getCredentialsCharset() != null); } public void setCredentialsCharset(String credentialsCharset) { if (credentialsCharset != null) session.setAttribute(CREDENTIALS_CHARSET_KEY, credentialsCharset); else removeCredentialsCharset(); } public void removeCredentialsCharset() { session.removeAttribute(CREDENTIALS_CHARSET_KEY); } public void addChannelId(String channelId, String channelFactoryClassName, String clientType) { if (channelId == null) throw new NullPointerException("channelId cannot be null"); session.setAttribute(CHANNELID_KEY_PREFIX + channelId, channelFactoryClassName); session.setAttribute(CHANNEL_CLIENTTYPE_KEY_PREFIX + channelId, clientType); } public boolean hasChannelId(String channelId) { if (channelId == null) return false; return session.getAttribute(CHANNELID_KEY_PREFIX + channelId) != null; } public String getChannelFactoryClassName(String channelId) { if (channelId == null) return null; return (String)session.getAttribute(CHANNELID_KEY_PREFIX + channelId); } public String getChannelClientType(String channelId) { if (channelId == null) return null; return (String)session.getAttribute(CHANNEL_CLIENTTYPE_KEY_PREFIX + channelId); } public void removeChannelId(String channelId) { if (channelId == null) return; session.removeAttribute(CHANNELID_KEY_PREFIX + channelId); clearSubscriptions(channelId); } public Set<String> getChannelIds() { Set<String> channelIds = new HashSet<String>(); for (Enumeration<String> e = session.getAttributeNames(); e.hasMoreElements(); ) { String key = e.nextElement(); if (key.startsWith(CHANNELID_KEY_PREFIX)) channelIds.add(key.substring(CHANNELID_KEY_PREFIX.length())); } return channelIds; } public void clearChannelIds() { Set<String> channelIds = getChannelIds(); for (String channelId : channelIds) removeChannelId(channelId); } public void addSubcription(String channelId, CommandMessage message) { if (channelId == null || message == null) throw new IllegalArgumentException("channelId and message cannot be null"); if (!hasChannelId(channelId)) throw new IllegalArgumentException("Unknown channelId: " + channelId); if (channelId.indexOf('.') != -1) throw new IllegalArgumentException("Invalid channelId (should not contain '.' characters): " + channelId); String subscriptionId = (String)message.getHeader(AsyncMessage.DESTINATION_CLIENT_ID_HEADER); if (subscriptionId == null) throw new IllegalArgumentException("Subscription id cannot be null: " + message); session.setAttribute(SUBSCRIPTION_KEY_PREFIX + channelId + '.' + subscriptionId, message); } public boolean hasSubcription(String channelId, String subscriptionId) { if (channelId == null || subscriptionId == null) return false; return (session.getAttribute(SUBSCRIPTION_KEY_PREFIX + channelId + '.' + subscriptionId) != null); } public void removeSubcription(String channelId, String subscriptionId) { if (channelId == null || subscriptionId == null) return; session.removeAttribute(SUBSCRIPTION_KEY_PREFIX + channelId + '.' + subscriptionId); } public List<CommandMessage> getSubscriptions(String channelId) { if (channelId == null) return Collections.emptyList(); String channelSubscriptionKeyPrefix = SUBSCRIPTION_KEY_PREFIX + channelId + '.'; List<CommandMessage> subscriptions = new ArrayList<CommandMessage>(); for (Enumeration<String> e = session.getAttributeNames(); e.hasMoreElements(); ) { String key = e.nextElement(); if (key.startsWith(channelSubscriptionKeyPrefix)) { CommandMessage subscription = (CommandMessage)session.getAttribute(key); subscriptions.add(subscription); } } return subscriptions; } public void clearSubscriptions(String channelId) { if (channelId == null) return; String channelSubscriptionKeyPrefix = SUBSCRIPTION_KEY_PREFIX + channelId + '.'; for (Enumeration<String> e = session.getAttributeNames(); e.hasMoreElements(); ) { String key = e.nextElement(); if (key.startsWith(channelSubscriptionKeyPrefix)) session.removeAttribute(key); } } public String getDestinationClientId(String destination) { return (String)session.getAttribute(DESTINATION_CLIENTID_KEY_PREFIX + destination); } public void setDestinationClientId(String destination, String clientId) { session.setAttribute(DESTINATION_CLIENTID_KEY_PREFIX + destination, clientId); } public String getDestinationSubscriptionId(String destination) { return (String)session.getAttribute(DESTINATION_SUBSCRIPTIONID_KEY_PREFIX + destination); } public void setDestinationSubscriptionId(String destination, String subscriptionId) { session.setAttribute(DESTINATION_SUBSCRIPTIONID_KEY_PREFIX + destination, subscriptionId); } public String getDestinationSelector(String destination) { return (String)session.getAttribute(DESTINATION_SELECTOR_KEY_PREFIX + destination); } public void setDestinationSelector(String destination, String selector) { session.setAttribute(DESTINATION_SELECTOR_KEY_PREFIX + destination, selector); } public Object[] getDestinationDataSelectors(String destination) { return (Object[])session.getAttribute(DESTINATION_DATA_SELECTORS_KEY_PREFIX + destination); } public void setDestinationDataSelectors(String destination, Object[] selectors) { session.setAttribute(DESTINATION_DATA_SELECTORS_KEY_PREFIX + destination, selectors); } }