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