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