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