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