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