001
014
015 package com.liferay.portal.kernel.servlet.filters.invoker;
016
017 import com.liferay.portal.kernel.cache.key.CacheKeyGenerator;
018 import com.liferay.portal.kernel.cache.key.CacheKeyGeneratorUtil;
019 import com.liferay.portal.kernel.concurrent.ConcurrentLFUCache;
020 import com.liferay.portal.kernel.log.Log;
021 import com.liferay.portal.kernel.log.LogFactoryUtil;
022 import com.liferay.portal.kernel.servlet.NonSerializableObjectRequestWrapper;
023 import com.liferay.portal.kernel.servlet.SecureHttpServletResponseWrapper;
024 import com.liferay.portal.kernel.util.BasePortalLifecycle;
025 import com.liferay.portal.kernel.util.ContextPathUtil;
026 import com.liferay.portal.kernel.util.GetterUtil;
027 import com.liferay.portal.kernel.util.JavaConstants;
028 import com.liferay.portal.kernel.util.PropsKeys;
029 import com.liferay.portal.kernel.util.PropsUtil;
030 import com.liferay.portal.kernel.util.ServerDetector;
031 import com.liferay.portal.kernel.util.StringPool;
032 import com.liferay.portal.kernel.util.Validator;
033 import com.liferay.portal.kernel.util.WebKeys;
034
035 import java.io.IOException;
036
037 import javax.servlet.Filter;
038 import javax.servlet.FilterChain;
039 import javax.servlet.FilterConfig;
040 import javax.servlet.ServletContext;
041 import javax.servlet.ServletException;
042 import javax.servlet.ServletRequest;
043 import javax.servlet.ServletResponse;
044 import javax.servlet.http.HttpServletRequest;
045 import javax.servlet.http.HttpServletResponse;
046
047
051 public class InvokerFilter extends BasePortalLifecycle implements Filter {
052
053 @Override
054 public void destroy() {
055 portalDestroy();
056 }
057
058 @Override
059 public void doFilter(
060 ServletRequest servletRequest, ServletResponse servletResponse,
061 FilterChain filterChain)
062 throws IOException, ServletException {
063
064 HttpServletRequest request = (HttpServletRequest)servletRequest;
065
066 String uri = getURI(request);
067
068 request = handleNonSerializableRequest(request);
069
070 HttpServletResponse response = (HttpServletResponse)servletResponse;
071
072 response = secureResponseHeaders(response);
073
074 request.setAttribute(WebKeys.INVOKER_FILTER_URI, uri);
075
076 try {
077 InvokerFilterChain invokerFilterChain = getInvokerFilterChain(
078 request, uri, filterChain);
079
080 Thread currentThread = Thread.currentThread();
081
082 ClassLoader contextClassLoader =
083 currentThread.getContextClassLoader();
084
085 invokerFilterChain.setContextClassLoader(contextClassLoader);
086
087 invokerFilterChain.doFilter(request, response);
088 }
089 finally {
090 request.removeAttribute(WebKeys.INVOKER_FILTER_URI);
091 }
092 }
093
094 @Override
095 public void init(FilterConfig filterConfig) throws ServletException {
096 _filterConfig = filterConfig;
097
098 ServletContext servletContext = _filterConfig.getServletContext();
099
100 _contextPath = ContextPathUtil.getContextPath(servletContext);
101
102 boolean registerPortalLifecycle = GetterUtil.getBoolean(
103 _filterConfig.getInitParameter("register-portal-lifecycle"), true);
104
105 if (registerPortalLifecycle) {
106 registerPortalLifecycle();
107 }
108 else {
109 try {
110 doPortalInit();
111 }
112 catch (Exception e) {
113 _log.error(e, e);
114
115 throw new ServletException(e);
116 }
117 }
118 }
119
120 protected void clearFilterChainsCache() {
121 if (_filterChains != null) {
122 _filterChains.clear();
123 }
124 }
125
126 @Override
127 protected void doPortalDestroy() {
128 ServletContext servletContext = _filterConfig.getServletContext();
129
130 InvokerFilterHelper invokerFilterHelper =
131 (InvokerFilterHelper)servletContext.getAttribute(
132 InvokerFilterHelper.class.getName());
133
134 if (invokerFilterHelper != null) {
135 servletContext.removeAttribute(InvokerFilterHelper.class.getName());
136
137 invokerFilterHelper.destroy();
138 }
139 }
140
141 @Override
142 protected void doPortalInit() throws Exception {
143 _invokerFilterChainSize = GetterUtil.getInteger(
144 PropsUtil.get(PropsKeys.INVOKER_FILTER_CHAIN_SIZE));
145
146 if (_invokerFilterChainSize > 0) {
147 _filterChains = new ConcurrentLFUCache<String, InvokerFilterChain>(
148 _invokerFilterChainSize);
149 }
150
151 ServletContext servletContext = _filterConfig.getServletContext();
152
153 InvokerFilterHelper invokerFilterHelper =
154 (InvokerFilterHelper)servletContext.getAttribute(
155 InvokerFilterHelper.class.getName());
156
157 if (invokerFilterHelper == null) {
158 invokerFilterHelper = new InvokerFilterHelper();
159
160 servletContext.setAttribute(
161 InvokerFilterHelper.class.getName(), invokerFilterHelper);
162
163 invokerFilterHelper.readLiferayFilterWebXML(
164 servletContext, "/WEB-INF/liferay-web.xml");
165 }
166
167 _invokerFilterHelper = invokerFilterHelper;
168
169 _invokerFilterHelper.addInvokerFilter(this);
170
171 String dispatcher = GetterUtil.getString(
172 _filterConfig.getInitParameter("dispatcher"));
173
174 if (dispatcher.equals("ERROR")) {
175 _dispatcher = Dispatcher.ERROR;
176 }
177 else if (dispatcher.equals("FORWARD")) {
178 _dispatcher = Dispatcher.FORWARD;
179 }
180 else if (dispatcher.equals("INCLUDE")) {
181 _dispatcher = Dispatcher.INCLUDE;
182 }
183 else if (dispatcher.equals("REQUEST")) {
184 _dispatcher = Dispatcher.REQUEST;
185 }
186 else {
187 throw new IllegalArgumentException(
188 "Invalid dispatcher " + dispatcher);
189 }
190 }
191
192 protected InvokerFilterChain getInvokerFilterChain(
193 HttpServletRequest request, String uri, FilterChain filterChain) {
194
195 if (_filterChains == null) {
196 return _invokerFilterHelper.createInvokerFilterChain(
197 request, _dispatcher, uri, filterChain);
198 }
199
200 CacheKeyGenerator cacheKeyGenerator =
201 CacheKeyGeneratorUtil.getCacheKeyGenerator(
202 InvokerFilter.class.getName());
203
204 String key = String.valueOf(cacheKeyGenerator.getCacheKey(uri));
205
206 InvokerFilterChain invokerFilterChain = _filterChains.get(key);
207
208 if (invokerFilterChain == null) {
209 invokerFilterChain = _invokerFilterHelper.createInvokerFilterChain(
210 request, _dispatcher, uri, filterChain);
211
212 _filterChains.put(key, invokerFilterChain);
213 }
214
215 return invokerFilterChain.clone(filterChain);
216 }
217
218 protected String getURI(HttpServletRequest request) {
219 String uri = null;
220
221 if (_dispatcher == Dispatcher.ERROR) {
222 uri = (String)request.getAttribute(
223 JavaConstants.JAVAX_SERVLET_ERROR_REQUEST_URI);
224 }
225 else if (_dispatcher == Dispatcher.INCLUDE) {
226 uri = (String)request.getAttribute(
227 JavaConstants.JAVAX_SERVLET_INCLUDE_REQUEST_URI);
228 }
229 else {
230 uri = request.getRequestURI();
231 }
232
233 if (Validator.isNotNull(_contextPath) &&
234 !_contextPath.equals(StringPool.SLASH) &&
235 uri.startsWith(_contextPath)) {
236
237 uri = uri.substring(_contextPath.length());
238 }
239
240 return uri;
241 }
242
243 protected HttpServletRequest handleNonSerializableRequest(
244 HttpServletRequest request) {
245
246 if (ServerDetector.isWebLogic()) {
247 if (!NonSerializableObjectRequestWrapper.isWrapped(request)) {
248 request = new NonSerializableObjectRequestWrapper(request);
249 }
250 }
251
252 return request;
253 }
254
255 protected HttpServletResponse secureResponseHeaders(
256 HttpServletResponse response) {
257
258 return new SecureHttpServletResponseWrapper(response);
259 }
260
261 private static Log _log = LogFactoryUtil.getLog(InvokerFilter.class);
262
263 private String _contextPath;
264 private Dispatcher _dispatcher;
265 private ConcurrentLFUCache<String, InvokerFilterChain> _filterChains;
266 private FilterConfig _filterConfig;
267 private int _invokerFilterChainSize;
268 private InvokerFilterHelper _invokerFilterHelper;
269
270 }