/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library 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 library 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. */ package com.liferay.portal.servlet; import com.liferay.portal.kernel.servlet.PersistentHttpServletRequestWrapper; import com.liferay.portal.kernel.util.AutoResetThreadLocal; import com.liferay.portal.kernel.util.WebKeys; import java.io.Closeable; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.List; import java.util.Locale; import java.util.concurrent.locks.Lock; import javax.servlet.RequestDispatcher; import javax.servlet.ServletRequest; import javax.servlet.ServletRequestWrapper; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; /** * @author Shuyang Zhou */ public class ThreadLocalFacadeHttpServletRequestWrapper extends PersistentHttpServletRequestWrapper implements Closeable { public ThreadLocalFacadeHttpServletRequestWrapper( ServletRequestWrapper servletRequestWrapper, HttpServletRequest httpServletRequest) { super(httpServletRequest); _servletRequestWrapper = servletRequestWrapper; _nextHttpServletRequestThreadLocal.set(httpServletRequest); _locales = new ArrayList<>(); Enumeration<Locale> enumeration = httpServletRequest.getLocales(); while (enumeration.hasMoreElements()) { _locales.add(enumeration.nextElement()); } } @Override public void close() { if (_servletRequestWrapper != null) { HttpServletRequest nextHttpServletRequest = _nextHttpServletRequestThreadLocal.get(); _servletRequestWrapper.setRequest(nextHttpServletRequest); } } @Override public Object getAttribute(String name) { ServletRequest servletRequest = getRequest(); return servletRequest.getAttribute(name); } @Override public Enumeration<String> getAttributeNames() { ServletRequest servletRequest = getRequest(); Lock lock = (Lock)servletRequest.getAttribute( WebKeys.PARALLEL_RENDERING_MERGE_LOCK); if (lock != null) { lock.lock(); } try { return servletRequest.getAttributeNames(); } finally { if (lock != null) { lock.unlock(); } } } @Override public Enumeration<Locale> getLocales() { return Collections.enumeration(_locales); } @Override public ServletRequest getRequest() { return _nextHttpServletRequestThreadLocal.get(); } @Override public RequestDispatcher getRequestDispatcher(String uri) { ServletRequest servletRequest = getRequest(); return servletRequest.getRequestDispatcher(uri); } @Override public HttpSession getSession() { return getSession(true); } @Override public HttpSession getSession(boolean create) { HttpServletRequest httpServletRequest = (HttpServletRequest)getRequest(); HttpSession httpSession = httpServletRequest.getSession(false); if (!create || (httpSession != null)) { return httpSession; } synchronized (httpServletRequest.getServletContext()) { return httpServletRequest.getSession(true); } } @Override public void removeAttribute(String name) { ServletRequest servletRequest = getRequest(); servletRequest.removeAttribute(name); } @Override public void setAttribute(String name, Object o) { ServletRequest servletRequest = getRequest(); servletRequest.setAttribute(name, o); } @Override public void setRequest(ServletRequest servletRequest) { _nextHttpServletRequestThreadLocal.set( (HttpServletRequest)servletRequest); } private static final ThreadLocal<HttpServletRequest> _nextHttpServletRequestThreadLocal = new AutoResetThreadLocal<HttpServletRequest>( ThreadLocalFacadeHttpServletRequestWrapper.class + "._nextHttpServletRequestThreadLocal") { @Override protected HttpServletRequest copy( HttpServletRequest httpServletRequest) { return httpServletRequest; } }; private final List<Locale> _locales; private final ServletRequestWrapper _servletRequestWrapper; }