blob: 2943703cfc23e14c2779e1a964155ea1238234de [file] [log] [blame]
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +00001/*
Richard S. Hall435c20c2006-09-28 20:11:35 +00002 * 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. Hallfe8e5602006-04-19 15:23:22 +00009 *
Richard S. Hall435c20c2006-09-28 20:11:35 +000010 * http://www.apache.org/licenses/LICENSE-2.0
Richard S. Hallfe8e5602006-04-19 15:23:22 +000011 *
Richard S. Hall435c20c2006-09-28 20:11:35 +000012 * 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. Hallfe8e5602006-04-19 15:23:22 +000018 */
19package org.apache.felix.http.jetty;
20
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +000021
Richard S. Hallfe8e5602006-04-19 15:23:22 +000022import java.security.AccessControlContext;
23import java.security.AccessController;
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +000024import java.util.Dictionary;
25import java.util.HashMap;
26import java.util.HashSet;
27import java.util.Map;
28import java.util.Set;
Richard S. Hallfe8e5602006-04-19 15:23:22 +000029
30import javax.servlet.Servlet;
31import javax.servlet.ServletException;
32
Felix Meschbergerc7ee0152008-03-26 09:24:35 +000033import org.mortbay.jetty.Server;
34import org.mortbay.jetty.servlet.Context;
35import org.mortbay.jetty.servlet.OsgiResourceHolder;
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +000036import org.mortbay.jetty.servlet.OsgiServletHandler;
Felix Meschbergerc7ee0152008-03-26 09:24:35 +000037import org.mortbay.jetty.servlet.SessionHandler;
Richard S. Hallfe8e5602006-04-19 15:23:22 +000038import org.osgi.framework.Bundle;
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +000039import org.osgi.service.http.HttpContext;
Richard S. Hallfe8e5602006-04-19 15:23:22 +000040import org.osgi.service.http.HttpService;
41import org.osgi.service.http.NamespaceException;
Felix Meschbergerc7ee0152008-03-26 09:24:35 +000042import org.osgi.service.log.LogService;
Richard S. Hallfe8e5602006-04-19 15:23:22 +000043
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +000044
Richard S. Hallfe8e5602006-04-19 15:23:22 +000045public class HttpServiceImpl implements HttpService
46{
47 /** global namesspace of all aliases that have been registered */
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +000048 private static Map m_aliasNamespace = null;
Richard S. Hallfe8e5602006-04-19 15:23:22 +000049
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 Meschbergerc7ee0152008-03-26 09:24:35 +000055 private Server m_server = null;
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +000056 private OsgiServletHandler m_serverServletHandler = null;
Richard S. Hallfe8e5602006-04-19 15:23:22 +000057
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +000058
Felix Meschbergerc7ee0152008-03-26 09:24:35 +000059 public HttpServiceImpl( Bundle bundle, Server server, OsgiServletHandler serverServletHandler )
Richard S. Hallfe8e5602006-04-19 15:23:22 +000060 {
61 m_bundle = bundle;
62 m_server = server;
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +000063 m_serverServletHandler = serverServletHandler;
Richard S. Hallfe8e5602006-04-19 15:23:22 +000064 m_localAliasSet = new HashSet();
65
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +000066 if ( m_aliasNamespace == null )
Richard S. Hallfe8e5602006-04-19 15:23:22 +000067 {
68 m_aliasNamespace = new HashMap();
69 }
Richard S. Hallfe8e5602006-04-19 15:23:22 +000070 }
71
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +000072
Richard S. Hallfe8e5602006-04-19 15:23:22 +000073 /**
74 * Initializes static variables.
75 **/
76 public static void initializeStatics()
77 {
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +000078 if ( m_aliasNamespace != null )
Richard S. Hallfe8e5602006-04-19 15:23:22 +000079 {
80 m_aliasNamespace.clear();
81 }
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +000082 ServletContextGroup.initializeStatics();
Richard S. Hallfe8e5602006-04-19 15:23:22 +000083 }
84
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +000085
86 public HttpContext createDefaultHttpContext()
Richard S. Hallfe8e5602006-04-19 15:23:22 +000087 {
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +000088 return new DefaultContextImpl( m_bundle );
Richard S. Hallfe8e5602006-04-19 15:23:22 +000089 }
90
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +000091
92 public void registerServlet( String alias, Servlet servlet, Dictionary params, HttpContext osgiHttpContext )
Richard S. Hallfe8e5602006-04-19 15:23:22 +000093 throws ServletException, NamespaceException
94 {
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +000095 Activator.debug( "http register servlet :" + m_bundle + ", alias: " + alias );
Richard S. Hallfe8e5602006-04-19 15:23:22 +000096
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +000097 if ( !aliasValid( alias ) )
Richard S. Hallfe8e5602006-04-19 15:23:22 +000098 {
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +000099 throw new IllegalArgumentException( "malformed alias" );
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000100 }
101
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +0000102 if ( ServletContextGroup.isServletRegistered( servlet ) )
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000103 {
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +0000104 throw new ServletException( "servlet already registered" );
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000105 }
106
107 // add alias with null details, and record servlet instance details
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +0000108 addAlias( alias, null );
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000109
110 //make sure alias is unique, and create
111 ServletContextGroup grp = null;
112
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +0000113 if ( osgiHttpContext == null )
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000114 {
115 osgiHttpContext = createDefaultHttpContext();
116 }
117
118 // servlets using same context must get same handler to ensure
119 // they share a common ServletContext
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +0000120 Activator.debug( "looking for context: " + osgiHttpContext );
121 grp = ServletContextGroup.getServletContextGroup( m_serverServletHandler, osgiHttpContext );
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000122
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +0000123 grp.addServlet( servlet, alias, params );
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000124
125 // update alias namespace with reference to group object for later
126 // unregistering
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +0000127 updateAlias( alias, grp );
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000128
129 // maybe should remove alias/servlet entries if exceptions?
130 }
131
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000132
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +0000133 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. Hallfe8e5602006-04-19 15:23:22 +0000138 {
Rob Walker48cb2432008-10-13 14:30:43 +0000139 throw new IllegalArgumentException( "malformed alias: " + alias);
140 }
141
142 if ( !nameValid( name ) )
143 {
144 throw new IllegalArgumentException( "malformed name: " + name);
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000145 }
146
147 // add alias with null details
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +0000148 addAlias( alias, null );
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000149
150 //make sure alias is unique, and create
Felix Meschbergerc7ee0152008-03-26 09:24:35 +0000151 Context hdlrContext = null;
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000152
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +0000153 if ( osgiHttpContext == null )
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000154 {
155 osgiHttpContext = createDefaultHttpContext();
156 }
157
Felix Meschbergerc7ee0152008-03-26 09:24:35 +0000158 // 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. Hallfe8e5602006-04-19 15:23:22 +0000162
Felix Meschbergerc7ee0152008-03-26 09:24:35 +0000163 grp.addResource( alias, name );
164
165 // update alias namespace with reference to group object for later
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000166 // unregistering
Felix Meschbergerc7ee0152008-03-26 09:24:35 +0000167 updateAlias( alias, grp );
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000168
Felix Meschbergerc7ee0152008-03-26 09:24:35 +0000169 // maybe should remove alias/servlet entries if exceptions?
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000170 }
171
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +0000172
173 public void unregister( String alias )
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000174 {
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +0000175 doUnregister( alias, true );
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000176 }
177
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +0000178
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000179 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 Meschbergerb76cfdb2007-09-28 14:13:22 +0000185 String[] all = ( String[] ) m_localAliasSet.toArray( new String[0] );
186 for ( int ix = 0; ix < all.length; ix++ )
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000187 {
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +0000188 doUnregister( all[ix], false );
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000189 }
190 }
191
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +0000192
193 protected void doUnregister( String alias, boolean forced )
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000194 {
Felix Meschbergerc7ee0152008-03-26 09:24:35 +0000195 Activator.debug( "** http unregister servlet :" + m_bundle + ", alias: " + alias + ",forced:" + forced );
196 ServletContextGroup grp = removeAlias( alias );
197 if ( grp != null )
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000198 {
Felix Meschbergerc7ee0152008-03-26 09:24:35 +0000199 grp.remove( alias, forced );
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000200 }
201 }
202
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +0000203
204 protected void addAlias( String alias, Object obj ) throws NamespaceException
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000205 {
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +0000206 synchronized ( m_aliasNamespace )
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000207 {
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +0000208 if ( m_aliasNamespace.containsKey( alias ) )
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000209 {
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +0000210 throw new NamespaceException( "alias already registered" );
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000211 }
212
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +0000213 m_aliasNamespace.put( alias, obj );
214 m_localAliasSet.add( alias );
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000215 }
216 }
217
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +0000218
Felix Meschbergerc7ee0152008-03-26 09:24:35 +0000219 protected ServletContextGroup removeAlias( String alias )
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000220 {
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +0000221 synchronized ( m_aliasNamespace )
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000222 {
223 // remove alias, don't worry if doesn't exist
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +0000224 Object obj = m_aliasNamespace.remove( alias );
225 m_localAliasSet.remove( alias );
Felix Meschbergerc7ee0152008-03-26 09:24:35 +0000226 return ( ServletContextGroup ) obj;
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000227 }
228 }
229
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +0000230
231 protected void updateAlias( String alias, Object obj )
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000232 {
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +0000233 synchronized ( m_aliasNamespace )
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000234 {
235 // only update if already present
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +0000236 if ( m_aliasNamespace.containsKey( alias ) )
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000237 {
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +0000238 m_aliasNamespace.put( alias, obj );
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000239 }
240 }
241 }
242
Felix Meschbergerb76cfdb2007-09-28 14:13:22 +0000243
244 protected boolean aliasValid( String alias )
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000245 {
Rob Walker48cb2432008-10-13 14:30:43 +0000246 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. Hallfe8e5602006-04-19 15:23:22 +0000268 {
269 return false;
270 }
271
272 return true;
273 }
Richard S. Hallfe8e5602006-04-19 15:23:22 +0000274}