FELIX-4060 : Implement HTTP Service Update (RFC-189) - remove intermediate listener registry

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1670917 13f79535-47bb-0310-9956-ffa450edef68
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 16dd573..2555312 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
@@ -47,11 +47,10 @@
 
     public ContextHandler(final ServletContextHelperInfo info,
             final ServletContext webContext,
-            final PerContextEventListener eventListener,
             final Bundle bundle)
     {
         this.info = info;
-        this.eventListener = eventListener;
+        this.eventListener = new PerContextEventListener(bundle, this);
         this.bundle = bundle;
         this.sharedContext = new SharedServletContextImpl(webContext,
                 info.getName(),
@@ -147,4 +146,8 @@
         public ExtServletContext servletContext;
         public ServletContextHelper servletContextHelper;
     }
+
+    public PerContextEventListener getListenerRegistry() {
+        return this.eventListener;
+    }
 }
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ListenerRegistry.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ListenerRegistry.java
deleted file mode 100644
index d7411dd..0000000
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ListenerRegistry.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.felix.http.base.internal.whiteboard;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.TreeMap;
-
-import javax.annotation.Nonnull;
-
-import org.apache.felix.http.base.internal.runtime.HttpSessionAttributeListenerInfo;
-import org.apache.felix.http.base.internal.runtime.HttpSessionIdListenerInfo;
-import org.apache.felix.http.base.internal.runtime.HttpSessionListenerInfo;
-import org.apache.felix.http.base.internal.runtime.ServletContextAttributeListenerInfo;
-import org.apache.felix.http.base.internal.runtime.ServletContextHelperInfo;
-import org.apache.felix.http.base.internal.runtime.ServletContextListenerInfo;
-import org.apache.felix.http.base.internal.runtime.ServletRequestAttributeListenerInfo;
-import org.apache.felix.http.base.internal.runtime.ServletRequestListenerInfo;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.ServiceReference;
-
-public final class ListenerRegistry
-{
-    private final Map<ServletContextHelperInfo, PerContextEventListener> registriesByContext = new TreeMap<ServletContextHelperInfo, PerContextEventListener>();
-
-    private final Bundle bundle;
-
-    public ListenerRegistry(final Bundle bundle)
-    {
-        this.bundle = bundle;
-    }
-
-    public PerContextEventListener addContext(ServletContextHelperInfo info)
-    {
-        if (registriesByContext.containsKey(info))
-        {
-            throw new IllegalArgumentException("Context with id " + info.getServiceId() + "is already registered");
-        }
-
-        PerContextEventListener contextRegistry = new PerContextEventListener(bundle);
-        registriesByContext.put(info, contextRegistry);
-        return contextRegistry;
-    }
-
-    public void removeContext(ServletContextHelperInfo info)
-    {
-        registriesByContext.remove(info);
-    }
-
-    public void initialized(@Nonnull final ServletContextListenerInfo listenerInfo,
-            ContextHandler contextHandler)
-    {
-        registriesByContext.get(contextHandler.getContextInfo()).initialized(listenerInfo, contextHandler);
-    }
-
-    public void destroyed(@Nonnull final ServletContextListenerInfo listenerInfo,
-            ContextHandler contextHandler)
-    {
-        registriesByContext.get(contextHandler.getContextInfo()).destroyed(listenerInfo, contextHandler);
-    }
-
-    void addListener(@Nonnull final ServletContextAttributeListenerInfo info,
-            final ContextHandler contextHandler)
-    {
-        getRegistryForContext(contextHandler).addListener(info);
-    }
-
-    void removeListener(@Nonnull final ServletContextAttributeListenerInfo info,
-            final ContextHandler contextHandler)
-    {
-        getRegistryForContext(contextHandler).removeListener(info);
-    }
-
-    void addListener(@Nonnull final HttpSessionAttributeListenerInfo info,
-            final ContextHandler contextHandler)
-    {
-        getRegistryForContext(contextHandler).addListener(info);
-    }
-
-    void removeListener(@Nonnull final HttpSessionAttributeListenerInfo info,
-            final ContextHandler contextHandler)
-    {
-        getRegistryForContext(contextHandler).removeListener(info);
-    }
-
-    void addListener(@Nonnull final HttpSessionIdListenerInfo info,
-            final ContextHandler contextHandler)
-    {
-        getRegistryForContext(contextHandler).addListener(info);
-    }
-
-    void removeListener(@Nonnull final HttpSessionIdListenerInfo info,
-            final ContextHandler contextHandler)
-    {
-        getRegistryForContext(contextHandler).removeListener(info);
-    }
-
-    void addListener(@Nonnull final HttpSessionListenerInfo info,
-            final ContextHandler contextHandler)
-    {
-        getRegistryForContext(contextHandler).addListener(info);
-    }
-
-    void removeListener(@Nonnull final HttpSessionListenerInfo info,
-            final ContextHandler contextHandler)
-    {
-        getRegistryForContext(contextHandler).removeListener(info);
-    }
-
-    void addListener(@Nonnull final ServletRequestListenerInfo info,
-            final ContextHandler contextHandler)
-    {
-        getRegistryForContext(contextHandler).addListener(info);
-    }
-
-    void removeListener(@Nonnull final ServletRequestListenerInfo info,
-            final ContextHandler contextHandler)
-    {
-        getRegistryForContext(contextHandler).removeListener(info);
-    }
-
-    void addListener(@Nonnull final ServletRequestAttributeListenerInfo info,
-            final ContextHandler contextHandler)
-    {
-        getRegistryForContext(contextHandler).addListener(info);
-    }
-
-    void removeListener(@Nonnull final ServletRequestAttributeListenerInfo info,
-            final ContextHandler contextHandler)
-    {
-        getRegistryForContext(contextHandler).removeListener(info);
-    }
-
-    private PerContextEventListener getRegistryForContext(ContextHandler contextHandler)
-    {
-        PerContextEventListener contextRegistry = registriesByContext.get(contextHandler.getContextInfo());
-        if (contextRegistry == null)
-        {
-            throw new IllegalArgumentException("ContextHandler " + contextHandler.getContextInfo().getName() + " is not registered");
-        }
-        return contextRegistry;
-    }
-
-    public Map<Long, Collection<ServiceReference<?>>> getContextRuntimes()
-    {
-        Map<Long, Collection<ServiceReference<?>>> listenersByContext = new HashMap<Long, Collection<ServiceReference<?>>>();
-        for (ServletContextHelperInfo contextInfo : registriesByContext.keySet())
-        {
-            long serviceId = contextInfo.getServiceId();
-            listenersByContext.put(serviceId, registriesByContext.get(contextInfo).getRuntime());
-        }
-        return listenersByContext;
-    }
-}
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/PerContextEventListener.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/PerContextEventListener.java
index 30dcdc1..2b8fdba 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/PerContextEventListener.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/PerContextEventListener.java
@@ -78,13 +78,15 @@
 
     private final Bundle bundle;
 
-    PerContextEventListener(final Bundle bundle)
+    private final ContextHandler contextHandler;
+
+    PerContextEventListener(final Bundle bundle, final ContextHandler contextHandler)
     {
         this.bundle = bundle;
+        this.contextHandler = contextHandler;
     }
 
-    void initialized(@Nonnull final ServletContextListenerInfo listenerInfo,
-            @Nonnull ContextHandler contextHandler)
+    void initialized(@Nonnull final ServletContextListenerInfo listenerInfo)
     {
         final ServletContextListener listener = listenerInfo.getService(bundle);
         if (listener != null)
@@ -99,8 +101,7 @@
         }
     }
 
-    void destroyed(@Nonnull final ServletContextListenerInfo listenerInfo,
-            @Nonnull ContextHandler contextHandler)
+    void destroyed(@Nonnull final ServletContextListenerInfo listenerInfo)
     {
         final ServiceReference<ServletContextListener> listenerRef = listenerInfo
                 .getServiceReference();
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardManager.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardManager.java
index 82020a5..025f0b8 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardManager.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardManager.java
@@ -104,8 +104,6 @@
 
     private final WhiteboardHttpService httpService;
 
-    private final ListenerRegistry listenerRegistry;
-
     private final Map<AbstractInfo<?>, Integer> serviceFailures = new ConcurrentSkipListMap<AbstractInfo<?>, Integer>();
 
     private volatile ServletContext webContext;
@@ -131,7 +129,6 @@
         this.bundleContext = bundleContext;
         this.httpServiceFactory = httpServiceFactory;
         this.httpService = new WhiteboardHttpService(this.bundleContext, registry);
-        this.listenerRegistry = new ListenerRegistry(bundleContext.getBundle());
         this.serviceRuntime = new HttpServiceRuntimeImpl(registry, this);
     }
 
@@ -288,7 +285,7 @@
         // context listeners first
         for(final ServletContextListenerInfo info : listeners.values())
         {
-            this.listenerRegistry.initialized(info, handler);
+            handler.getListenerRegistry().initialized(info);
         }
         // now register services
         for(final WhiteboardServiceInfo<?> info : services)
@@ -324,7 +321,7 @@
         }
         for(final ServletContextListenerInfo info : listeners.values())
         {
-            this.listenerRegistry.destroyed(info, handler);
+            handler.getListenerRegistry().destroyed(info);
         }
         handler.deactivate();
 
@@ -343,10 +340,8 @@
             {
                 synchronized ( this.contextMap )
                 {
-                    PerContextEventListener contextEventListener = listenerRegistry.addContext(info);
-                    ContextHandler handler = new ContextHandler(info,
+                    final ContextHandler handler = new ContextHandler(info,
                             this.webContext,
-                            contextEventListener,
                             this.bundleContext.getBundle());
 
                     List<ContextHandler> handlerList = this.contextMap.get(info.getName());
@@ -429,7 +424,6 @@
                             this.activate(newHead);
                             removeFailure(newHead.getContextInfo(), FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE);
                         }
-                        listenerRegistry.removeContext(info);
                     }
                 }
             }
@@ -540,27 +534,27 @@
 
             else if ( info instanceof ServletContextAttributeListenerInfo )
             {
-                this.listenerRegistry.addListener((ServletContextAttributeListenerInfo) info, handler);
+                handler.getListenerRegistry().addListener((ServletContextAttributeListenerInfo) info);
             }
             else if ( info instanceof HttpSessionListenerInfo )
             {
-                this.listenerRegistry.addListener((HttpSessionListenerInfo) info, handler);
+                handler.getListenerRegistry().addListener((HttpSessionListenerInfo) info);
             }
             else if ( info instanceof HttpSessionAttributeListenerInfo )
             {
-                this.listenerRegistry.addListener((HttpSessionAttributeListenerInfo) info, handler);
+                handler.getListenerRegistry().addListener((HttpSessionAttributeListenerInfo) info);
             }
             else if ( info instanceof HttpSessionIdListenerInfo )
             {
-                this.listenerRegistry.addListener((HttpSessionIdListenerInfo) info, handler);
+                handler.getListenerRegistry().addListener((HttpSessionIdListenerInfo) info);
             }
             else if ( info instanceof ServletRequestListenerInfo )
             {
-                this.listenerRegistry.addListener((ServletRequestListenerInfo) info, handler);
+                handler.getListenerRegistry().addListener((ServletRequestListenerInfo) info);
             }
             else if ( info instanceof ServletRequestAttributeListenerInfo )
             {
-                this.listenerRegistry.addListener((ServletRequestAttributeListenerInfo) info, handler);
+                handler.getListenerRegistry().addListener((ServletRequestAttributeListenerInfo) info);
             }
         }
         catch (final RegistrationFailureException e)
@@ -599,27 +593,27 @@
 
             else if ( info instanceof ServletContextAttributeListenerInfo )
             {
-                this.listenerRegistry.removeListener((ServletContextAttributeListenerInfo) info, handler);
+                handler.getListenerRegistry().removeListener((ServletContextAttributeListenerInfo) info);
             }
             else if ( info instanceof HttpSessionListenerInfo )
             {
-                this.listenerRegistry.removeListener((HttpSessionListenerInfo) info, handler);
+                handler.getListenerRegistry().removeListener((HttpSessionListenerInfo) info);
             }
             else if ( info instanceof HttpSessionAttributeListenerInfo )
             {
-                this.listenerRegistry.removeListener((HttpSessionAttributeListenerInfo) info, handler);
+                handler.getListenerRegistry().removeListener((HttpSessionAttributeListenerInfo) info);
             }
             else if ( info instanceof HttpSessionIdListenerInfo )
             {
-                this.listenerRegistry.removeListener((HttpSessionIdListenerInfo) info, handler);
+                handler.getListenerRegistry().removeListener((HttpSessionIdListenerInfo) info);
             }
             else if ( info instanceof ServletRequestListenerInfo )
             {
-                this.listenerRegistry.removeListener((ServletRequestListenerInfo) info, handler);
+                handler.getListenerRegistry().removeListener((ServletRequestListenerInfo) info);
             }
             else if ( info instanceof ServletRequestAttributeListenerInfo )
             {
-                this.listenerRegistry.removeListener((ServletRequestAttributeListenerInfo) info, handler);
+                handler.getListenerRegistry().removeListener((ServletRequestAttributeListenerInfo) info);
             }
         }
         catch (final RegistrationFailureException e)
@@ -697,7 +691,7 @@
     {
         Collection<ServletContextHelperRuntime> contextRuntimes = new TreeSet<ServletContextHelperRuntime>(ServletContextHelperRuntime.COMPARATOR);
         List<ContextRuntime> handlerRuntimes;
-        Map<Long, Collection<ServiceReference<?>>> listenerRuntimes;
+        final Map<Long, Collection<ServiceReference<?>>> listenerRuntimes = new HashMap<Long, Collection<ServiceReference<?>>>();
         FailureRuntime.Builder failureRuntime = FailureRuntime.builder();
         synchronized ( this.contextMap )
         {
@@ -705,11 +699,14 @@
             {
                 if ( !contextHandlerList.isEmpty() )
                 {
-                    contextRuntimes.add(contextHandlerList.get(0));
+                    final ContextHandler handler = contextHandlerList.get(0);
+                    contextRuntimes.add(handler);
+
+                    final long serviceId = handler.getContextInfo().getServiceId();
+                    listenerRuntimes.put(serviceId, handler.getListenerRegistry().getRuntime());
                 }
             }
             handlerRuntimes = registry.getRuntime(failureRuntime);
-            listenerRuntimes = listenerRegistry.getContextRuntimes();
             failureRuntime.add(serviceFailures);
         }
         return new RegistryRuntime(contextRuntimes, handlerRuntimes, listenerRuntimes, failureRuntime.build());
diff --git a/http/base/src/test/java/org/apache/felix/http/base/internal/runtime/dto/RuntimeDTOBuilderTest.java b/http/base/src/test/java/org/apache/felix/http/base/internal/runtime/dto/RuntimeDTOBuilderTest.java
index 4d1a59d..a107415 100644
--- a/http/base/src/test/java/org/apache/felix/http/base/internal/runtime/dto/RuntimeDTOBuilderTest.java
+++ b/http/base/src/test/java/org/apache/felix/http/base/internal/runtime/dto/RuntimeDTOBuilderTest.java
@@ -63,7 +63,6 @@
 import org.apache.felix.http.base.internal.runtime.ServletContextHelperInfo;
 import org.apache.felix.http.base.internal.runtime.ServletInfo;
 import org.apache.felix.http.base.internal.whiteboard.ContextHandler;
-import org.apache.felix.http.base.internal.whiteboard.ListenerRegistry;
 import org.apache.felix.http.base.internal.whiteboard.PerContextEventListener;
 import org.junit.Before;
 import org.junit.Rule;
@@ -138,14 +137,12 @@
 
     private RegistryRuntime registry;
     private Map<String, Object> runtimeAttributes;
-	private ListenerRegistry listenerRegistry;
 
     @Before
     public void setUp()
     {
         registry = null;
         runtimeAttributes = RUNTIME_ATTRIBUTES;
-        listenerRegistry = new ListenerRegistry(bundle);
     }
 
     public ServletContextHelperRuntime setupContext(ServletContext context, String name, long serviceId)
@@ -163,8 +160,8 @@
         Map<String, String> initParameters = createInitParameterMap();
         ServletContextHelperInfo contextInfo = createContextInfo(0, serviceId, name, path, initParameters);
 
-        PerContextEventListener eventListener = listenerRegistry.addContext(contextInfo);
-        ServletContextHelperRuntime contextHandler = new ContextHandler(contextInfo, context, eventListener, bundle);
+        ContextHandler contextHandler = new ContextHandler(contextInfo, context, bundle);
+        PerContextEventListener eventListener = contextHandler.getListenerRegistry();
 
         ServletContext sharedContext = contextHandler.getSharedContext();
         sharedContext.setAttribute("intAttr", 1);