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.clustering;
022
023import java.util.ArrayList;
024import java.util.Collections;
025import java.util.Enumeration;
026import java.util.HashSet;
027import java.util.List;
028import java.util.Set;
029
030import javax.servlet.http.HttpSession;
031
032import flex.messaging.messages.AsyncMessage;
033import flex.messaging.messages.CommandMessage;
034
035/**
036 * @author Franck WOLFF
037 */
038public class SessionDistributedData implements DistributedData {
039
040        private static final String KEY_PREFIX = "__GDD__";
041        private static final String CREDENTIALS_KEY = KEY_PREFIX + "CREDENTIALS";
042        private static final String CREDENTIALS_CHARSET_KEY = KEY_PREFIX + "CREDENTIALS_CHARSET";
043        private static final String CHANNELID_KEY_PREFIX = KEY_PREFIX + "CHANNELID.";
044        private static final String SUBSCRIPTION_KEY_PREFIX = KEY_PREFIX + "SUBSCRIPTION.";
045        private static final String DESTINATION_CLIENTID_KEY_PREFIX = "org.granite.gravity.channel.clientId.";
046        private static final String DESTINATION_SUBSCRIPTIONID_KEY_PREFIX = "org.granite.gravity.channel.subscriptionId.";
047        private static final String DESTINATION_SELECTOR_KEY_PREFIX = KEY_PREFIX + "org.granite.gravity.selector.";
048        private static final String DESTINATION_DATA_SELECTORS_KEY_PREFIX = KEY_PREFIX + "org.granite.gravity.dataSelectors.";
049        
050        private final HttpSession session;
051
052        public SessionDistributedData(HttpSession session) {
053                if (session == null)
054                        throw new NullPointerException("HTTP session cannot be null");
055                this.session = session;
056        }
057        
058        public Object getCredentials() {
059                return session.getAttribute(CREDENTIALS_KEY);
060        }
061
062        public boolean hasCredentials() {
063                return (getCredentials() != null);
064        }
065
066        public void setCredentials(Object credentials) {
067                if (credentials != null)
068                        session.setAttribute(CREDENTIALS_KEY, credentials);
069                else
070                        removeCredentials();
071        }
072
073        public void removeCredentials() {
074                session.removeAttribute(CREDENTIALS_KEY);
075        }
076
077        public String getCredentialsCharset() {
078                return (String)session.getAttribute(CREDENTIALS_CHARSET_KEY);
079        }
080
081        public boolean hasCredentialsCharset() {
082                return (getCredentialsCharset() != null);
083        }
084
085        public void setCredentialsCharset(String credentialsCharset) {
086                if (credentialsCharset != null)
087                        session.setAttribute(CREDENTIALS_CHARSET_KEY, credentialsCharset);
088                else
089                        removeCredentialsCharset();
090        }
091
092        public void removeCredentialsCharset() {
093                session.removeAttribute(CREDENTIALS_CHARSET_KEY);
094        }
095
096        public void addChannelId(String channelId, String channelFactoryClassName) {
097                if (channelId == null)
098                        throw new NullPointerException("channelId cannot be null");
099                session.setAttribute(CHANNELID_KEY_PREFIX + channelId, channelFactoryClassName);
100        }
101
102        public boolean hasChannelId(String channelId) {
103                if (channelId == null)
104                        return false;
105                return session.getAttribute(CHANNELID_KEY_PREFIX + channelId) != null;
106        }
107        
108        public String getChannelFactoryClassName(String channelId) {
109                if (channelId == null)
110                        return null;
111                return (String)session.getAttribute(CHANNELID_KEY_PREFIX + channelId);
112        }
113
114        public void removeChannelId(String channelId) {
115                if (channelId == null)
116                        return;
117                session.removeAttribute(CHANNELID_KEY_PREFIX + channelId);
118                clearSubscriptions(channelId);
119        }
120
121        public Set<String> getChannelIds() {
122                Set<String> channelIds = new HashSet<String>();
123                for (Enumeration<String> e = session.getAttributeNames(); e.hasMoreElements(); ) {
124                        String key = e.nextElement();
125                        if (key.startsWith(CHANNELID_KEY_PREFIX))
126                                channelIds.add(key.substring(CHANNELID_KEY_PREFIX.length()));
127                }
128                return channelIds;
129        }
130
131        public void clearChannelIds() {
132                Set<String> channelIds = getChannelIds();
133                for (String channelId : channelIds)
134                        removeChannelId(channelId);
135        }
136
137        public void addSubcription(String channelId, CommandMessage message) {
138                if (channelId == null || message == null)
139                        throw new IllegalArgumentException("channelId and message cannot be null");
140                if (!hasChannelId(channelId))
141                        throw new IllegalArgumentException("Unknown channelId: " + channelId);
142                if (channelId.indexOf('.') != -1)
143                        throw new IllegalArgumentException("Invalid channelId (should not contain '.' characters): " + channelId);
144                String subscriptionId = (String)message.getHeader(AsyncMessage.DESTINATION_CLIENT_ID_HEADER);
145                if (subscriptionId == null)
146                        throw new IllegalArgumentException("Subscription id cannot be null: " + message);
147                session.setAttribute(SUBSCRIPTION_KEY_PREFIX + channelId + '.' + subscriptionId, message);
148        }
149
150        public boolean hasSubcription(String channelId, String subscriptionId) {
151                if (channelId == null || subscriptionId == null)
152                        return false;
153                return (session.getAttribute(SUBSCRIPTION_KEY_PREFIX + channelId + '.' + subscriptionId) != null);
154        }
155
156        public void removeSubcription(String channelId, String subscriptionId) {
157                if (channelId == null || subscriptionId == null)
158                        return;
159                session.removeAttribute(SUBSCRIPTION_KEY_PREFIX + channelId + '.' + subscriptionId);
160        }
161
162        public List<CommandMessage> getSubscriptions(String channelId) {
163                if (channelId == null)
164                        return Collections.emptyList();
165                String channelSubscriptionKeyPrefix = SUBSCRIPTION_KEY_PREFIX + channelId + '.';
166                List<CommandMessage> subscriptions = new ArrayList<CommandMessage>();
167                for (Enumeration<String> e = session.getAttributeNames(); e.hasMoreElements(); ) {
168                        String key = e.nextElement();
169                        if (key.startsWith(channelSubscriptionKeyPrefix)) {
170                                CommandMessage subscription = (CommandMessage)session.getAttribute(key);
171                                subscriptions.add(subscription);
172                        }
173                }
174                return subscriptions;
175        }
176
177        public void clearSubscriptions(String channelId) {
178                if (channelId == null)
179                        return;
180                String channelSubscriptionKeyPrefix = SUBSCRIPTION_KEY_PREFIX + channelId + '.';
181                for (Enumeration<String> e = session.getAttributeNames(); e.hasMoreElements(); ) {
182                        String key = e.nextElement();
183                        if (key.startsWith(channelSubscriptionKeyPrefix))
184                                session.removeAttribute(key);
185                }
186        }
187        
188        
189        public String getDestinationClientId(String destination) {
190                return (String)session.getAttribute(DESTINATION_CLIENTID_KEY_PREFIX + destination);
191        }
192        
193        public void setDestinationClientId(String destination, String clientId) {
194                session.setAttribute(DESTINATION_CLIENTID_KEY_PREFIX + destination, clientId);
195        }
196        
197        public String getDestinationSubscriptionId(String destination) {
198                return (String)session.getAttribute(DESTINATION_SUBSCRIPTIONID_KEY_PREFIX + destination);
199        }
200        
201        public void setDestinationSubscriptionId(String destination, String subscriptionId) {
202                session.setAttribute(DESTINATION_SUBSCRIPTIONID_KEY_PREFIX + destination, subscriptionId);
203        }
204        
205        public String getDestinationSelector(String destination) {
206                return (String)session.getAttribute(DESTINATION_SELECTOR_KEY_PREFIX + destination);
207        }
208        
209        public void setDestinationSelector(String destination, String selector) {
210                session.setAttribute(DESTINATION_SELECTOR_KEY_PREFIX + destination, selector);
211        }
212        
213        public Object[] getDestinationDataSelectors(String destination) {
214                return (Object[])session.getAttribute(DESTINATION_DATA_SELECTORS_KEY_PREFIX + destination);
215        }
216        
217        public void setDestinationDataSelectors(String destination, Object[] selectors) {
218                session.setAttribute(DESTINATION_DATA_SELECTORS_KEY_PREFIX + destination, selectors);
219        }
220}