001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.servlet;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.util.ListUtil;
020    import com.liferay.portal.kernel.util.Validator;
021    import com.liferay.portal.util.PropsValues;
022    import com.liferay.util.servlet.NullSession;
023    
024    import java.util.Collections;
025    import java.util.Enumeration;
026    import java.util.HashMap;
027    import java.util.List;
028    import java.util.Map;
029    
030    import javax.servlet.ServletContext;
031    import javax.servlet.http.HttpSession;
032    
033    /**
034     * @author Brian Wing Shun Chan
035     */
036    public class SharedSessionWrapper implements HttpSession {
037    
038            public SharedSessionWrapper(
039                    HttpSession portalSession, HttpSession portletSession) {
040    
041                    if (portalSession == null) {
042                            _portalSession = new NullSession();
043    
044                            if (_log.isWarnEnabled()) {
045                                    _log.warn("Wrapped portal session is null");
046                            }
047                    }
048    
049                    _portalSession = portalSession;
050                    _portletSession = portletSession;
051            }
052    
053            @Override
054            public boolean equals(Object obj) {
055                    if (this == obj) {
056                            return true;
057                    }
058    
059                    if (!(obj instanceof SharedSessionWrapper)) {
060                            return false;
061                    }
062    
063                    SharedSessionWrapper sharedSessionWrapper = (SharedSessionWrapper)obj;
064    
065                    if (Validator.equals(
066                                    _portalSession, sharedSessionWrapper._portalSession) &&
067                            Validator.equals(
068                                    _portletSession, sharedSessionWrapper._portletSession)) {
069    
070                            return true;
071                    }
072    
073                    return false;
074            }
075    
076            @Override
077            public Object getAttribute(String name) {
078                    HttpSession session = getSessionDelegate(name);
079    
080                    return session.getAttribute(name);
081            }
082    
083            @Override
084            public Enumeration<String> getAttributeNames() {
085                    HttpSession session = getSessionDelegate();
086    
087                    Enumeration<String> namesEnu = session.getAttributeNames();
088    
089                    if (session == _portletSession) {
090                            List<String> namesList = Collections.list(namesEnu);
091    
092                            Enumeration<String> portalSessionNamesEnu =
093                                    _portalSession.getAttributeNames();
094    
095                            while (portalSessionNamesEnu.hasMoreElements()) {
096                                    String name = portalSessionNamesEnu.nextElement();
097    
098                                    if (containsSharedAttribute(name)) {
099                                            namesList.add(name);
100                                    }
101                            }
102    
103                            namesEnu = Collections.enumeration(namesList);
104                    }
105    
106                    return namesEnu;
107            }
108    
109            @Override
110            public long getCreationTime() {
111                    HttpSession session = getSessionDelegate();
112    
113                    return session.getCreationTime();
114            }
115    
116            @Override
117            public String getId() {
118                    HttpSession session = getSessionDelegate();
119    
120                    return session.getId();
121            }
122    
123            @Override
124            public long getLastAccessedTime() {
125                    HttpSession session = getSessionDelegate();
126    
127                    return session.getLastAccessedTime();
128            }
129    
130            @Override
131            public int getMaxInactiveInterval() {
132                    HttpSession session = getSessionDelegate();
133    
134                    return session.getMaxInactiveInterval();
135            }
136    
137            @Override
138            public ServletContext getServletContext() {
139                    HttpSession session = getSessionDelegate();
140    
141                    return session.getServletContext();
142            }
143    
144            /**
145             * @deprecated
146             */
147            @Override
148            public javax.servlet.http.HttpSessionContext getSessionContext() {
149                    HttpSession session = getSessionDelegate();
150    
151                    return session.getSessionContext();
152            }
153    
154            @Override
155            public Object getValue(String name) {
156                    return getAttribute(name);
157            }
158    
159            @Override
160            public String[] getValueNames() {
161                    List<String> names = ListUtil.fromEnumeration(getAttributeNames());
162    
163                    return names.toArray(new String[names.size()]);
164            }
165    
166            @Override
167            public int hashCode() {
168                    if (_portletSession == null) {
169    
170                            // LPS-35558
171    
172                            return _portalSession.hashCode();
173                    }
174                    else {
175                            return _portalSession.hashCode() ^ _portletSession.hashCode();
176                    }
177            }
178    
179            @Override
180            public void invalidate() {
181                    HttpSession session = getSessionDelegate();
182    
183                    session.invalidate();
184            }
185    
186            @Override
187            public boolean isNew() {
188                    HttpSession session = getSessionDelegate();
189    
190                    return session.isNew();
191            }
192    
193            @Override
194            public void putValue(String name, Object value) {
195                    setAttribute(name, value);
196            }
197    
198            @Override
199            public void removeAttribute(String name) {
200                    HttpSession session = getSessionDelegate(name);
201    
202                    session.removeAttribute(name);
203            }
204    
205            @Override
206            public void removeValue(String name) {
207                    removeAttribute(name);
208            }
209    
210            @Override
211            public void setAttribute(String name, Object value) {
212                    HttpSession session = getSessionDelegate(name);
213    
214                    session.setAttribute(name, value);
215            }
216    
217            @Override
218            public void setMaxInactiveInterval(int maxInactiveInterval) {
219                    HttpSession session = getSessionDelegate();
220    
221                    session.setMaxInactiveInterval(maxInactiveInterval);
222            }
223    
224            protected boolean containsSharedAttribute(String name) {
225                    for (String sharedName : PropsValues.SESSION_SHARED_ATTRIBUTES) {
226                            if (name.startsWith(sharedName)) {
227                                    return true;
228                            }
229                    }
230    
231                    return false;
232            }
233    
234            protected HttpSession getSessionDelegate() {
235                    if (_portletSession != null) {
236                            return _portletSession;
237                    }
238                    else {
239                            return _portalSession;
240                    }
241            }
242    
243            protected HttpSession getSessionDelegate(String name) {
244                    if (_portletSession == null) {
245                            return _portalSession;
246                    }
247    
248                    if (_sharedSessionAttributesExcludes.containsKey(name)) {
249                            return _portletSession;
250                    }
251                    else if (containsSharedAttribute(name)) {
252                            return _portalSession;
253                    }
254                    else {
255                            return _portletSession;
256                    }
257            }
258    
259            private static Log _log = LogFactoryUtil.getLog(SharedSessionWrapper.class);
260    
261            private static Map<String, String> _sharedSessionAttributesExcludes;
262    
263            static {
264                    _sharedSessionAttributesExcludes = new HashMap<String, String>();
265    
266                    for (String name : PropsValues.SESSION_SHARED_ATTRIBUTES_EXCLUDES) {
267                            _sharedSessionAttributesExcludes.put(name, name);
268                    }
269            }
270    
271            private HttpSession _portalSession;
272            private HttpSession _portletSession;
273    
274    }