/*******************************************************************************
* Copyright (c) 2011, 2015 EclipseSource and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* EclipseSource - initial API and implementation
******************************************************************************/
package org.eclipse.rap.rwt.internal.engine;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.eclipse.rap.rwt.internal.application.ApplicationContextImpl;
import org.eclipse.rap.rwt.internal.protocol.ClientMessageConst;
import org.eclipse.rap.rwt.internal.service.UISessionImpl;
import org.eclipse.rap.rwt.service.UISession;
public class RWTClusterSupport implements Filter {
@Override
public void init( FilterConfig filterConfig ) {
}
@Override
public void doFilter( ServletRequest request, ServletResponse response, FilterChain chain )
throws IOException, ServletException
{
beforeService( request );
chain.doFilter( request, response );
afterService( request );
}
@Override
public void destroy() {
}
private static void beforeService( ServletRequest request ) {
HttpSession httpSession = getHttpSession( request );
if( httpSession != null ) {
beforeService( httpSession, getConnectionId( request ) );
}
}
private static void beforeService( HttpSession httpSession, String connectionId ) {
UISessionImpl uiSession = UISessionImpl.getInstanceFromSession( httpSession, connectionId );
if( uiSession != null ) {
uiSession.setHttpSession( httpSession );
attachApplicationContext( uiSession );
PostDeserialization.runProcessors( uiSession );
}
}
private static void attachApplicationContext( UISession uiSession ) {
ServletContext servletContext = uiSession.getHttpSession().getServletContext();
ApplicationContextImpl applicationContext = ApplicationContextImpl.getFrom( servletContext );
( ( UISessionImpl )uiSession ).setApplicationContext( applicationContext );
}
private static void afterService( ServletRequest request ) {
HttpSession httpSession = getHttpSession( request );
if( httpSession != null ) {
afterService( httpSession, getConnectionId( request ) );
}
}
private static void afterService( HttpSession httpSession, String connectionId ) {
markSessionChanged( httpSession, connectionId );
}
private static void markSessionChanged( HttpSession httpSession, String connectionId ) {
// If a session attribute changes, the servlet engine must be told to replicate the change.
// Unfortunately the Servlet specs do not specify how this should be done.
// The most common way is to call HttpSession.setAttribute() to flag the object as changed.
// See http://wiki.eclipse.org/RAP/RWT_Cluster#Serializable_Session_Data
// See also: J2EE clustering, Part 2, section Session-storage guidelines
// http://java.sun.com/developer/technicalArticles/J2EE/clustering/
UISessionImpl uiSession = UISessionImpl.getInstanceFromSession( httpSession, connectionId );
if( uiSession != null ) {
uiSession.attachToHttpSession();
}
}
private static HttpSession getHttpSession( ServletRequest request ) {
return ( ( HttpServletRequest )request ).getSession( false );
}
private static String getConnectionId( ServletRequest request ) {
return request.getParameter( ClientMessageConst.CONNECTION_ID );
}
}