/*
* Copyright 2000-2013 Enonic AS
* http://www.enonic.com/license
*/
package com.enonic.cms.web.portal.interceptor;
import java.util.Collection;
import java.util.Stack;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.enonic.cms.api.plugin.ext.http.HttpInterceptor;
import com.enonic.cms.core.plugin.ext.HttpInterceptorExtensions;
import com.enonic.cms.server.service.servlet.OriginalPathResolver;
import com.enonic.cms.web.portal.PortalWebContext;
@Component
public class HttpInterceptorInterceptor
implements RequestInterceptor
{
private static final String POST_HANDLE_PLUGINS_PARAM = "httpInterceptorInterceptor.postHandlePlugins";
private HttpInterceptorExtensions httpInterceptorExtensions;
@Autowired
public void setHttpInterceptorExtensions( HttpInterceptorExtensions httpInterceptorExtensions )
{
this.httpInterceptorExtensions = httpInterceptorExtensions;
}
private OriginalPathResolver originalPathResolver = new OriginalPathResolver();
@Override
public boolean preHandle( final PortalWebContext context )
throws Exception
{
final HttpServletRequest request = context.getRequest();
final HttpServletResponse response = context.getResponse();
Stack<HttpInterceptor> pluginsReadyForPostHandle = new Stack<HttpInterceptor>();
boolean continueExecutionAsNormal = executePreHandle( request, response, pluginsReadyForPostHandle );
request.setAttribute( POST_HANDLE_PLUGINS_PARAM, pluginsReadyForPostHandle );
return continueExecutionAsNormal;
}
@Override
public void postHandle( final PortalWebContext context )
throws Exception
{
final HttpServletRequest request = context.getRequest();
final HttpServletResponse response = context.getResponse();
Stack<HttpInterceptor> pluginsReadyForPostHandle = (Stack<HttpInterceptor>) request.getAttribute( POST_HANDLE_PLUGINS_PARAM );
if ( pluginsReadyForPostHandle != null )
{
executePostHandle( request, response, pluginsReadyForPostHandle );
}
}
/**
* Find the applicable interceptor plugins for the given request, and execute their pre processing routine if they
* have not allready been executed.
*
* @param req The servlet request.
* @param res The servlet response.
* @param pluginsReadyForPostHandle A list of all previously executed plugins. These will not be executed again,
* while all the new plugins that are executed this time around, are added to the list.
* @return <code>true</code> if it should proceed, <code>false</code> if execution should be interrupted.
* @throws Exception Any exception that a plugin may throw.
*/
private boolean executePreHandle( HttpServletRequest req, HttpServletResponse res, Stack<HttpInterceptor> pluginsReadyForPostHandle )
throws Exception
{
for ( HttpInterceptor plugin : getInterceptorPlugins( req ) )
{
boolean proceed = plugin.preHandle( req, res );
pluginsReadyForPostHandle.add( plugin );
if ( !proceed )
{
return false;
}
}
return true;
}
private Collection<HttpInterceptor> getInterceptorPlugins( HttpServletRequest req )
{
String path = originalPathResolver.getRequestPathFromHttpRequest( req );
return this.httpInterceptorExtensions.findMatching( path );
}
/**
* Execute the post processing routine of the interceptor plugins that was prehandled successfully.
*
* @param req The servlet request.
* @param res The servlet response.
* @param pluginsReadyForPostHandle The plugins to execute.
* @throws Exception Any exception that a plugin may throw.
*/
private void executePostHandle( HttpServletRequest req, HttpServletResponse res, Stack<HttpInterceptor> pluginsReadyForPostHandle )
throws Exception
{
for ( HttpInterceptor plugin : pluginsReadyForPostHandle )
{
plugin.postHandle( req, res );
}
}
}