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