FELIX-4060 : Implement HTTP Service Update (RFC-189)

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1656640 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/AbstractHandler.java b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/AbstractHandler.java
index d45f84b..ddb578b 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/AbstractHandler.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/AbstractHandler.java
@@ -16,9 +16,7 @@
  */
 package org.apache.felix.http.base.internal.handler;
 
-import java.util.HashMap;
 import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
 import java.util.regex.Pattern;
 
 import javax.servlet.Filter;
@@ -29,35 +27,17 @@
 
 public abstract class AbstractHandler<T extends AbstractHandler> implements Comparable<T>
 {
-    private final static AtomicInteger ID = new AtomicInteger();
-
-    private final int id;
     private final String baseName;
     private final ExtServletContext context;
     private final Map<String, String> initParams;
 
-    public AbstractHandler(ExtServletContext context, String baseName)
-    {
-        this.context = context;
-        this.baseName = baseName;
-        this.id = ID.incrementAndGet();
-        this.initParams = new HashMap<String, String>();
-    }
-
     public AbstractHandler(ExtServletContext context, final Map<String, String> initParams, String baseName)
     {
         this.context = context;
         this.baseName = baseName;
-        this.id = ID.incrementAndGet();
-        this.initParams = new HashMap<String, String>();
-        if ( initParams != null)
-        {
-            this.initParams.putAll(initParams);
-        }
+        this.initParams = initParams;
     }
 
-    public abstract void destroy();
-
     public final Map<String, String> getInitParams()
     {
         return this.initParams;
@@ -68,30 +48,26 @@
         String name = this.baseName;
         if (name == null)
         {
-            name = String.format("%s_%d", getSubject().getClass(), this.id);
+            name = String.format("%s_%d", getSubject().getClass(), this.hashCode());
         }
         return name;
     }
 
-    public abstract void init() throws ServletException;
-
     public ExtServletContext getContext()
     {
         return this.context;
     }
 
-    /**
-     * @return a unique ID for this handler, &gt; 0.
-     */
-    protected final int getId()
-    {
-        return id;
-    }
+    public abstract void init() throws ServletException;
+
+    public abstract void destroy();
 
     /**
      * @return the {@link Servlet} or {@link Filter} this handler handles.
      */
     protected abstract Object getSubject();
 
+    protected abstract long getServiceId();
+
     public abstract Pattern[] getPatterns();
 }
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java
index a6f73ef..0b94c06 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java
@@ -31,8 +31,8 @@
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.felix.http.base.internal.context.ExtServletContext;
-import org.apache.felix.http.base.internal.runtime.ServletContextHelperInfo;
 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.util.PatternUtil;
 
 public final class FilterHandler extends AbstractHandler<FilterHandler>
@@ -45,7 +45,7 @@
 
     public FilterHandler(final ServletContextHelperInfo contextInfo, ExtServletContext context, Filter filter, FilterInfo filterInfo)
     {
-        super(context, filterInfo.getInitParams(), filterInfo.getName());
+        super(context, filterInfo.getInitParameters(), filterInfo.getName());
         this.filter = filter;
         this.filterInfo = filterInfo;
         // Compose a single array of all patterns & regexs the filter must represent...
@@ -153,4 +153,10 @@
     {
         return this.contextServiceId;
     }
+
+    @Override
+    protected long getServiceId()
+    {
+        return this.filterInfo.getServiceId();
+    }
 }
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java
index 32da3ef..b3570d0 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java
@@ -54,23 +54,15 @@
 
     public PerContextHandlerRegistry getRegistry(final ServletContextHelperInfo info)
     {
+        final long key = (info == null ? 0 : info.getServiceId());
+
         synchronized ( this )
         {
             for(final PerContextHandlerRegistry r : this.registrations)
             {
-                if ( info == null )
+                if ( key == r.getContextServiceId())
                 {
-                    if ( r.getContextServiceid() == -1)
-                    {
-                        return r;
-                    }
-                }
-                else
-                {
-                    if ( info.getServiceId() == r.getContextServiceid())
-                    {
-                        return r;
-                    }
+                    return r;
                 }
             }
             final PerContextHandlerRegistry reg = new PerContextHandlerRegistry(info);
@@ -85,7 +77,7 @@
         final List<PerContextHandlerRegistry> regs = this.registrations;
         for(final PerContextHandlerRegistry r : regs)
         {
-            if ( serviceId != null && serviceId == r.getContextServiceid() )
+            if ( serviceId != null && serviceId == r.getContextServiceId() )
             {
                 return r.getErrorsMapping();
             }
@@ -108,7 +100,7 @@
         final List<PerContextHandlerRegistry> regs = this.registrations;
         for(final PerContextHandlerRegistry r : regs)
         {
-            if ( id == r.getContextServiceid() )
+            if ( id == r.getContextServiceId() )
             {
                 return r.getFilterHandlers(servletHandler, dispatcherType, requestURI);
             }
@@ -123,7 +115,7 @@
             final List<PerContextHandlerRegistry> regs = this.registrations;
             for(final PerContextHandlerRegistry r : regs)
             {
-                if ( contextId == r.getContextServiceid() )
+                if ( contextId == r.getContextServiceId() )
                 {
                     return r.getServletHandlerByName(name);
                 }
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/PerContextHandlerRegistry.java b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/PerContextHandlerRegistry.java
index 38391b6..09d9ecb 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/PerContextHandlerRegistry.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/PerContextHandlerRegistry.java
@@ -349,7 +349,7 @@
         return this.prefixPath;
     }
 
-    public long getContextServiceid()
+    public long getContextServiceId()
     {
         return this.serviceId;
     }
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java
index fec9663..4c0611e 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java
@@ -51,7 +51,7 @@
                           final ServletInfo servletInfo,
                           final Servlet servlet)
     {
-        super(context, servletInfo.getInitParams(), servletInfo.getName());
+        super(context, servletInfo.getInitParameters(), servletInfo.getName());
         this.servlet = servlet;
         this.servletInfo = servletInfo;
 
@@ -78,7 +78,7 @@
     @Override
     public int compareTo(final ServletHandler other)
     {
-        return getId() - other.getId();
+        return this.servletInfo.compareTo(other.servletInfo);
     }
 
     public String determineServletPath(String uri)
@@ -158,4 +158,10 @@
     {
         return this.contextServiceId;
     }
+
+    @Override
+    protected long getServiceId()
+    {
+        return this.servletInfo.getServiceId();
+    }
 }
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/AbstractInfo.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/AbstractInfo.java
index 7cbbc62..c7ed3ba 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/AbstractInfo.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/AbstractInfo.java
@@ -162,7 +162,7 @@
      */
     protected Map<String, String> getInitParams(final ServiceReference<T> ref, final String prefix)
     {
-        Map<String, String> result = null;
+        final Map<String, String> result = new HashMap<String, String>();
         for (final String key : ref.getPropertyKeys())
         {
             if ( key.startsWith(prefix))
@@ -172,10 +172,6 @@
 
                 if (paramValue != null)
                 {
-                    if ( result == null )
-                    {
-                        result = new HashMap<String, String>();
-                    }
                     result.put(paramKey, paramValue);
                 }
             }
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/FilterInfo.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/FilterInfo.java
index f8c7edf..8f11086 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/FilterInfo.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/FilterInfo.java
@@ -173,7 +173,7 @@
         return dispatcher;
     }
 
-    public Map<String, String> getInitParams()
+    public Map<String, String> getInitParameters()
     {
         return initParams;
     }
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletContextHelperInfo.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletContextHelperInfo.java
index b3ceb67..06694b7 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletContextHelperInfo.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletContextHelperInfo.java
@@ -46,7 +46,8 @@
      */
     private final Map<String, String> initParams;
 
-    public ServletContextHelperInfo(final ServiceReference<ServletContextHelper> ref) {
+    public ServletContextHelperInfo(final ServiceReference<ServletContextHelper> ref)
+    {
         super(ref);
         this.name = this.getStringProperty(ref, HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME);
         this.path = this.getStringProperty(ref, HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH);
@@ -97,7 +98,7 @@
         return this.prefix;
     }
 
-    public Map<String, String> getInitParams()
+    public Map<String, String> getInitParameters()
     {
         return initParams;
     }
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletInfo.java b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletInfo.java
index 057c05a..f2aab64 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletInfo.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/runtime/ServletInfo.java
@@ -18,6 +18,7 @@
  */
 package org.apache.felix.http.base.internal.runtime;
 
+import java.util.Collections;
 import java.util.Map;
 
 import javax.servlet.Servlet;
@@ -89,7 +90,7 @@
         this.patterns = resource.getPatterns();
         this.errorPage = null;
         this.asyncSupported = false;
-        this.initParams = null;
+        this.initParams = Collections.emptyMap();
     }
 
     private static ServiceReference getRef(final ServiceReference ref)
@@ -139,7 +140,7 @@
         return asyncSupported;
     }
 
-    public Map<String, String> getInitParams()
+    public Map<String, String> getInitParameters()
     {
         return initParams;
     }
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ContextHandler.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ContextHandler.java
index 16a6254..fed1f4b 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ContextHandler.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ContextHandler.java
@@ -69,7 +69,7 @@
         this.sharedContext = new SharedServletContextImpl(webContext,
                 info.getName(),
                 info.getPrefix(),
-                info.getInitParams(),
+                info.getInitParameters(),
                 new ServletContextAttributeListener() {
 
                     @Override
diff --git a/http/base/src/test/java/org/apache/felix/http/base/internal/handler/AbstractHandlerTest.java b/http/base/src/test/java/org/apache/felix/http/base/internal/handler/AbstractHandlerTest.java
index e2fc82c..a820be3 100644
--- a/http/base/src/test/java/org/apache/felix/http/base/internal/handler/AbstractHandlerTest.java
+++ b/http/base/src/test/java/org/apache/felix/http/base/internal/handler/AbstractHandlerTest.java
@@ -43,9 +43,9 @@
         AbstractHandler h1 = createHandler();
         AbstractHandler h2 = createHandler();
 
-        Assert.assertTrue(h1.getId() > 0);
-        Assert.assertTrue(h2.getId() > 0);
-        Assert.assertFalse(h1.getId() == h2.getId());
+        Assert.assertTrue(h1.getServiceId() < 0);
+        Assert.assertTrue(h2.getServiceId() < 0);
+        Assert.assertFalse(h1.getServiceId() == h2.getServiceId());
     }
 
     @Test
diff --git a/http/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterHandlerTest.java b/http/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterHandlerTest.java
index 789f986..624d2d3 100644
--- a/http/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterHandlerTest.java
+++ b/http/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterHandlerTest.java
@@ -26,6 +26,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import java.util.Collections;
 import java.util.Map;
 
 import javax.servlet.DispatcherType;
@@ -240,8 +241,12 @@
         return createHandler(pattern, ranking, null);
     }
 
-    private FilterHandler createHandler(String pattern, int ranking, final Map<String, String> initParams)
+    private FilterHandler createHandler(String pattern, int ranking, Map<String, String> initParams)
     {
+        if ( initParams == null )
+        {
+            initParams = Collections.emptyMap();
+        }
         final FilterInfo info = new FilterInfo(null, pattern, ranking, initParams);
         return new FilterHandler(null, this.context, this.filter, info);
     }
diff --git a/http/base/src/test/java/org/apache/felix/http/base/internal/handler/ServletHandlerTest.java b/http/base/src/test/java/org/apache/felix/http/base/internal/handler/ServletHandlerTest.java
index 86f7760..d8a94aa 100644
--- a/http/base/src/test/java/org/apache/felix/http/base/internal/handler/ServletHandlerTest.java
+++ b/http/base/src/test/java/org/apache/felix/http/base/internal/handler/ServletHandlerTest.java
@@ -27,6 +27,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import java.util.Collections;
 import java.util.Map;
 
 import javax.servlet.Servlet;
@@ -219,6 +220,10 @@
 
     private ServletHandler createHandler(String alias, Map<String, String> map)
     {
+        if ( map == null )
+        {
+            map = Collections.emptyMap();
+        }
         final ServletInfo info = new ServletInfo(null, alias, 0, map);
         return new ServletHandler(null, this.context, info, this.servlet);
     }