/* * Copyright 2008 biaoping.yin * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.frameworkset.web.servlet.context; import javax.faces.context.FacesContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import javax.servlet.jsp.PageContext; import org.frameworkset.spi.support.NamedInheritableThreadLocal; import org.frameworkset.spi.support.NamedThreadLocal; import org.frameworkset.util.ClassUtils; /** * <p>Title: RequestContextHolder.java</p> * <p>Description: </p> * <p>bboss workgroup</p> * <p>Copyright (c) 2008</p> * @Date 2010-10-1 * @author biaoping.yin * @version 1.0 */ public abstract class RequestContextHolder { private static final boolean jsfPresent = ClassUtils.isPresent("javax.faces.context.FacesContext", RequestContextHolder.class.getClassLoader()); private static final ThreadLocal requestAttributesHolder = new NamedThreadLocal("Request attributes"); private static final ThreadLocal inheritableRequestAttributesHolder = new NamedInheritableThreadLocal("Request context"); /** * Reset the RequestAttributes for the current thread. */ public static void resetRequestAttributes() { requestAttributesHolder.set(null); inheritableRequestAttributesHolder.set(null); } /** * Bind the given RequestAttributes to the current thread, * <i>not</i> exposing it as inheritable for child threads. * @param attributes the RequestAttributes to expose * @see #setRequestAttributes(RequestAttributes, boolean) */ public static void setRequestAttributes(RequestAttributes attributes) { setRequestAttributes(attributes, false); } /** * Bind the given RequestAttributes to the current thread. * @param attributes the RequestAttributes to expose * @param inheritable whether to expose the RequestAttributes as inheritable * for child threads (using an {@link java.lang.InheritableThreadLocal}) */ public static void setRequestAttributes(RequestAttributes attributes, boolean inheritable) { if (inheritable) { inheritableRequestAttributesHolder.set(attributes); requestAttributesHolder.set(null); } else { requestAttributesHolder.set(attributes); inheritableRequestAttributesHolder.set(null); } } /** * Return the RequestAttributes currently bound to the thread. * @return the RequestAttributes currently bound to the thread, * or <code>null</code> if none bound */ public static RequestAttributes getRequestAttributes() { RequestAttributes attributes = (RequestAttributes) requestAttributesHolder.get(); if (attributes == null) { attributes = (RequestAttributes) inheritableRequestAttributesHolder.get(); } return attributes; } /** * Return the RequestContainer currently bound to the thread. * @return the RequestContainer currently bound to the thread, * or <code>null</code> if none bound */ public static RequestContainer getRequestContainer() { RequestContainer attributes = (RequestContainer) requestAttributesHolder.get(); if (attributes == null) { attributes = (RequestContainer) inheritableRequestAttributesHolder.get(); } return attributes; } public static HttpServletResponse getResponse() { RequestContainer requestContainer = getRequestContainer(); return requestContainer != null?requestContainer.getResponse():null; } public static PageContext getPageContext() { RequestContainer requestContainer = getRequestContainer(); return requestContainer != null?requestContainer.getPageContext():null; } public static HttpServletRequest getRequest() { RequestContainer requestContainer = getRequestContainer(); return requestContainer != null?requestContainer.getRequest():null; } public static HttpSession getSession(boolean create) { RequestContainer requestContainer = getRequestContainer(); return requestContainer != null?requestContainer.getSession(create):null; } public static HttpSession getSession() { RequestContainer requestContainer = getRequestContainer(); return requestContainer != null?requestContainer.getSession():null; } /** * Return the RequestAttributes currently bound to the thread. * <p>Exposes the previously bound RequestAttributes instance, if any. * Falls back to the current JSF FacesContext, if any. * @return the RequestAttributes currently bound to the thread * @throws IllegalStateException if no RequestAttributes object * is bound to the current thread * @see #setRequestAttributes * @see ServletRequestAttributes * @see FacesRequestAttributes * @see javax.faces.context.FacesContext#getCurrentInstance() */ public static RequestAttributes currentRequestAttributes() throws IllegalStateException { RequestAttributes attributes = getRequestAttributes(); if (attributes == null) { if (jsfPresent) { attributes = FacesRequestAttributesFactory.getFacesRequestAttributes(); } if (attributes == null) { throw new IllegalStateException("No thread-bound request found: " + "Are you referring to request attributes outside of an actual web request, " + "or processing a request outside of the originally receiving thread? " + "If you are actually operating within a web request and still receive this message, " + "your code is probably running outside of DispatcherServlet/DispatcherPortlet: " + "In this case, use RequestContextListener or RequestContextFilter to expose the current request."); } } return attributes; } /** * Inner class to avoid hard-coded JSF dependency. */ private static class FacesRequestAttributesFactory { public static RequestAttributes getFacesRequestAttributes() { FacesContext facesContext = FacesContext.getCurrentInstance(); return (facesContext != null ? new FacesRequestAttributes(facesContext) : null); } } }