Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 1 | /* |
Richard S. Hall | 435c20c | 2006-09-28 20:11:35 +0000 | [diff] [blame] | 2 | * Licensed to the Apache Software Foundation (ASF) under one |
| 3 | * or more contributor license agreements. See the NOTICE file |
| 4 | * distributed with this work for additional information |
| 5 | * regarding copyright ownership. The ASF licenses this file |
| 6 | * to you under the Apache License, Version 2.0 (the |
| 7 | * "License"); you may not use this file except in compliance |
| 8 | * with the License. You may obtain a copy of the License at |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 9 | * |
Richard S. Hall | 435c20c | 2006-09-28 20:11:35 +0000 | [diff] [blame] | 10 | * http://www.apache.org/licenses/LICENSE-2.0 |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 11 | * |
Richard S. Hall | 435c20c | 2006-09-28 20:11:35 +0000 | [diff] [blame] | 12 | * Unless required by applicable law or agreed to in writing, |
| 13 | * software distributed under the License is distributed on an |
| 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| 15 | * KIND, either express or implied. See the License for the |
| 16 | * specific language governing permissions and limitations |
| 17 | * under the License. |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 18 | */ |
| 19 | package org.apache.felix.http.jetty; |
| 20 | |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 21 | |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 22 | import java.security.AccessControlContext; |
| 23 | import java.security.AccessController; |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 24 | import java.util.Dictionary; |
| 25 | import java.util.HashMap; |
| 26 | import java.util.HashSet; |
| 27 | import java.util.Map; |
| 28 | import java.util.Set; |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 29 | |
| 30 | import javax.servlet.Servlet; |
| 31 | import javax.servlet.ServletException; |
| 32 | |
Felix Meschberger | c7ee015 | 2008-03-26 09:24:35 +0000 | [diff] [blame] | 33 | import org.mortbay.jetty.Server; |
| 34 | import org.mortbay.jetty.servlet.Context; |
| 35 | import org.mortbay.jetty.servlet.OsgiResourceHolder; |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 36 | import org.mortbay.jetty.servlet.OsgiServletHandler; |
Felix Meschberger | c7ee015 | 2008-03-26 09:24:35 +0000 | [diff] [blame] | 37 | import org.mortbay.jetty.servlet.SessionHandler; |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 38 | import org.osgi.framework.Bundle; |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 39 | import org.osgi.service.http.HttpContext; |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 40 | import org.osgi.service.http.HttpService; |
| 41 | import org.osgi.service.http.NamespaceException; |
Felix Meschberger | c7ee015 | 2008-03-26 09:24:35 +0000 | [diff] [blame] | 42 | import org.osgi.service.log.LogService; |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 43 | |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 44 | |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 45 | public class HttpServiceImpl implements HttpService |
| 46 | { |
| 47 | /** global namesspace of all aliases that have been registered */ |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 48 | private static Map m_aliasNamespace = null; |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 49 | |
| 50 | /** local list of aliases registered by the bundle holding this service */ |
| 51 | private Set m_localAliasSet = null; |
| 52 | |
| 53 | /** Bundle which "got" this service instance from the service factory */ |
| 54 | private Bundle m_bundle = null; |
Felix Meschberger | c7ee015 | 2008-03-26 09:24:35 +0000 | [diff] [blame] | 55 | private Server m_server = null; |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 56 | private OsgiServletHandler m_serverServletHandler = null; |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 57 | |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 58 | |
Felix Meschberger | c7ee015 | 2008-03-26 09:24:35 +0000 | [diff] [blame] | 59 | public HttpServiceImpl( Bundle bundle, Server server, OsgiServletHandler serverServletHandler ) |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 60 | { |
| 61 | m_bundle = bundle; |
| 62 | m_server = server; |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 63 | m_serverServletHandler = serverServletHandler; |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 64 | m_localAliasSet = new HashSet(); |
| 65 | |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 66 | if ( m_aliasNamespace == null ) |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 67 | { |
| 68 | m_aliasNamespace = new HashMap(); |
| 69 | } |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 70 | } |
| 71 | |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 72 | |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 73 | /** |
| 74 | * Initializes static variables. |
| 75 | **/ |
| 76 | public static void initializeStatics() |
| 77 | { |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 78 | if ( m_aliasNamespace != null ) |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 79 | { |
| 80 | m_aliasNamespace.clear(); |
| 81 | } |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 82 | ServletContextGroup.initializeStatics(); |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 83 | } |
| 84 | |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 85 | |
| 86 | public HttpContext createDefaultHttpContext() |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 87 | { |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 88 | return new DefaultContextImpl( m_bundle ); |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 89 | } |
| 90 | |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 91 | |
| 92 | public void registerServlet( String alias, Servlet servlet, Dictionary params, HttpContext osgiHttpContext ) |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 93 | throws ServletException, NamespaceException |
| 94 | { |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 95 | Activator.debug( "http register servlet :" + m_bundle + ", alias: " + alias ); |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 96 | |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 97 | if ( !aliasValid( alias ) ) |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 98 | { |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 99 | throw new IllegalArgumentException( "malformed alias" ); |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 100 | } |
| 101 | |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 102 | if ( ServletContextGroup.isServletRegistered( servlet ) ) |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 103 | { |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 104 | throw new ServletException( "servlet already registered" ); |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 105 | } |
| 106 | |
| 107 | // add alias with null details, and record servlet instance details |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 108 | addAlias( alias, null ); |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 109 | |
| 110 | //make sure alias is unique, and create |
| 111 | ServletContextGroup grp = null; |
| 112 | |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 113 | if ( osgiHttpContext == null ) |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 114 | { |
| 115 | osgiHttpContext = createDefaultHttpContext(); |
| 116 | } |
| 117 | |
| 118 | // servlets using same context must get same handler to ensure |
| 119 | // they share a common ServletContext |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 120 | Activator.debug( "looking for context: " + osgiHttpContext ); |
| 121 | grp = ServletContextGroup.getServletContextGroup( m_serverServletHandler, osgiHttpContext ); |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 122 | |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 123 | grp.addServlet( servlet, alias, params ); |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 124 | |
| 125 | // update alias namespace with reference to group object for later |
| 126 | // unregistering |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 127 | updateAlias( alias, grp ); |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 128 | |
| 129 | // maybe should remove alias/servlet entries if exceptions? |
| 130 | } |
| 131 | |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 132 | |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 133 | public void registerResources( String alias, String name, HttpContext osgiHttpContext ) throws NamespaceException |
| 134 | { |
| 135 | Activator.debug( "** http register resource :" + m_bundle + ", alias: " + alias ); |
| 136 | |
| 137 | if ( !aliasValid( alias ) ) |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 138 | { |
Rob Walker | 48cb243 | 2008-10-13 14:30:43 +0000 | [diff] [blame] | 139 | throw new IllegalArgumentException( "malformed alias: " + alias); |
| 140 | } |
| 141 | |
| 142 | if ( !nameValid( name ) ) |
| 143 | { |
| 144 | throw new IllegalArgumentException( "malformed name: " + name); |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 145 | } |
| 146 | |
| 147 | // add alias with null details |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 148 | addAlias( alias, null ); |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 149 | |
| 150 | //make sure alias is unique, and create |
Felix Meschberger | c7ee015 | 2008-03-26 09:24:35 +0000 | [diff] [blame] | 151 | Context hdlrContext = null; |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 152 | |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 153 | if ( osgiHttpContext == null ) |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 154 | { |
| 155 | osgiHttpContext = createDefaultHttpContext(); |
| 156 | } |
| 157 | |
Felix Meschberger | c7ee015 | 2008-03-26 09:24:35 +0000 | [diff] [blame] | 158 | // servlets using same context must get same handler to ensure |
| 159 | // they share a common ServletContext |
| 160 | Activator.debug( "looking for context: " + osgiHttpContext ); |
| 161 | ServletContextGroup grp = ServletContextGroup.getServletContextGroup( m_serverServletHandler, osgiHttpContext ); |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 162 | |
Felix Meschberger | c7ee015 | 2008-03-26 09:24:35 +0000 | [diff] [blame] | 163 | grp.addResource( alias, name ); |
| 164 | |
| 165 | // update alias namespace with reference to group object for later |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 166 | // unregistering |
Felix Meschberger | c7ee015 | 2008-03-26 09:24:35 +0000 | [diff] [blame] | 167 | updateAlias( alias, grp ); |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 168 | |
Felix Meschberger | c7ee015 | 2008-03-26 09:24:35 +0000 | [diff] [blame] | 169 | // maybe should remove alias/servlet entries if exceptions? |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 170 | } |
| 171 | |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 172 | |
| 173 | public void unregister( String alias ) |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 174 | { |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 175 | doUnregister( alias, true ); |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 176 | } |
| 177 | |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 178 | |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 179 | protected void unregisterAll() |
| 180 | { |
| 181 | // note that this is a forced unregister, so we shouldn't call destroy |
| 182 | // on any servlets |
| 183 | // unregister each alias for the bundle - copy list since it will |
| 184 | // change |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 185 | String[] all = ( String[] ) m_localAliasSet.toArray( new String[0] ); |
| 186 | for ( int ix = 0; ix < all.length; ix++ ) |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 187 | { |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 188 | doUnregister( all[ix], false ); |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 189 | } |
| 190 | } |
| 191 | |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 192 | |
| 193 | protected void doUnregister( String alias, boolean forced ) |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 194 | { |
Felix Meschberger | c7ee015 | 2008-03-26 09:24:35 +0000 | [diff] [blame] | 195 | Activator.debug( "** http unregister servlet :" + m_bundle + ", alias: " + alias + ",forced:" + forced ); |
| 196 | ServletContextGroup grp = removeAlias( alias ); |
| 197 | if ( grp != null ) |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 198 | { |
Felix Meschberger | c7ee015 | 2008-03-26 09:24:35 +0000 | [diff] [blame] | 199 | grp.remove( alias, forced ); |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 200 | } |
| 201 | } |
| 202 | |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 203 | |
| 204 | protected void addAlias( String alias, Object obj ) throws NamespaceException |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 205 | { |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 206 | synchronized ( m_aliasNamespace ) |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 207 | { |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 208 | if ( m_aliasNamespace.containsKey( alias ) ) |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 209 | { |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 210 | throw new NamespaceException( "alias already registered" ); |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 211 | } |
| 212 | |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 213 | m_aliasNamespace.put( alias, obj ); |
| 214 | m_localAliasSet.add( alias ); |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 215 | } |
| 216 | } |
| 217 | |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 218 | |
Felix Meschberger | c7ee015 | 2008-03-26 09:24:35 +0000 | [diff] [blame] | 219 | protected ServletContextGroup removeAlias( String alias ) |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 220 | { |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 221 | synchronized ( m_aliasNamespace ) |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 222 | { |
| 223 | // remove alias, don't worry if doesn't exist |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 224 | Object obj = m_aliasNamespace.remove( alias ); |
| 225 | m_localAliasSet.remove( alias ); |
Felix Meschberger | c7ee015 | 2008-03-26 09:24:35 +0000 | [diff] [blame] | 226 | return ( ServletContextGroup ) obj; |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 227 | } |
| 228 | } |
| 229 | |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 230 | |
| 231 | protected void updateAlias( String alias, Object obj ) |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 232 | { |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 233 | synchronized ( m_aliasNamespace ) |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 234 | { |
| 235 | // only update if already present |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 236 | if ( m_aliasNamespace.containsKey( alias ) ) |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 237 | { |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 238 | m_aliasNamespace.put( alias, obj ); |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 239 | } |
| 240 | } |
| 241 | } |
| 242 | |
Felix Meschberger | b76cfdb | 2007-09-28 14:13:22 +0000 | [diff] [blame] | 243 | |
| 244 | protected boolean aliasValid( String alias ) |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 245 | { |
Rob Walker | 48cb243 | 2008-10-13 14:30:43 +0000 | [diff] [blame] | 246 | if (alias == null) |
| 247 | { |
| 248 | return false; |
| 249 | } |
| 250 | |
| 251 | if (!alias.equals( "/" ) && ( !alias.startsWith( "/" ) || alias.endsWith( "/" ) ) ) |
| 252 | { |
| 253 | return false; |
| 254 | } |
| 255 | |
| 256 | return true; |
| 257 | } |
| 258 | |
| 259 | |
| 260 | protected boolean nameValid( String name ) |
| 261 | { |
| 262 | if (name == null) |
| 263 | { |
| 264 | return false; |
| 265 | } |
| 266 | |
| 267 | if (name.endsWith( "/" )) |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 268 | { |
| 269 | return false; |
| 270 | } |
| 271 | |
| 272 | return true; |
| 273 | } |
Richard S. Hall | fe8e560 | 2006-04-19 15:23:22 +0000 | [diff] [blame] | 274 | } |