/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package com.xpn.xwiki.wysiwyg.server.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.xwiki.container.Container;
import org.xwiki.container.servlet.ServletContainerException;
import org.xwiki.container.servlet.ServletContainerInitializer;
import org.xwiki.context.Execution;

import com.xpn.xwiki.XWiki;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.user.api.XWikiUser;
import com.xpn.xwiki.web.Utils;
import com.xpn.xwiki.web.XWikiServletContext;
import com.xpn.xwiki.web.XWikiServletRequest;
import com.xpn.xwiki.web.XWikiServletResponse;

/**
 * This filter can be used to initialize the XWiki context before processing a request.
 * 
 * @version $Id$
 */
public class XWikiContextInitializationFilter implements Filter
{
    /**
     * The filter configuration object.
     */
    private FilterConfig filterConfig;

    /**
     * {@inheritDoc}
     * 
     * @see Filter#destroy()
     */
    public void destroy()
    {
        filterConfig = null;
    }

    /**
     * {@inheritDoc}
     * 
     * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
     */
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
        ServletException
    {
        try {
            initializeXWikiContext(request, response);
            chain.doFilter(request, response);
        } finally {
            cleanupComponents();
        }
    }

    /**
     * {@inheritDoc}
     * 
     * @see Filter#init(FilterConfig)
     */
    public void init(FilterConfig filterConfig) throws ServletException
    {
        this.filterConfig = filterConfig;
    }

    /**
     * Initializes the XWiki context.
     * 
     * @param request the request being processed
     * @param response the response
     * @throws ServletException if the initialization fails
     */
    protected void initializeXWikiContext(ServletRequest request, ServletResponse response) throws ServletException
    {
        try {
            // Not all request types specify an action (e.g. GWT-RPC) so we default to the empty string.
            String action = "";
            XWikiServletContext xwikiEngine = new XWikiServletContext(filterConfig.getServletContext());
            XWikiServletRequest xwikiRequest = new XWikiServletRequest((HttpServletRequest) request);
            XWikiServletResponse xwikiResponse = new XWikiServletResponse((HttpServletResponse) response);

            // Create the XWiki context.
            XWikiContext context = Utils.prepareContext(action, xwikiRequest, xwikiResponse, xwikiEngine);

            // Initialize the Container component which is the new way of transporting the Context in the new component
            // architecture. Further initialization might require the Container component.
            initializeContainerComponent(context);

            // Initialize the XWiki database. XWiki#getXWiki(XWikiContext) calls XWikiContext.setWiki(XWiki).
            XWiki xwiki = XWiki.getXWiki(context);

            // Initialize the URL factory.
            context.setURLFactory(xwiki.getURLFactoryService().createURLFactory(context.getMode(), context));

            // Initialize the current user.
            XWikiUser user = context.getWiki().checkAuth(context);
            if (user != null) {
                context.setUser(user.getUser());
            }
        } catch (XWikiException e) {
            throw new ServletException("Failed to initialize the XWiki context.", e);
        }
    }

    /**
     * @param context the XWiki context
     * @throws ServletException if the container component initialization fails
     */
    protected void initializeContainerComponent(XWikiContext context) throws ServletException
    {
        // Initialize the Container fields (request, response, session). Note that this is a bridge between the old core
        // and the component architecture. In the new component architecture we use ThreadLocal to transport the
        // request, response and session to components which require them.
        ServletContainerInitializer containerInitializer = Utils.getComponent(ServletContainerInitializer.class);

        try {
            containerInitializer.initializeRequest(context.getRequest().getHttpServletRequest(), context);
            containerInitializer.initializeResponse(context.getResponse().getHttpServletResponse());
            containerInitializer.initializeSession(context.getRequest().getHttpServletRequest());
        } catch (ServletContainerException e) {
            throw new ServletException("Failed to initialize Request/Response or Session", e);
        }
    }

    /**
     * We must ensure we clean the ThreadLocal variables located in the Container and Execution components as otherwise
     * we will have a potential memory leak.
     */
    protected void cleanupComponents()
    {
        Container container = Utils.getComponent(Container.class);
        container.removeRequest();
        container.removeResponse();
        container.removeSession();

        Execution execution = Utils.getComponent(Execution.class);
        execution.removeContext();
    }
}

@@ -2061,16 +2061,82 @@
 onfig;%0A%0A
+    /**%0A     * XWiki context mode.%0A     */%0A    private int mode;%0A%0A
     /**%0A
@@ -2539,32 +2539,142 @@
 %7B%0A        try %7B%0A
+            // Only HTTP requests are supported.%0A            if (request instanceof HttpServletRequest) %7B%0A    
             init
@@ -2704,32 +2704,46 @@
 est, response);%0A
+            %7D%0A
             chai
@@ -2789,24 +2789,85 @@
 %7D finally %7B%0A
+            if (request instanceof HttpServletRequest) %7B%0A    
             
@@ -2883,24 +2883,38 @@
 mponents();%0A
+            %7D%0A
         %7D%0A  
@@ -3120,16 +3120,172 @@
 rConfig;
+%0A%0A        try %7B%0A            mode = Integer.parseInt(filterConfig.getInitParameter(%22mode%22));%0A        %7D catch (Exception e) %7B%0A            mode = -1;%0A        %7D
 %0A    %7D%0A%0A
@@ -4225,24 +4225,207 @@
 kiEngine);%0A%0A
+            // Overwrite the context mode if the mode filter initialization parameter is specified.%0A            if (mode %3E= 0) %7B%0A                context.setMode(mode);%0A            %7D%0A%0A
             

Add the ability to overwrite the XWiki context mode while using the XWiki context initialization filter.