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