You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cz...@apache.org on 2015/02/03 11:11:25 UTC

svn commit: r1656662 - in /felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal: handler/PerContextHandlerRegistry.java runtime/ServletInfo.java service/HttpServiceImpl.java whiteboard/WhiteboardHttpService.java

Author: cziegeler
Date: Tue Feb  3 10:11:25 2015
New Revision: 1656662

URL: http://svn.apache.org/r1656662
Log:
FELIX-4060 : Implement HTTP Service Update (RFC-189) - fix broken HttpService implementation

Modified:
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/PerContextHandlerRegistry.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletInfo.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardHttpService.java

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/PerContextHandlerRegistry.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/PerContextHandlerRegistry.java?rev=1656662&r1=1656661&r2=1656662&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/PerContextHandlerRegistry.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/PerContextHandlerRegistry.java Tue Feb  3 10:11:25 2015
@@ -31,7 +31,6 @@ import javax.servlet.ServletException;
 import org.apache.felix.http.base.internal.runtime.FilterInfo;
 import org.apache.felix.http.base.internal.runtime.ServletContextHelperInfo;
 import org.apache.felix.http.base.internal.runtime.ServletInfo;
-import org.osgi.service.http.NamespaceException;
 
 public final class PerContextHandlerRegistry implements Comparable<PerContextHandlerRegistry>
 {
@@ -109,14 +108,8 @@ public final class PerContextHandlerRegi
     /**
      * Add a new servlet.
      */
-    public synchronized void addServlet(ServletContextHelperInfo contextInfo, ServletHandler handler) throws ServletException, NamespaceException
+    public synchronized void addServlet(final ServletHandler handler) throws ServletException
     {
-        if (this.servletMap.containsKey(handler.getServlet()))
-        {
-            // Do not destroy the servlet as the same instance was already registered
-            throw new ServletException("Servlet instance " + handler.getName() + " already registered");
-        }
-
         // Can be null in case of error-handling servlets...
         String[] patterns = handler.getServletInfo().getPatterns();
         int length = patterns == null ? 0 : patterns.length;
@@ -189,11 +182,6 @@ public final class PerContextHandlerRegi
         return result.toArray(new FilterHandler[result.size()]);
     }
 
-    public synchronized Servlet getServletByAlias(String alias)
-    {
-        return this.servletPatternMap.get(alias);
-    }
-
     public ServletHandler getServletHandlerByName(String name)
     {
         return this.servletMapping.getByName(name);
@@ -260,7 +248,7 @@ public final class PerContextHandlerRegi
         return null;
     }
 
-    public synchronized Servlet removeServlet(final ServletContextHelperInfo contextInfo, ServletInfo servletInfo, final boolean destroy)
+    public synchronized Servlet removeServlet(ServletInfo servletInfo, final boolean destroy)
     {
         for(final ServletHandler handler : this.servletMap.values())
         {

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletInfo.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletInfo.java?rev=1656662&r1=1656661&r2=1656662&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletInfo.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletInfo.java Tue Feb  3 10:11:25 2015
@@ -108,7 +108,7 @@ public final class ServletInfo extends W
     {
         super(serviceRanking);
         this.name = name;
-        this.patterns = new String[] {pattern};
+        this.patterns = new String[] {pattern, pattern + "/*"};
         this.initParams = initParams;
         this.asyncSupported = false;
         this.errorPage = null;

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java?rev=1656662&r1=1656661&r2=1656662&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java Tue Feb  3 10:11:25 2015
@@ -20,7 +20,9 @@ import java.util.Dictionary;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.Map;
+import java.util.Set;
 
 import javax.servlet.Filter;
 import javax.servlet.Servlet;
@@ -45,16 +47,16 @@ public final class HttpServiceImpl imple
 {
     private final Bundle bundle;
     private final PerContextHandlerRegistry handlerRegistry;
-    private final HashSet<Servlet> localServlets;
-    private final HashSet<Filter> localFilters;
+    private final Set<Servlet> localServlets = new HashSet<Servlet>();
+    private final Set<Filter> localFilters = new HashSet<Filter>();
     private final ServletContextManager contextManager;
 
+    private final Map<String, ServletHandler> aliasMap = new HashMap<String, ServletHandler>();
+    
     public HttpServiceImpl(Bundle bundle, ServletContext context, PerContextHandlerRegistry handlerRegistry, ServletContextAttributeListener servletAttributeListener, boolean sharedContextAttributes)
     {
         this.bundle = bundle;
         this.handlerRegistry = handlerRegistry;
-        this.localServlets = new HashSet<Servlet>();
-        this.localFilters = new HashSet<Filter>();
         this.contextManager = new ServletContextManager(this.bundle, context, servletAttributeListener, sharedContextAttributes);
     }
 
@@ -108,14 +110,19 @@ public final class HttpServiceImpl imple
         this.localFilters.add(filter);
     }
 
+    /**
+     * No need to sync this method, syncing is done via {@link #registerServlet(String, Servlet, Dictionary, HttpContext)}
+     * @see org.osgi.service.http.HttpService#registerResources(java.lang.String, java.lang.String, org.osgi.service.http.HttpContext)
+     */
     @Override
-    public void registerResources(String alias, String name, HttpContext context) throws NamespaceException
+    public void registerResources(final String alias, final String name, final HttpContext context) throws NamespaceException
     {
         if (!isNameValid(name))
         {
             throw new IllegalArgumentException("Malformed resource name [" + name + "]");
         }
 
+        // TODO - check validity of alias
         try
         {
             Servlet servlet = new ResourceServlet(name);
@@ -160,56 +167,62 @@ public final class HttpServiceImpl imple
         }
 
         final ServletInfo servletInfo = new ServletInfo(null, alias, 0, paramMap);
-
         final ExtServletContext httpContext = getServletContext(context);
 
         final ServletHandler handler = new ServletHandler(null,
                 httpContext,
                 servletInfo,
                 servlet);
-        try {
-            this.handlerRegistry.addServlet(null, handler);
-        } catch (ServletException e) {
-            // TODO create failure DTO
-        } catch (NamespaceException e) {
-            // TODO create failure DTO
-        }
 
-        this.localServlets.add(servlet);
+        synchronized ( this.aliasMap ) 
+        {
+        	if ( this.aliasMap.containsKey(alias) ) 
+        	{
+        	    throw new NamespaceException("Alias " + alias + " is already in use.");	
+        	}
+        	if ( this.localServlets.contains(servlet) )
+        	{
+                throw new ServletException("Servlet instance " + handler.getName() + " already registered");        		
+        	}
+            
+            this.handlerRegistry.addServlet(handler);
+
+            this.aliasMap.put(alias, handler);
+            this.localServlets.add(servlet);
+        }
     }
 
     /**
      * @see org.osgi.service.http.HttpService#unregister(java.lang.String)
      */
     @Override
-    public void unregister(String alias)
+    public void unregister(final String alias)
     {
-        final Servlet servlet = this.handlerRegistry.getServletByAlias(alias);
-        if (servlet == null)
+        synchronized ( this.aliasMap ) 
         {
-            // FELIX-4561 - don't bother throwing an exception if we're stopping anyway...
-            if ((bundle.getState() & Bundle.STOPPING) != 0)
-            {
-                throw new IllegalArgumentException("Nothing registered at " + alias);
-            }
-            else
-            {
-                SystemLogger.debug("Nothing registered at " + alias + "; ignoring this because the bundle is stopping!", null);
-            }
-        }
-        unregisterServlet(servlet);
+		    final ServletHandler handler = this.aliasMap.remove(alias);	
+	        if ( handler == null )
+	        {
+	        	throw new IllegalArgumentException("Nothing registered at " + alias);        	
+	        }
+	        final Servlet servlet = this.handlerRegistry.removeServlet(handler.getServletInfo(), true);
+	        if (servlet != null)
+	        {
+	        	this.localServlets.remove(servlet);
+	        }
+		}
     }
 
     public void unregisterAll()
     {
-        HashSet<Servlet> servlets = new HashSet<Servlet>(this.localServlets);
-        for (Servlet servlet : servlets)
+        final Set<Servlet> servlets = new HashSet<Servlet>(this.localServlets);
+        for (final Servlet servlet : servlets)
         {
             unregisterServlet(servlet, false);
         }
 
-        HashSet<Filter> filters = new HashSet<Filter>(this.localFilters);
-        for (Filter fiter : filters)
+        final Set<Filter> filters = new HashSet<Filter>(this.localFilters);
+        for (final Filter fiter : filters)
         {
             unregisterFilter(fiter, false);
         }
@@ -240,7 +253,21 @@ public final class HttpServiceImpl imple
         if ( servlet != null )
         {
             this.handlerRegistry.removeServlet(servlet, destroy);
-            this.localServlets.remove(servlet);
+            synchronized ( this.aliasMap )
+            {
+            	final Iterator<Map.Entry<String, ServletHandler>> i = this.aliasMap.entrySet().iterator();
+            	while ( i.hasNext() )
+            	{
+            		final Map.Entry<String, ServletHandler> entry = i.next();
+            		if ( entry.getValue().getServlet() == servlet )
+            		{
+            			i.remove();
+            			break;
+            		}
+            		
+            	}
+            	this.localServlets.remove(servlet);
+            }
         }
     }
 

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardHttpService.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardHttpService.java?rev=1656662&r1=1656661&r2=1656662&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardHttpService.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardHttpService.java Tue Feb  3 10:11:25 2015
@@ -36,7 +36,7 @@ import org.apache.felix.http.base.intern
 import org.apache.felix.http.base.internal.whiteboard.tracker.ServletContextListenerTracker;
 import org.apache.felix.http.base.internal.whiteboard.tracker.ServletTracker;
 import org.osgi.framework.BundleContext;
-import org.osgi.service.http.NamespaceException;
+import org.osgi.framework.ServiceObjects;
 import org.osgi.util.tracker.ServiceTracker;
 
 public final class WhiteboardHttpService
@@ -94,20 +94,23 @@ public final class WhiteboardHttpService
     public void registerServlet(@Nonnull final ContextHandler contextHandler,
             @Nonnull final ServletInfo servletInfo)
     {
-        final Servlet servlet = this.bundleContext.getServiceObjects(servletInfo.getServiceReference()).getService();
-        // TODO create failure DTO if null
-        if ( servlet != null )
+        final ServiceObjects<Servlet> so = this.bundleContext.getServiceObjects(servletInfo.getServiceReference());
+        if ( so != null )
         {
-            final ServletHandler handler = new ServletHandler(contextHandler.getContextInfo(),
-                    contextHandler.getServletContext(servletInfo.getServiceReference().getBundle()),
-                    servletInfo,
-                    servlet);
-            try {
-                this.handlerRegistry.getRegistry(contextHandler.getContextInfo()).addServlet(contextHandler.getContextInfo(), handler);
-            } catch (ServletException e) {
-                // TODO create failure DTO
-            } catch (NamespaceException e) {
-                // TODO create failure DTO
+            final Servlet servlet = so.getService();
+            // TODO create failure DTO if null
+            if ( servlet != null )
+            {
+                final ServletHandler handler = new ServletHandler(contextHandler.getContextInfo(),
+                        contextHandler.getServletContext(servletInfo.getServiceReference().getBundle()),
+                        servletInfo,
+                        servlet);
+                try {
+                    this.handlerRegistry.getRegistry(contextHandler.getContextInfo()).addServlet(handler);
+                } catch (final ServletException e) {
+                    so.ungetService(servlet);
+                    // TODO create failure DTO
+                }
             }
         }
     }
@@ -119,7 +122,7 @@ public final class WhiteboardHttpService
      */
     public void unregisterServlet(@Nonnull final ContextHandler contextHandler, @Nonnull final ServletInfo servletInfo)
     {
-        final Servlet instance = this.handlerRegistry.getRegistry(contextHandler.getContextInfo()).removeServlet(contextHandler.getContextInfo(), servletInfo, true);
+        final Servlet instance = this.handlerRegistry.getRegistry(contextHandler.getContextInfo()).removeServlet(servletInfo, true);
         if ( instance != null )
         {
             this.bundleContext.getServiceObjects(servletInfo.getServiceReference()).ungetService(instance);
@@ -182,11 +185,9 @@ public final class WhiteboardHttpService
                 servletInfo,
                 servlet);
         try {
-            this.handlerRegistry.getRegistry(contextHandler.getContextInfo()).addServlet(contextHandler.getContextInfo(), handler);
+            this.handlerRegistry.getRegistry(contextHandler.getContextInfo()).addServlet(handler);
         } catch (ServletException e) {
             // TODO create failure DTO
-        } catch (NamespaceException e) {
-            // TODO create failure DTO
         }
     }