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.PortletServlet;
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 void initFilter(
177 ServletContext servletContext, String filterName,
178 String filterClassName, Map<String, String> initParameterMap)
179 throws Exception {
180
181 ClassLoader contextClassLoader =
182 (ClassLoader)servletContext.getAttribute(
183 PortletServlet.PORTLET_CLASS_LOADER);
184
185 if (contextClassLoader == null) {
186 Thread currentThread = Thread.currentThread();
187
188 contextClassLoader = currentThread.getContextClassLoader();
189 }
190
191 Filter filter = (Filter)InstanceFactory.newInstance(
192 contextClassLoader, filterClassName);
193
194 FilterConfig filterConfig = new InvokerFilterConfig(
195 servletContext, filterName, initParameterMap);
196
197 filter.init(filterConfig);
198
199 boolean filterEnabled = true;
200
201 if (filter instanceof LiferayFilter) {
202 LiferayFilter liferayFilter = (LiferayFilter)filter;
203
204 filterEnabled = liferayFilter.isFilterEnabled();
205 }
206
207 if (filterEnabled) {
208 _filterConfigs.put(filterName, filterConfig);
209 _filters.put(filterName, filter);
210 }
211 else {
212 if (filter instanceof PortalLifecycle) {
213 PortalLifecycle portalLifecycle = (PortalLifecycle)filter;
214
215 PortalLifecycleUtil.removeDestroy(portalLifecycle);
216 }
217
218 if (_log.isDebugEnabled()) {
219 _log.debug("Removing disabled filter " + filter.getClass());
220 }
221 }
222 }
223
224 protected void initFilterMapping(
225 String filterName, List<String> urlPatterns, List<String> dispatchers) {
226
227 Filter filter = _filters.get(filterName);
228
229 if (filter == null) {
230 return;
231 }
232
233 FilterConfig filterConfig = _filterConfigs.get(filterName);
234
235 if (filterConfig == null) {
236 return;
237 }
238
239 FilterMapping filterMapping = new FilterMapping(
240 filter, filterConfig, urlPatterns, dispatchers);
241
242 _filterMappings.add(filterMapping);
243 }
244
245 protected void readLiferayFilterWebXML(
246 ServletContext servletContext, String path)
247 throws Exception {
248
249 InputStream inputStream = servletContext.getResourceAsStream(path);
250
251 if (inputStream == null) {
252 return;
253 }
254
255 Document document = SAXReaderUtil.read(inputStream, true);
256
257 Element rootElement = document.getRootElement();
258
259 List<Element> filterElements = rootElement.elements("filter");
260
261 for (Element filterElement : filterElements) {
262 String filterName = filterElement.elementText("filter-name");
263 String filterClassName = filterElement.elementText("filter-class");
264
265 Map<String, String> initParameterMap =
266 new HashMap<String, String>();
267
268 List<Element> initParamElements = filterElement.elements(
269 "init-param");
270
271 for (Element initParamElement : initParamElements) {
272 String name = initParamElement.elementText("param-name");
273 String value = initParamElement.elementText("param-value");
274
275 initParameterMap.put(name, value);
276 }
277
278 initFilter(
279 servletContext, filterName, filterClassName, initParameterMap);
280 }
281
282 List<Element> filterMappingElements = rootElement.elements(
283 "filter-mapping");
284
285 for (Element filterMappingElement : filterMappingElements) {
286 String filterName = filterMappingElement.elementText("filter-name");
287
288 List<String> urlPatterns = new ArrayList<String>();
289
290 List<Element> urlPatternElements = filterMappingElement.elements(
291 "url-pattern");
292
293 for (Element urlPatternElement : urlPatternElements) {
294 urlPatterns.add(urlPatternElement.getTextTrim());
295 }
296
297 List<String> dispatchers = new ArrayList<String>(4);
298
299 List<Element> dispatcherElements = filterMappingElement.elements(
300 "dispatcher");
301
302 for (Element dispatcherElement : dispatcherElements) {
303 String dispatcher =
304 dispatcherElement.getTextTrim().toUpperCase();
305
306 dispatchers.add(dispatcher);
307 }
308
309 initFilterMapping(filterName, urlPatterns, dispatchers);
310 }
311 }
312
313 private static Log _log = LogFactoryUtil.getLog(InvokerFilter.class);
314
315 private Map<String, FilterConfig> _filterConfigs =
316 new HashMap<String, FilterConfig>();
317 private List<FilterMapping> _filterMappings =
318 new CopyOnWriteArrayList<FilterMapping>();
319 private Map<String, Filter> _filters = new HashMap<String, Filter>();
320 private List<InvokerFilter> _invokerFilters =
321 new ArrayList<InvokerFilter>();
322
323 }