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