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 }