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.clustering;
022    
023    import java.util.ArrayList;
024    import java.util.Collections;
025    import java.util.Enumeration;
026    import java.util.HashSet;
027    import java.util.List;
028    import java.util.Set;
029    
030    import javax.servlet.http.HttpSession;
031    
032    import flex.messaging.messages.AsyncMessage;
033    import flex.messaging.messages.CommandMessage;
034    
035    /**
036     * @author Franck WOLFF
037     */
038    public 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    }