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