blob: c4e7c8a83a0647a52607edba798a018f1eb30f3a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2018 Liferay, Inc.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Liferay, Inc. - Bug 530063 - CNFE when session replication
* is used with equinox.http.servlet in bridge mode
******************************************************************************/
package org.eclipse.equinox.http.servlet.internal.servlet;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import javax.servlet.http.*;
import org.eclipse.equinox.http.servlet.internal.HttpServiceRuntimeImpl;
import org.eclipse.equinox.http.servlet.internal.context.ContextController;
import org.eclipse.equinox.http.servlet.internal.util.EventListeners;
import org.eclipse.equinox.http.servlet.session.HttpSessionInvalidator;
/**
* @since 1.5
*/
public class HttpSessionTracker implements HttpSessionInvalidator {
public HttpSessionTracker(HttpServiceRuntimeImpl httpServiceRuntime) {
this.httpServiceRuntime = httpServiceRuntime;
}
@Override
public void invalidate(String sessionId, boolean invalidateParent) {
Set<HttpSessionAdaptor> httpSessionAdaptors =
httpSessionAdaptorsMap.remove(sessionId);
if (httpSessionAdaptors == null) {
return;
}
for (HttpSessionAdaptor httpSessionAdaptor : httpSessionAdaptors) {
ContextController contextController =
httpSessionAdaptor.getController();
EventListeners eventListeners =
contextController.getEventListeners();
List<HttpSessionListener> httpSessionListeners = eventListeners.get(
HttpSessionListener.class);
if (!httpSessionListeners.isEmpty()) {
HttpSessionEvent httpSessionEvent = new HttpSessionEvent(
httpSessionAdaptor);
for (HttpSessionListener listener : httpSessionListeners) {
try {
listener.sessionDestroyed(httpSessionEvent);
}
catch (IllegalStateException ise) {
// outer session is already invalidated
}
}
}
List<HttpSessionAttributeListener> httpSessionAttributeListeners =
eventListeners.get(HttpSessionAttributeListener.class);
if (!httpSessionListeners.isEmpty()) {
Enumeration<String> enumeration =
httpSessionAdaptor.getAttributeNames();
while (enumeration.hasMoreElements()) {
HttpSessionBindingEvent httpSessionBindingEvent =
new HttpSessionBindingEvent(
httpSessionAdaptor, enumeration.nextElement());
for (HttpSessionAttributeListener
httpSessionAttributeListener :
httpSessionAttributeListeners) {
httpSessionAttributeListener.attributeRemoved(
httpSessionBindingEvent);
}
}
}
contextController.removeActiveSession(
httpSessionAdaptor.getSession());
if (invalidateParent) {
try {
httpSessionAdaptor.getSession().invalidate();
}
catch (IllegalStateException ise) {
httpServiceRuntime.log(
"Session was already invalidated!", ise); //$NON-NLS-1$
}
}
}
}
public void addHttpSessionAdaptor(
String sessionId, HttpSessionAdaptor httpSessionAdaptor) {
Set<HttpSessionAdaptor> httpSessionAdaptors =
httpSessionAdaptorsMap.get(sessionId);
if (httpSessionAdaptors == null) {
httpSessionAdaptors = Collections.newSetFromMap(
new ConcurrentHashMap<HttpSessionAdaptor, Boolean>());
Set<HttpSessionAdaptor> previousHttpSessionAdaptors =
httpSessionAdaptorsMap.putIfAbsent(
sessionId, httpSessionAdaptors);
if (previousHttpSessionAdaptors != null) {
httpSessionAdaptors = previousHttpSessionAdaptors;
}
}
httpSessionAdaptors.add(httpSessionAdaptor);
}
public void clear() {
// At this point there should be no left over sessions. If
// there are we'll log it because there's some kind of leak.
if (!httpSessionAdaptorsMap.isEmpty()) {
httpServiceRuntime.log(
"There are HttpSessionAdaptors left over. There might be a context or session leak!"); //$NON-NLS-1$
}
}
public boolean removeHttpSessionAdaptor(
String sessionId, HttpSessionAdaptor httpSessionAdaptor) {
Set<HttpSessionAdaptor> httpSessionAdaptors =
httpSessionAdaptorsMap.get(sessionId);
if (httpSessionAdaptors == null) {
return false;
}
try {
return httpSessionAdaptors.remove(httpSessionAdaptor);
}
finally {
if (httpSessionAdaptors.isEmpty()) {
httpSessionAdaptorsMap.remove(sessionId, httpSessionAdaptors);
}
}
}
private final ConcurrentMap<String, Set<HttpSessionAdaptor>>
httpSessionAdaptorsMap =
new ConcurrentHashMap<String, Set<HttpSessionAdaptor>>();
private final HttpServiceRuntimeImpl httpServiceRuntime;
}