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