001
014
015 package com.liferay.portal.kernel.servlet.filters.invoker;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.servlet.LiferayFilter;
020 import com.liferay.portal.kernel.servlet.PluginContextListener;
021 import com.liferay.portal.kernel.util.InstanceFactory;
022 import com.liferay.portal.kernel.util.PortalLifecycle;
023 import com.liferay.portal.kernel.util.PortalLifecycleUtil;
024 import com.liferay.portal.kernel.util.StringUtil;
025 import com.liferay.portal.kernel.util.Validator;
026 import com.liferay.portal.kernel.xml.Document;
027 import com.liferay.portal.kernel.xml.Element;
028 import com.liferay.portal.kernel.xml.SAXReaderUtil;
029
030 import java.io.InputStream;
031
032 import java.util.ArrayList;
033 import java.util.HashMap;
034 import java.util.List;
035 import java.util.Map;
036 import java.util.concurrent.CopyOnWriteArrayList;
037
038 import javax.servlet.Filter;
039 import javax.servlet.FilterChain;
040 import javax.servlet.FilterConfig;
041 import javax.servlet.ServletContext;
042 import javax.servlet.ServletException;
043 import javax.servlet.http.HttpServletRequest;
044
045
049 public class InvokerFilterHelper {
050
051 public void destroy() {
052 for (Map.Entry<String, Filter> entry : _filters.entrySet()) {
053 Filter filter = entry.getValue();
054
055 try {
056 filter.destroy();
057 }
058 catch (Exception e) {
059 _log.error(e, e);
060 }
061 }
062
063 _filterConfigs.clear();
064 _filterMappings.clear();
065 _filters.clear();
066
067 for (InvokerFilter invokerFilter : _invokerFilters) {
068 invokerFilter.clearFilterChainsCache();
069 }
070 }
071
072 public Filter getFilter(String filterName) {
073 return _filters.get(filterName);
074 }
075
076 public FilterConfig getFilterConfig(String filterName) {
077 return _filterConfigs.get(filterName);
078 }
079
080 public void init(FilterConfig filterConfig) throws ServletException {
081 try {
082 ServletContext servletContext = filterConfig.getServletContext();
083
084 readLiferayFilterWebXML(servletContext, "/WEB-INF/liferay-web.xml");
085 }
086 catch (Exception e) {
087 _log.error(e, e);
088
089 throw new ServletException(e);
090 }
091 }
092
093 public Filter registerFilter(String filterName, Filter filter) {
094 Filter previousFilter = _filters.put(filterName, filter);
095
096 if (previousFilter != null) {
097 for (FilterMapping filterMapping : _filterMappings) {
098 if (filterMapping.getFilter() == previousFilter) {
099 if (filter != null) {
100 filterMapping.setFilter(filter);
101 }
102 else {
103 _filterMappings.remove(filterMapping);
104 _filterConfigs.remove(filterName);
105 }
106 }
107 }
108 }
109
110 for (InvokerFilter invokerFilter : _invokerFilters) {
111 invokerFilter.clearFilterChainsCache();
112 }
113
114 return previousFilter;
115 }
116
117 public void registerFilterMapping(
118 FilterMapping filterMapping, String filterName, boolean after) {
119
120 int i = 0;
121
122 if (Validator.isNotNull(filterName)) {
123 Filter filter = _filters.get(filterName);
124
125 if (filter != null) {
126 for (; i < _filterMappings.size(); i++) {
127 FilterMapping currentFilterMapping = _filterMappings.get(i);
128
129 if (currentFilterMapping.getFilter() == filter) {
130 break;
131 }
132 }
133 }
134 }
135
136 if (after) {
137 i++;
138 }
139
140 _filterMappings.add(i, filterMapping);
141
142 for (InvokerFilter invokerFilter : _invokerFilters) {
143 invokerFilter.clearFilterChainsCache();
144 }
145 }
146
147 public void unregisterFilterMapping(FilterMapping filterMapping) {
148 _filterMappings.remove(filterMapping);
149
150 for (InvokerFilter invokerFilter : _invokerFilters) {
151 invokerFilter.clearFilterChainsCache();
152 }
153 }
154
155 protected void addInvokerFilter(InvokerFilter invokerFilter) {
156 _invokerFilters.add(invokerFilter);
157 }
158
159 protected InvokerFilterChain createInvokerFilterChain(
160 HttpServletRequest request, Dispatcher dispatcher, String uri,
161 FilterChain filterChain) {
162
163 InvokerFilterChain invokerFilterChain = new InvokerFilterChain(
164 filterChain);
165
166 for (FilterMapping filterMapping : _filterMappings) {
167 if (filterMapping.isMatch(request, dispatcher, uri)) {
168 Filter filter = filterMapping.getFilter();
169
170 invokerFilterChain.addFilter(filter);
171 }
172 }
173
174 return invokerFilterChain;
175 }
176
177 protected Filter getFilter(
178 ServletContext servletContext, String filterClassName,
179 FilterConfig filterConfig) {
180
181 ClassLoader pluginClassLoader = getPluginClassLoader(servletContext);
182
183 Thread currentThread = Thread.currentThread();
184
185 ClassLoader contextClassLoader = currentThread.getContextClassLoader();
186
187 try {
188 if (contextClassLoader != pluginClassLoader) {
189 currentThread.setContextClassLoader(pluginClassLoader);
190 }
191
192 Filter filter = (Filter)InstanceFactory.newInstance(
193 pluginClassLoader, filterClassName);
194
195 filter.init(filterConfig);
196
197 return filter;
198 }
199 catch (Exception e) {
200 _log.error("Unable to initialize filter " + filterClassName, e);
201 }
202 finally {
203 if (contextClassLoader != pluginClassLoader) {
204 currentThread.setContextClassLoader(contextClassLoader);
205 }
206 }
207
208 return null;
209 }
210
211 protected ClassLoader getPluginClassLoader(ServletContext servletContext) {
212 ClassLoader classLoader = (ClassLoader)servletContext.getAttribute(
213 PluginContextListener.PLUGIN_CLASS_LOADER);
214
215 if (classLoader != null) {
216 return classLoader;
217 }
218
219 Thread currentThread = Thread.currentThread();
220
221 return currentThread.getContextClassLoader();
222 }
223
224 protected void initFilter(
225 ServletContext servletContext, String filterName,
226 String filterClassName, Map<String, String> initParameterMap)
227 throws Exception {
228
229 FilterConfig filterConfig = new InvokerFilterConfig(
230 servletContext, filterName, initParameterMap);
231
232 Filter filter = getFilter(
233 servletContext, filterClassName, filterConfig);
234
235 if (filter == null) {
236 return;
237 }
238
239 boolean filterEnabled = true;
240
241 if (filter instanceof LiferayFilter) {
242
243
244
245
246
247
248
249
250 }
251
252 if (filterEnabled) {
253 _filterConfigs.put(filterName, filterConfig);
254 _filters.put(filterName, filter);
255 }
256 else {
257 if (filter instanceof PortalLifecycle) {
258 PortalLifecycle portalLifecycle = (PortalLifecycle)filter;
259
260 PortalLifecycleUtil.removeDestroy(portalLifecycle);
261 }
262
263 if (_log.isDebugEnabled()) {
264 _log.debug("Removing disabled filter " + filter.getClass());
265 }
266 }
267 }
268
269 protected void initFilterMapping(
270 String filterName, List<String> urlPatterns, List<String> dispatchers) {
271
272 Filter filter = _filters.get(filterName);
273
274 if (filter == null) {
275 return;
276 }
277
278 FilterConfig filterConfig = _filterConfigs.get(filterName);
279
280 if (filterConfig == null) {
281 return;
282 }
283
284 FilterMapping filterMapping = new FilterMapping(
285 filter, filterConfig, urlPatterns, dispatchers);
286
287 _filterMappings.add(filterMapping);
288 }
289
290 protected void readLiferayFilterWebXML(
291 ServletContext servletContext, String path)
292 throws Exception {
293
294 InputStream inputStream = servletContext.getResourceAsStream(path);
295
296 if (inputStream == null) {
297 return;
298 }
299
300 Document document = SAXReaderUtil.read(inputStream, true);
301
302 Element rootElement = document.getRootElement();
303
304 List<Element> filterElements = rootElement.elements("filter");
305
306 for (Element filterElement : filterElements) {
307 String filterName = filterElement.elementText("filter-name");
308 String filterClassName = filterElement.elementText("filter-class");
309
310 Map<String, String> initParameterMap =
311 new HashMap<String, String>();
312
313 List<Element> initParamElements = filterElement.elements(
314 "init-param");
315
316 for (Element initParamElement : initParamElements) {
317 String name = initParamElement.elementText("param-name");
318 String value = initParamElement.elementText("param-value");
319
320 initParameterMap.put(name, value);
321 }
322
323 initFilter(
324 servletContext, filterName, filterClassName, initParameterMap);
325 }
326
327 List<Element> filterMappingElements = rootElement.elements(
328 "filter-mapping");
329
330 for (Element filterMappingElement : filterMappingElements) {
331 String filterName = filterMappingElement.elementText("filter-name");
332
333 List<String> urlPatterns = new ArrayList<String>();
334
335 List<Element> urlPatternElements = filterMappingElement.elements(
336 "url-pattern");
337
338 for (Element urlPatternElement : urlPatternElements) {
339 urlPatterns.add(urlPatternElement.getTextTrim());
340 }
341
342 List<String> dispatchers = new ArrayList<String>(4);
343
344 List<Element> dispatcherElements = filterMappingElement.elements(
345 "dispatcher");
346
347 for (Element dispatcherElement : dispatcherElements) {
348 String dispatcher = StringUtil.toUpperCase(
349 dispatcherElement.getTextTrim());
350
351 dispatchers.add(dispatcher);
352 }
353
354 initFilterMapping(filterName, urlPatterns, dispatchers);
355 }
356 }
357
358 private static Log _log = LogFactoryUtil.getLog(InvokerFilterHelper.class);
359
360 private Map<String, FilterConfig> _filterConfigs =
361 new HashMap<String, FilterConfig>();
362 private List<FilterMapping> _filterMappings =
363 new CopyOnWriteArrayList<FilterMapping>();
364 private Map<String, Filter> _filters = new HashMap<String, Filter>();
365 private List<InvokerFilter> _invokerFilters =
366 new ArrayList<InvokerFilter>();
367
368 }