%line | %branch | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
org.apache.jetspeed.container.session.PortalSessionsManagerImpl$PortalSessionRegistry |
|
|
1 | /* |
|
2 | * Licensed to the Apache Software Foundation (ASF) under one or more |
|
3 | * contributor license agreements. See the NOTICE file distributed with |
|
4 | * this work for additional information regarding copyright ownership. |
|
5 | * The ASF licenses this file to You under the Apache License, Version 2.0 |
|
6 | * (the "License"); you may not use this file except in compliance with |
|
7 | * the License. You may obtain a copy of the License at |
|
8 | * |
|
9 | * http://www.apache.org/licenses/LICENSE-2.0 |
|
10 | * |
|
11 | * Unless required by applicable law or agreed to in writing, software |
|
12 | * distributed under the License is distributed on an "AS IS" BASIS, |
|
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
14 | * See the License for the specific language governing permissions and |
|
15 | * limitations under the License. |
|
16 | */ |
|
17 | package org.apache.jetspeed.container.session; |
|
18 | ||
19 | import java.util.Arrays; |
|
20 | import java.util.Collection; |
|
21 | import java.util.Collections; |
|
22 | import java.util.HashMap; |
|
23 | import java.util.Iterator; |
|
24 | import java.util.Map; |
|
25 | ||
26 | import javax.servlet.http.HttpSession; |
|
27 | ||
28 | import org.apache.commons.logging.Log; |
|
29 | import org.apache.commons.logging.LogFactory; |
|
30 | ||
31 | /** |
|
32 | * PortalSessionsManagerImpl |
|
33 | * |
|
34 | * @author <a href="mailto:ate@douma.nu">Ate Douma</a> |
|
35 | * @version $Id: $ |
|
36 | */ |
|
37 | public class PortalSessionsManagerImpl implements PortalSessionsManager |
|
38 | { |
|
39 | ||
40 | private static Log log = LogFactory.getLog(PortalSessionsManagerImpl.class); |
|
41 | ||
42 | private static final class PortalSessionRegistry |
|
43 | { |
|
44 | long portalSessionKey; |
|
45 | PortalSessionMonitor psm; |
|
46 | Map sessionMonitors; |
|
47 | ||
48 | PortalSessionRegistry() |
|
49 | 0 | { |
50 | 0 | sessionMonitors = Collections.synchronizedMap(new HashMap()); |
51 | 0 | } |
52 | } |
|
53 | ||
54 | private long portalSessionKeySequence; |
|
55 | private Map portalSessionsRegistry; |
|
56 | private boolean forceInvalidate; |
|
57 | ||
58 | public PortalSessionsManagerImpl() |
|
59 | { |
|
60 | this(true); |
|
61 | } |
|
62 | ||
63 | public PortalSessionsManagerImpl(boolean forceInvalidate) |
|
64 | { |
|
65 | portalSessionKeySequence = System.currentTimeMillis(); |
|
66 | portalSessionsRegistry = Collections.synchronizedMap(new HashMap()); |
|
67 | this.forceInvalidate = forceInvalidate; |
|
68 | } |
|
69 | ||
70 | /* (non-Javadoc) |
|
71 | * @see org.apache.jetspeed.container.session.PortalSessionsManager#portalSessionCreated(javax.servlet.http.HttpSession) |
|
72 | */ |
|
73 | public void portalSessionCreated(HttpSession portalSession) |
|
74 | { |
|
75 | PortalSessionMonitor psm = null; |
|
76 | ||
77 | synchronized (this) |
|
78 | { |
|
79 | psm = new PortalSessionMonitorImpl(++portalSessionKeySequence, forceInvalidate); |
|
80 | } |
|
81 | ||
82 | portalSession.setAttribute(PortalSessionMonitor.SESSION_KEY, psm); |
|
83 | // register it as if activated |
|
84 | portalSessionDidActivate(psm); |
|
85 | } |
|
86 | ||
87 | /* (non-Javadoc) |
|
88 | * @see org.apache.jetspeed.container.session.PortalSessionsManager#portalSessionWillPassivate(org.apache.jetspeed.container.session.PortalSessionMonitor) |
|
89 | */ |
|
90 | public void portalSessionWillPassivate(PortalSessionMonitor psm) |
|
91 | { |
|
92 | portalSessionsRegistry.remove(psm.getSessionId()); |
|
93 | } |
|
94 | ||
95 | /* (non-Javadoc) |
|
96 | * @see org.apache.jetspeed.container.session.PortalSessionsManager#portalSessionDidActivate(org.apache.jetspeed.container.session.PortalSessionMonitor) |
|
97 | */ |
|
98 | public void portalSessionDidActivate(PortalSessionMonitor restoredPsm) |
|
99 | { |
|
100 | PortalSessionRegistry psr = (PortalSessionRegistry)portalSessionsRegistry.get(restoredPsm.getSessionId()); |
|
101 | if ( psr != null && psr.portalSessionKey != -1 && psr.portalSessionKey != restoredPsm.getSessionKey() ) |
|
102 | { |
|
103 | // looks like Client didn't join the previous portal session while the sessionId is reused (cookies disabled?) |
|
104 | // destroy the "old" portal Session and any (probably also not-joined) registered paSessions |
|
105 | portalSessionDestroyed(psr.psm); |
|
106 | psr = null; |
|
107 | } |
|
108 | if ( psr == null ) |
|
109 | { |
|
110 | psr = new PortalSessionRegistry(); |
|
111 | portalSessionsRegistry.put(restoredPsm.getSessionId(), psr); |
|
112 | } |
|
113 | // save the restored instance |
|
114 | psr.psm = restoredPsm; |
|
115 | psr.portalSessionKey = restoredPsm.getSessionKey(); |
|
116 | // validate registered paSessions are in sync |
|
117 | // we iterate with shallow copy of paSessions to avoid conflicts with concurrent updates of paSessions |
|
118 | Iterator iter = valuesShallowCopy(psr.sessionMonitors.values()).iterator(); |
|
119 | PortletApplicationSessionMonitor pasm; |
|
120 | while (iter.hasNext()) |
|
121 | { |
|
122 | pasm = (PortletApplicationSessionMonitor)iter.next(); |
|
123 | if ( pasm.getPortalSessionKey() != psr.portalSessionKey ) |
|
124 | { |
|
125 | pasm.invalidateSession(); |
|
126 | // remove from original map ! |
|
127 | psr.sessionMonitors.remove(pasm.getContextPath()); |
|
128 | } |
|
129 | } |
|
130 | } |
|
131 | ||
132 | /* (non-Javadoc) |
|
133 | * @see org.apache.jetspeed.container.session.PortalSessionsManager#portalSessionDestroyed(org.apache.jetspeed.container.session.PortalSessionMonitor) |
|
134 | */ |
|
135 | public void portalSessionDestroyed(PortalSessionMonitor psm) |
|
136 | { |
|
137 | PortalSessionRegistry psr = (PortalSessionRegistry)portalSessionsRegistry.remove(psm.getSessionId()); |
|
138 | if ( psr != null ) |
|
139 | { |
|
140 | // we iterate with shallow copy of paSessions to avoid conflicts with concurrent updates of paSessions |
|
141 | Iterator iter = valuesShallowCopy(psr.sessionMonitors.values()).iterator(); |
|
142 | while (iter.hasNext()) |
|
143 | { |
|
144 | ((PortletApplicationSessionMonitor) iter.next()).invalidateSession(); |
|
145 | } |
|
146 | ||
147 | try |
|
148 | { |
|
149 | // To make sure its gone. |
|
150 | // You better not remove the psm from the portal session yourself ;) |
|
151 | psm.invalidateSession(); |
|
152 | } |
|
153 | catch (IllegalStateException ise) |
|
154 | { |
|
155 | // pSession already invalid, ignore |
|
156 | } |
|
157 | } |
|
158 | } |
|
159 | ||
160 | /* (non-Javadoc) |
|
161 | * @see org.apache.jetspeed.container.session.PortalSessionsManager#checkMonitorSession(java.lang.String, javax.servlet.http.HttpSession, javax.servlet.http.HttpSession) |
|
162 | */ |
|
163 | public void checkMonitorSession(String contextPath, HttpSession portalSession, HttpSession paSession) |
|
164 | { |
|
165 | if ( portalSession != null && paSession != class="keyword">null ) |
|
166 | { |
|
167 | if (portalSession == paSession) |
|
168 | { |
|
169 | // On WebSphere 6.1.0.11, strange symptoms like this occur... |
|
170 | log.warn("servlet context name of paSession(" + paSession.getId() + "): " + paSession.getServletContext().getServletContextName()); |
|
171 | return; |
|
172 | } |
|
173 | ||
174 | PortalSessionRegistry psr = (PortalSessionRegistry)portalSessionsRegistry.get(portalSession.getId()); |
|
175 | if (psr == null) |
|
176 | { |
|
177 | // yet unexplained condition: the HttpSessionListener on the portal application *should* have registered the session!!! |
|
178 | // Alas, it has been reported to happen... |
|
179 | // Now trying to do some recovering here |
|
180 | PortalSessionMonitor psm = (PortalSessionMonitor)portalSession.getAttribute(PortalSessionMonitor.SESSION_KEY); |
|
181 | // the psm better be null here, otherwise something really is corrupt or not playing by the listeners contracts |
|
182 | if ( psm == null ) |
|
183 | { |
|
184 | portalSessionCreated(portalSession); |
|
185 | } |
|
186 | else |
|
187 | { |
|
188 | // Now we have discovered a really strange situation here |
|
189 | // Only explanation I can see is that a passivation of the portalSession occurred, |
|
190 | // but that the activation again didn't trigger the sessionDidActivate event handler??? |
|
191 | // Lets just try to accomodate this situation for now: |
|
192 | portalSessionDidActivate(psm); |
|
193 | } |
|
194 | // now retrieve the just created psr again |
|
195 | psr = (PortalSessionRegistry)portalSessionsRegistry.get(portalSession.getId()); |
|
196 | } |
|
197 | PortletApplicationSessionMonitor pasm = (PortletApplicationSessionMonitor)psr.sessionMonitors.get(contextPath); |
|
198 | if ( pasm != null ) |
|
199 | { |
|
200 | try |
|
201 | { |
|
202 | if ( paSession.getAttribute(PortletApplicationSessionMonitor.SESSION_KEY) == null ) |
|
203 | { |
|
204 | // looks like Client didn't join the previous pa session |
|
205 | // destroy the "old" paSession |
|
206 | pasm.invalidateSession(); |
|
207 | pasm = null; |
|
208 | // no need to remove the "old" pasm from the sessionMonitors as it will be replaced right below |
|
209 | } |
|
210 | } |
|
211 | catch (IllegalStateException ise) |
|
212 | { |
|
213 | // paSession already invalid, ignore |
|
214 | } |
|
215 | } |
|
216 | if ( pasm == null ) |
|
217 | { |
|
218 | pasm = new PortletApplicationSessionMonitorImpl(contextPath,portalSession.getId(),psr.portalSessionKey, forceInvalidate); |
|
219 | try |
|
220 | { |
|
221 | paSession.setAttribute(PortletApplicationSessionMonitor.SESSION_KEY, pasm); |
|
222 | psr.sessionMonitors.put(contextPath, pasm); |
|
223 | } |
|
224 | catch (IllegalStateException ise) |
|
225 | { |
|
226 | // paSession already invalid, ignore |
|
227 | } |
|
228 | } |
|
229 | } |
|
230 | } |
|
231 | ||
232 | /* (non-Javadoc) |
|
233 | * @see org.apache.jetspeed.container.session.PortalSessionsManager#sessionWillPassivate(org.apache.jetspeed.container.session.PortletApplicationSessionMonitor) |
|
234 | */ |
|
235 | public void sessionWillPassivate(PortletApplicationSessionMonitor pasm) |
|
236 | { |
|
237 | PortalSessionRegistry psr = (PortalSessionRegistry)portalSessionsRegistry.get(pasm.getPortalSessionId()); |
|
238 | if (psr != null ) |
|
239 | { |
|
240 | psr.sessionMonitors.remove(pasm.getContextPath()); |
|
241 | } |
|
242 | } |
|
243 | ||
244 | /* (non-Javadoc) |
|
245 | * @see org.apache.jetspeed.container.session.PortalSessionsManager#sessionDidActivate(org.apache.jetspeed.container.session.PortletApplicationSessionMonitor) |
|
246 | */ |
|
247 | public void sessionDidActivate(PortletApplicationSessionMonitor restoredPasm) |
|
248 | { |
|
249 | PortalSessionRegistry psr = (PortalSessionRegistry)portalSessionsRegistry.get(restoredPasm.getPortalSessionId()); |
|
250 | if ( psr == null ) |
|
251 | { |
|
252 | // looks like the portalSession was passivated or the paSession was replicated to another JVM while its related portalSession wasn't (yet) |
|
253 | // so, we're gonna anticipate future activation of the portalSession: |
|
254 | // create a temporary psr with an "empty" psm for now (portalSessionKey == -1) |
|
255 | // once the portalSession is replicated/Activated, it will validate registered paSessions having the correct portalSessionKey |
|
256 | psr = new PortalSessionRegistry(); |
|
257 | psr.psm = new PortalSessionMonitorImpl(-1); |
|
258 | portalSessionsRegistry.put(restoredPasm.getPortalSessionId(), psr); |
|
259 | } |
|
260 | ||
261 | // save the restored instance |
|
262 | restoredPasm.getSession().setAttribute(PortletApplicationSessionMonitor.SESSION_KEY, restoredPasm); |
|
263 | psr.sessionMonitors.put(restoredPasm.getContextPath(), restoredPasm); |
|
264 | } |
|
265 | ||
266 | /* (non-Javadoc) |
|
267 | * @see org.apache.jetspeed.container.session.PortalSessionsManager#sessionDestroyed(org.apache.jetspeed.container.session.PortletApplicationSessionMonitor) |
|
268 | */ |
|
269 | public void sessionDestroyed(PortletApplicationSessionMonitor pasm) |
|
270 | { |
|
271 | PortalSessionRegistry psr = (PortalSessionRegistry)portalSessionsRegistry.get(pasm.getPortalSessionId()); |
|
272 | if ( psr != null ) |
|
273 | { |
|
274 | psr.sessionMonitors.remove(pasm.getContextPath()); |
|
275 | ||
276 | try |
|
277 | { |
|
278 | // To make sure its gone. |
|
279 | // You better not remove the pasm from the session yourself ;) |
|
280 | pasm.invalidateSession(); |
|
281 | } |
|
282 | catch (IllegalStateException ise) |
|
283 | { |
|
284 | // paSession already invalid, ignore |
|
285 | } |
|
286 | } |
|
287 | } |
|
288 | ||
289 | /* (non-Javadoc) |
|
290 | * @see org.apache.jetspeed.container.session.PortalSessionsManager#sessionCount() |
|
291 | */ |
|
292 | public int sessionCount() { |
|
293 | ||
294 | return portalSessionsRegistry.size(); |
|
295 | } |
|
296 | ||
297 | /** |
|
298 | * Returns a shallow copy of the given Collection. |
|
299 | * @param inValues |
|
300 | * @return shallow copy |
|
301 | */ |
|
302 | private Collection valuesShallowCopy(Collection inValues) { |
|
303 | return Arrays.asList(inValues.toArray()); |
|
304 | } |
|
305 | } |
This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |