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