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