001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.geronimo.jetty6;
018
019 import java.util.Collection;
020 import java.util.Arrays;
021
022 import org.apache.geronimo.gbean.GBeanInfo;
023 import org.apache.geronimo.gbean.GBeanInfoBuilder;
024 import org.apache.geronimo.gbean.ReferenceCollection;
025 import org.apache.geronimo.gbean.ReferenceCollectionEvent;
026 import org.apache.geronimo.gbean.ReferenceCollectionListener;
027 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
028 import org.mortbay.jetty.Handler;
029 import org.mortbay.jetty.servlet.FilterMapping;
030 import org.mortbay.jetty.servlet.ServletHandler;
031
032 /**
033 * @version $Rev: 550559 $ $Date: 2007-06-25 13:33:39 -0400 (Mon, 25 Jun 2007) $
034 */
035 public class JettyFilterMapping extends FilterMapping {
036
037 private final String[] urlPatterns;
038 private final boolean requestDispatch;
039 private final boolean forwardDispatch;
040 private final boolean includeDispatch;
041 private final boolean errorDispatch;
042 private final JettyFilterHolder jettyFilterHolder;
043 private final Collection<JettyServletHolder> jettyServletHolders;
044 private final JettyFilterMapping previous;
045 private final JettyServletRegistration jettyServletRegistration;
046
047 //todo use an interface for endpoints.
048 public JettyFilterMapping() {
049 this.urlPatterns = null;
050 this.requestDispatch = false;
051 this.forwardDispatch = false;
052 this.includeDispatch = false;
053 this.errorDispatch = false;
054 this.jettyFilterHolder = null;
055 this.jettyServletHolders = null;
056 this.previous = null;
057 this.jettyServletRegistration = null;
058 }
059
060 public JettyFilterMapping(String[] urlPatterns,
061 boolean requestDispatch,
062 boolean forwardDispatch,
063 boolean includeDispatch,
064 boolean errorDispatch,
065 JettyFilterHolder jettyFilterHolder,
066 Collection<JettyServletHolder> jettyServletHolders,
067 JettyFilterMapping previous,
068 JettyServletRegistration jettyServletRegistration) {
069 this.urlPatterns = urlPatterns;
070 this.requestDispatch = requestDispatch;
071 this.forwardDispatch = forwardDispatch;
072 this.includeDispatch = includeDispatch;
073 this.errorDispatch = errorDispatch;
074 this.jettyFilterHolder = jettyFilterHolder;
075 this.jettyServletHolders = jettyServletHolders;
076 this.previous = previous;
077 this.jettyServletRegistration = jettyServletRegistration;
078
079 if (jettyServletRegistration != null) {
080 assert jettyServletHolders != null ^ urlPatterns != null;
081
082 String filterName = jettyFilterHolder.getFilterName();
083 int dispatches = 0;
084 if (requestDispatch) {
085 dispatches |= Handler.REQUEST;
086 }
087 if (forwardDispatch) {
088 dispatches |= Handler.FORWARD;
089 }
090 if (includeDispatch) {
091 dispatches |= Handler.INCLUDE;
092 }
093 if (errorDispatch) {
094 dispatches |= Handler.ERROR;
095 }
096
097
098 setFilterName(filterName);
099 setDispatches(dispatches);
100 setPathSpecs(urlPatterns);
101 if (jettyServletHolders != null) {
102 resetServlets();
103 if (jettyServletHolders instanceof ReferenceCollection) {
104 ((ReferenceCollection) jettyServletHolders).addReferenceCollectionListener(new ReferenceCollectionListener() {
105
106 public void memberAdded(ReferenceCollectionEvent event) {
107 resetServlets();
108 resetJettyFilterMappings();
109 }
110
111 public void memberRemoved(ReferenceCollectionEvent event) {
112 resetServlets();
113 resetJettyFilterMappings();
114 }
115 });
116 }
117 }
118
119 jettyServletRegistration.getServletHandler().addFilterMapping(this);
120 }
121 }
122
123 private void resetJettyFilterMappings() {
124 //This causes jetty to recompute the filter to servlet mappings based on the
125 //current servlet names in the filter mappings. Pretty inefficient.
126 ServletHandler servletHandler = jettyServletRegistration.getServletHandler();
127 FilterMapping[] filterMappings = servletHandler.getFilterMappings();
128 FilterMapping[] copy = filterMappings.clone();
129 servletHandler.setFilterMappings(copy);
130 }
131
132 private void resetServlets() {
133 String[] servletNames = new String[jettyServletHolders.size()];
134 int i = 0;
135 for (JettyServletHolder jettyServletHolder : jettyServletHolders) {
136 servletNames[i++] = jettyServletHolder.getServletName();
137 }
138 setServletNames(servletNames);
139 }
140
141 public String[] getUrlPatterns() {
142 return urlPatterns;
143 }
144
145 public boolean isRequestDispatch() {
146 return requestDispatch;
147 }
148
149 public boolean isForwardDispatch() {
150 return forwardDispatch;
151 }
152
153 public boolean isIncludeDispatch() {
154 return includeDispatch;
155 }
156
157 public boolean isErrorDispatch() {
158 return errorDispatch;
159 }
160
161 public JettyFilterHolder getFilter() {
162 return jettyFilterHolder;
163 }
164
165 public Collection<JettyServletHolder> getServlets() {
166 return jettyServletHolders;
167 }
168
169 public JettyFilterMapping getPrevious() {
170 return previous;
171 }
172
173 public JettyServletRegistration getJettyServletRegistration() {
174 return jettyServletRegistration;
175 }
176
177 public static final GBeanInfo GBEAN_INFO;
178
179 static {
180 GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(JettyFilterMapping.class, NameFactory.URL_WEB_FILTER_MAPPING);
181 infoBuilder.addAttribute("urlPatterns", String[].class, true);
182 infoBuilder.addAttribute("requestDispatch", boolean.class, true);
183 infoBuilder.addAttribute("forwardDispatch", boolean.class, true);
184 infoBuilder.addAttribute("includeDispatch", boolean.class, true);
185 infoBuilder.addAttribute("errorDispatch", boolean.class, true);
186
187 infoBuilder.addReference("Filter", JettyFilterHolder.class, NameFactory.WEB_FILTER);
188 infoBuilder.addReference("Servlets", JettyServletHolder.class, NameFactory.SERVLET);
189 infoBuilder.addReference("Previous", JettyFilterMapping.class, NameFactory.URL_WEB_FILTER_MAPPING);
190 infoBuilder.addReference("JettyServletRegistration", JettyServletRegistration.class, NameFactory.WEB_MODULE);
191
192 infoBuilder.setConstructor(new String[]{"urlPatterns",
193 "requestDispatch",
194 "forwardDispatch",
195 "includeDispatch",
196 "errorDispatch",
197 "Filter",
198 "Servlets",
199 "Previous",
200 "JettyServletRegistration"});
201
202 GBEAN_INFO = infoBuilder.getBeanInfo();
203 }
204
205 public static GBeanInfo getGBeanInfo() {
206 return GBEAN_INFO;
207 }
208 }