/* * 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 org.xwiki.wysiwyg.server.filter; import java.io.IOException; import java.lang.reflect.Type; 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 org.xwiki.model.reference.DocumentReference; import org.xwiki.model.reference.DocumentReferenceResolver; import org.xwiki.model.reference.SpaceReference; import org.xwiki.model.reference.WikiReference; import com.xpn.xwiki.XWiki; import com.xpn.xwiki.XWikiContext; import com.xpn.xwiki.XWikiException; import com.xpn.xwiki.user.api.XWikiRightService; 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: 28b28ff3be809a86b3e59b7ed2d83e5212ce77b5 $ */ public class XWikiContextInitializationFilter implements Filter { /** * The filter configuration object. */ private FilterConfig filterConfig; /** * XWiki context mode. */ private int mode; @Override public void destroy() { this.filterConfig = null; } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { try { // Only HTTP requests are supported. if (request instanceof HttpServletRequest) { initializeXWikiContext(request, response); } chain.doFilter(request, response); } finally { if (request instanceof HttpServletRequest) { cleanupComponents(); } } } @Override public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig = filterConfig; try { this.mode = Integer.parseInt(filterConfig.getInitParameter("mode")); } catch (Exception e) { this.mode = -1; } } /** * 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(this.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); // Overwrite the context mode set in the prepareContext() call just above if the mode filter initialization // parameter is specified. if (this.mode >= 0) { context.setMode(this.mode); } // 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)); // Prepare the localized resources, according to the selected language. xwiki.prepareResources(context); // Initialize the current user. XWikiUser user = context.getWiki().checkAuth(context); if (user != null) { DocumentReferenceResolver<String> documentReferenceResolver = Utils.getComponent(DocumentReferenceResolver.TYPE_STRING, "explicit"); SpaceReference defaultUserSpace = new SpaceReference(XWiki.SYSTEM_SPACE, new WikiReference(context.getWikiId())); DocumentReference userReference = documentReferenceResolver.resolve(user.getUser(), defaultUserSpace); context.setUserReference(XWikiRightService.GUEST_USER.equals(userReference.getName()) ? null : userReference); } } 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((Type) ServletContainerInitializer.class); try { containerInitializer.initializeRequest(context.getRequest().getHttpServletRequest(), context); containerInitializer.initializeResponse(context.getResponse()); 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((Type) Container.class); container.removeRequest(); container.removeResponse(); container.removeSession(); Execution execution = Utils.getComponent((Type) Execution.class); execution.removeContext(); } }