001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.server.dispatch;
031:
032: import com.caucho.servlet.comet.CometFilter;
033: import com.caucho.servlet.comet.CometFilterChain;
034: import com.caucho.log.Log;
035: import com.caucho.util.L10N;
036:
037: import javax.servlet.Filter;
038: import javax.servlet.FilterChain;
039: import javax.servlet.ServletContext;
040: import javax.servlet.ServletException;
041:
042: import java.util.ArrayList;
043: import java.util.logging.Logger;
044:
045: /**
046: * Manages dispatching: servlets and filters.
047: */
048: public class FilterMapper {
049: private static final Logger log = Logger
050: .getLogger(FilterMapper.class.getName());
051: private static final L10N L = new L10N(FilterMapper.class);
052:
053: private ServletContext _servletContext;
054:
055: private int _unique;
056: private FilterManager _filterManager;
057:
058: private ArrayList<FilterMapping> _filterMap = new ArrayList<FilterMapping>();
059:
060: private ArrayList<FilterChainBuilder> _topFilters = new ArrayList<FilterChainBuilder>();
061:
062: private ArrayList<FilterChainBuilder> _bottomFilters = new ArrayList<FilterChainBuilder>();
063:
064: /**
065: * Sets the servlet context.
066: */
067: public void setServletContext(ServletContext servletContext) {
068: _servletContext = servletContext;
069: }
070:
071: /**
072: * Gets the servlet context.
073: */
074: public ServletContext getServletContext() {
075: return _servletContext;
076: }
077:
078: /**
079: * Returns the filter manager.
080: */
081: public FilterManager getFilterManager() {
082: return _filterManager;
083: }
084:
085: /**
086: * Sets the filter manager.
087: */
088: public void setFilterManager(FilterManager manager) {
089: _filterManager = manager;
090: }
091:
092: /**
093: * Adds a filter mapping
094: */
095: public void addFilterMapping(FilterMapping mapping)
096: throws ServletException {
097: try {
098: String filterName = mapping.getFilterName();
099:
100: if (filterName == null)
101: filterName = mapping.getFilterClassName();
102:
103: if (mapping.getFilterClassName() != null
104: && _filterManager.getFilter(filterName) == null) {
105: _filterManager.addFilter(mapping);
106: }
107:
108: if (_filterManager.getFilter(filterName) == null)
109: throw new ServletConfigException(
110: L
111: .l(
112: "'{0}' is an unknown filter-name. filter-mapping requires that the named filter be defined in a <filter> configuration before the <filter-mapping>.",
113: filterName));
114:
115: _filterMap.add(mapping);
116:
117: log.fine("filter-mapping " + mapping + " -> " + filterName);
118: } catch (ServletException e) {
119: throw e;
120: } catch (Exception e) {
121: throw new ServletException(e);
122: }
123: }
124:
125: /**
126: * Adds a top-filter. Top filters are added to every request
127: * in the filter chain.
128: */
129: public void addTopFilter(FilterChainBuilder filterBuilder) {
130: _topFilters.add(filterBuilder);
131: }
132:
133: /**
134: * Fills in the invocation.
135: */
136: public void buildDispatchChain(Invocation invocation,
137: FilterChain chain) throws ServletException {
138: synchronized (_filterMap) {
139: for (int i = _filterMap.size() - 1; i >= 0; i--) {
140: FilterMapping map = _filterMap.get(i);
141:
142: if (map.isMatch(invocation.getServletName())) {
143: String filterName = map.getFilterName();
144:
145: Filter filter = _filterManager
146: .createFilter(filterName);
147:
148: chain = addFilter(chain, filter);
149: }
150: }
151: }
152:
153: synchronized (_filterMap) {
154: for (int i = _filterMap.size() - 1; i >= 0; i--) {
155: FilterMapping map = _filterMap.get(i);
156:
157: if (map.isMatch(invocation)) {
158: String filterName = map.getFilterName();
159:
160: Filter filter = _filterManager
161: .createFilter(filterName);
162:
163: chain = addFilter(chain, filter);
164: }
165: }
166: }
167:
168: for (int i = 0; i < _topFilters.size(); i++) {
169: FilterChainBuilder filterBuilder;
170: filterBuilder = _topFilters.get(i);
171:
172: chain = filterBuilder.build(chain, invocation);
173: }
174:
175: invocation.setFilterChain(chain);
176: }
177:
178: /**
179: * Fills in the invocation.
180: */
181: public FilterChain buildFilterChain(FilterChain chain,
182: String servletName) throws ServletException {
183: synchronized (_filterMap) {
184: for (int i = _filterMap.size() - 1; i >= 0; i--) {
185: FilterMapping map = _filterMap.get(i);
186:
187: if (map.isMatch(servletName)) {
188: String filterName = map.getFilterName();
189:
190: Filter filter = _filterManager
191: .createFilter(filterName);
192:
193: chain = addFilter(chain, filter);
194: }
195: }
196: }
197:
198: return chain;
199: }
200:
201: private FilterChain addFilter(FilterChain chain, Filter filter) {
202: if (filter instanceof CometFilter
203: && chain instanceof CometFilterChain) {
204: CometFilter cometFilter = (CometFilter) filter;
205: CometFilterChain cometChain = (CometFilterChain) chain;
206:
207: return new CometFilterFilterChain(cometChain, cometFilter);
208: } else
209: return new FilterFilterChain(chain, filter);
210: }
211: }
|