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