FELIX-4060 : Implement HTTP Service Update (RFC-189) - Refactor http service related classes in according packages

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1659781 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/HttpServiceController.java b/http/base/src/main/java/org/apache/felix/http/base/internal/HttpServiceController.java
index 9141b48..fe0a0e1 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/HttpServiceController.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/HttpServiceController.java
@@ -23,66 +23,30 @@
 import javax.servlet.http.HttpSessionEvent;
 import javax.servlet.http.HttpSessionListener;
 
-import org.apache.felix.http.api.ExtHttpService;
 import org.apache.felix.http.base.internal.dispatch.Dispatcher;
 import org.apache.felix.http.base.internal.handler.HandlerRegistry;
 import org.apache.felix.http.base.internal.handler.HttpServicePlugin;
 import org.apache.felix.http.base.internal.handler.HttpSessionWrapper;
 import org.apache.felix.http.base.internal.runtime.HttpServiceRuntimeImpl;
 import org.apache.felix.http.base.internal.service.HttpServiceFactory;
-import org.apache.felix.http.base.internal.service.listener.HttpSessionAttributeListenerManager;
-import org.apache.felix.http.base.internal.service.listener.HttpSessionListenerManager;
 import org.apache.felix.http.base.internal.service.listener.ServletContextAttributeListenerManager;
 import org.apache.felix.http.base.internal.service.listener.ServletRequestAttributeListenerManager;
 import org.apache.felix.http.base.internal.service.listener.ServletRequestListenerManager;
 import org.apache.felix.http.base.internal.whiteboard.WhiteboardHttpService;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.http.HttpService;
 import org.osgi.service.http.runtime.HttpServiceRuntime;
 import org.osgi.service.http.runtime.HttpServiceRuntimeConstants;
 
 public final class HttpServiceController
 {
-    /**
-     * Name of the Framework property indicating whether the servlet context
-     * attributes of the ServletContext objects created for each HttpContext
-     * used to register servlets and resources share their attributes or not.
-     * By default (if this property is not specified or it's value is not
-     * <code>true</code> (case-insensitive)) servlet context attributes are not
-     * shared. To have servlet context attributes shared amongst servlet context
-     * and also with the ServletContext provided by the servlet container ensure
-     * setting the property as follows:
-     * <pre>
-     * org.apache.felix.http.shared_servlet_context_attributes = true
-     * </pre>
-     * <p>
-     * <b>WARNING:</b> Only set this property if absolutely needed (for example
-     * you implement an HttpSessionListener and want to access servlet context
-     * attributes of the ServletContext to which the HttpSession is linked).
-     * Otherwise leave this property unset.
-     */
-    private static final String FELIX_HTTP_SHARED_SERVLET_CONTEXT_ATTRIBUTES = "org.apache.felix.http.shared_servlet_context_attributes";
-
-    /** Compat property for previous versions. */
-    private static final String OBSOLETE_REG_PROPERTY_ENDPOINTS = "osgi.http.service.endpoints";
-
     private final BundleContext bundleContext;
     private final HandlerRegistry registry;
     private final Dispatcher dispatcher;
-    private final ServletContextAttributeListenerManager contextAttributeListener;
-    private final ServletRequestListenerManager requestListener;
-    private final ServletRequestAttributeListenerManager requestAttributeListener;
-    private final HttpSessionListenerManager sessionListener;
-    private final HttpSessionAttributeListenerManager sessionAttributeListener;
-    private final boolean sharedContextAttributes;
     private final HttpServicePlugin plugin;
+    private final HttpServiceFactory httpServiceFactory;
     private volatile WhiteboardHttpService whiteboardHttpService;
 
-    private final Hashtable<String, Object> httpServiceProps = new Hashtable<String, Object>();;
-    private volatile ServiceRegistration httpServiceReg;
-
     private volatile ServiceRegistration<HttpServiceRuntime> runtimeServiceReg;
     private final Hashtable<String, Object> runtimeServiceProps = new Hashtable<String, Object>();;
 
@@ -91,13 +55,8 @@
         this.bundleContext = bundleContext;
         this.registry = new HandlerRegistry();
         this.dispatcher = new Dispatcher(this.registry);
-        this.contextAttributeListener = new ServletContextAttributeListenerManager(bundleContext);
-        this.requestListener = new ServletRequestListenerManager(bundleContext);
-        this.requestAttributeListener = new ServletRequestAttributeListenerManager(bundleContext);
-        this.sessionListener = new HttpSessionListenerManager(bundleContext);
-        this.sessionAttributeListener = new HttpSessionAttributeListenerManager(bundleContext);
-        this.sharedContextAttributes = getBoolean(FELIX_HTTP_SHARED_SERVLET_CONTEXT_ATTRIBUTES);
         this.plugin = new HttpServicePlugin(bundleContext, registry);
+        this.httpServiceFactory = new HttpServiceFactory(this.bundleContext, this.registry);
     }
 
     public Dispatcher getDispatcher()
@@ -105,84 +64,67 @@
         return this.dispatcher;
     }
 
-    public ServletContextAttributeListenerManager getContextAttributeListener()
+    ServletContextAttributeListenerManager getContextAttributeListener()
     {
-        return contextAttributeListener;
+        return this.httpServiceFactory.getContextAttributeListener();
     }
 
-    public ServletRequestListenerManager getRequestListener()
+    ServletRequestListenerManager getRequestListener()
     {
-        return requestListener;
+        return this.httpServiceFactory.getRequestListener();
     }
 
-    public ServletRequestAttributeListenerManager getRequestAttributeListener()
+    ServletRequestAttributeListenerManager getRequestAttributeListener()
     {
-        return requestAttributeListener;
+        return this.httpServiceFactory.getRequestAttributeListener();
     }
 
-    public HttpSessionListener getSessionListener()
+    HttpSessionListener getSessionListener()
     {
         return new HttpSessionListener() {
 
             @Override
             public void sessionDestroyed(final HttpSessionEvent se) {
-                sessionListener.sessionDestroyed(se);
+                httpServiceFactory.getSessionListener().sessionDestroyed(se);
                 whiteboardHttpService.sessionDestroyed(se.getSession(), HttpSessionWrapper.getSessionContextIds(se.getSession()));
             }
 
             @Override
             public void sessionCreated(final HttpSessionEvent se) {
-                sessionListener.sessionCreated(se);
+                httpServiceFactory.getSessionListener().sessionCreated(se);
             }
         };
     }
 
-    public HttpSessionAttributeListener getSessionAttributeListener()
+    HttpSessionAttributeListener getSessionAttributeListener()
     {
-        return sessionAttributeListener;
+        return httpServiceFactory.getSessionAttributeListener();
     }
 
-    public void setProperties(Hashtable<String, Object> props)
+    public void setProperties(final Hashtable<String, Object> props)
     {
-        this.httpServiceProps.clear();
-        this.httpServiceProps.putAll(props);
-
-        if ( this.httpServiceProps.get(HttpServiceRuntimeConstants.HTTP_SERVICE_ENDPOINT_ATTRIBUTE) != null )
-        {
-            this.httpServiceProps.put(OBSOLETE_REG_PROPERTY_ENDPOINTS,
-                    this.httpServiceProps.get(HttpServiceRuntimeConstants.HTTP_SERVICE_ENDPOINT_ATTRIBUTE));
-        }
+        this.httpServiceFactory.setProperties(props);
 
         // runtime service gets the same props for now
         this.runtimeServiceProps.clear();
-        this.runtimeServiceProps.putAll(this.httpServiceProps);
+        this.runtimeServiceProps.putAll(props);
 
-        if (this.httpServiceReg != null)
+        if (this.runtimeServiceReg != null)
         {
-            this.httpServiceReg.setProperties(this.httpServiceProps);
-
             this.runtimeServiceProps.put(HttpServiceRuntimeConstants.HTTP_SERVICE_ID_ATTRIBUTE,
-                    this.httpServiceReg.getReference().getProperty(Constants.SERVICE_ID));
+                    this.httpServiceFactory.getHttpServiceServiceId());
             this.runtimeServiceReg.setProperties(this.runtimeServiceProps);
         }
     }
 
-    public void register(ServletContext servletContext)
+    public void register(final ServletContext servletContext)
     {
-        this.contextAttributeListener.open();
-        this.requestListener.open();
-        this.requestAttributeListener.open();
-        this.sessionListener.open();
-        this.sessionAttributeListener.open();
         this.plugin.register();
 
-        String[] ifaces = new String[] { HttpService.class.getName(), ExtHttpService.class.getName() };
-        HttpServiceFactory factory = new HttpServiceFactory(servletContext, this.registry, this.contextAttributeListener, this.sharedContextAttributes);
-
-        this.httpServiceReg = this.bundleContext.registerService(ifaces, factory, this.httpServiceProps);
+        this.httpServiceFactory.start(servletContext);
 
         this.runtimeServiceProps.put(HttpServiceRuntimeConstants.HTTP_SERVICE_ID_ATTRIBUTE,
-                this.httpServiceReg.getReference().getProperty(Constants.SERVICE_ID));
+                this.httpServiceFactory.getHttpServiceServiceId());
         this.runtimeServiceReg = this.bundleContext.registerService(HttpServiceRuntime.class,
                 new HttpServiceRuntimeImpl(),
                 this.runtimeServiceProps);
@@ -209,31 +151,13 @@
             this.runtimeServiceReg = null;
         }
 
-        this.sessionAttributeListener.close();
-        this.sessionListener.close();
-        this.contextAttributeListener.close();
-        this.requestListener.close();
-        this.requestAttributeListener.close();
-
         this.plugin.unregister();
 
-        if ( this.httpServiceReg != null )
+        if ( this.httpServiceFactory != null )
         {
-            try
-            {
-                this.httpServiceReg.unregister();
-                this.registry.shutdown();
-            }
-            finally
-            {
-                this.httpServiceReg = null;
-            }
+            this.httpServiceFactory.stop();
         }
-    }
 
-    private boolean getBoolean(final String property)
-    {
-        String prop = this.bundleContext.getProperty(property);
-        return (prop != null) ? Boolean.valueOf(prop).booleanValue() : false;
+        this.registry.shutdown();
     }
 }
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceFactory.java b/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceFactory.java
index ecf850a..0a132c0 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceFactory.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceFactory.java
@@ -16,30 +16,108 @@
  */
 package org.apache.felix.http.base.internal.service;
 
-import javax.servlet.ServletContext;
-import javax.servlet.ServletContextAttributeListener;
+import java.util.Hashtable;
 
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpSessionAttributeListener;
+import javax.servlet.http.HttpSessionListener;
+
+import org.apache.felix.http.api.ExtHttpService;
 import org.apache.felix.http.base.internal.handler.HandlerRegistry;
+import org.apache.felix.http.base.internal.service.listener.HttpSessionAttributeListenerManager;
+import org.apache.felix.http.base.internal.service.listener.HttpSessionListenerManager;
+import org.apache.felix.http.base.internal.service.listener.ServletContextAttributeListenerManager;
+import org.apache.felix.http.base.internal.service.listener.ServletRequestAttributeListenerManager;
+import org.apache.felix.http.base.internal.service.listener.ServletRequestListenerManager;
 import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceFactory;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.http.HttpService;
+import org.osgi.service.http.runtime.HttpServiceRuntimeConstants;
 
 public final class HttpServiceFactory
     implements ServiceFactory<HttpService>
 {
-    private final ServletContext context;
-    private final ServletContextAttributeListener attributeListener;
+    /**
+     * Name of the Framework property indicating whether the servlet context
+     * attributes of the ServletContext objects created for each HttpContext
+     * used to register servlets and resources share their attributes or not.
+     * By default (if this property is not specified or it's value is not
+     * <code>true</code> (case-insensitive)) servlet context attributes are not
+     * shared. To have servlet context attributes shared amongst servlet context
+     * and also with the ServletContext provided by the servlet container ensure
+     * setting the property as follows:
+     * <pre>
+     * org.apache.felix.http.shared_servlet_context_attributes = true
+     * </pre>
+     * <p>
+     * <b>WARNING:</b> Only set this property if absolutely needed (for example
+     * you implement an HttpSessionListener and want to access servlet context
+     * attributes of the ServletContext to which the HttpSession is linked).
+     * Otherwise leave this property unset.
+     */
+    private static final String FELIX_HTTP_SHARED_SERVLET_CONTEXT_ATTRIBUTES = "org.apache.felix.http.shared_servlet_context_attributes";
+
+    /** Compatiblity property for previous versions. */
+    private static final String OBSOLETE_REG_PROPERTY_ENDPOINTS = "osgi.http.service.endpoints";
+
+    private final BundleContext bundleContext;
     private final HandlerRegistry handlerRegistry;
     private final boolean sharedContextAttributes;
 
-    public HttpServiceFactory(ServletContext context, HandlerRegistry handlerRegistry,
-        ServletContextAttributeListener attributeListener, boolean sharedContextAttributes)
+    private final ServletContextAttributeListenerManager contextAttributeListenerManager;
+    private final ServletRequestListenerManager requestListenerManager;
+    private final ServletRequestAttributeListenerManager requestAttributeListenerManager;
+    private final HttpSessionListenerManager sessionListenerManager;
+    private final HttpSessionAttributeListenerManager sessionAttributeListenerManager;
+
+    private final Hashtable<String, Object> httpServiceProps = new Hashtable<String, Object>();
+    private volatile ServletContext context;
+    private volatile ServiceRegistration<?> httpServiceReg;
+
+    public HttpServiceFactory(final BundleContext bundleContext,
+            final HandlerRegistry handlerRegistry)
+    {
+        this.bundleContext = bundleContext;
+        this.handlerRegistry = handlerRegistry;
+        this.sharedContextAttributes = getBoolean(FELIX_HTTP_SHARED_SERVLET_CONTEXT_ATTRIBUTES);
+
+        this.contextAttributeListenerManager = new ServletContextAttributeListenerManager(bundleContext);
+        this.requestListenerManager = new ServletRequestListenerManager(bundleContext);
+        this.requestAttributeListenerManager = new ServletRequestAttributeListenerManager(bundleContext);
+        this.sessionListenerManager = new HttpSessionListenerManager(bundleContext);
+        this.sessionAttributeListenerManager = new HttpSessionAttributeListenerManager(bundleContext);
+    }
+
+    public void start(final ServletContext context)
     {
         this.context = context;
-        this.attributeListener = attributeListener;
-        this.handlerRegistry = handlerRegistry;
-        this.sharedContextAttributes = sharedContextAttributes;
+        this.contextAttributeListenerManager.open();
+        this.requestListenerManager.open();
+        this.requestAttributeListenerManager.open();
+        this.sessionListenerManager.open();
+        this.sessionAttributeListenerManager.open();
+
+        final String[] ifaces = new String[] { HttpService.class.getName(), ExtHttpService.class.getName() };
+        this.httpServiceReg = bundleContext.registerService(ifaces, this, this.httpServiceProps);
+    }
+
+    public void stop()
+    {
+        this.context = null;
+        if ( this.httpServiceReg != null )
+        {
+            this.httpServiceReg.unregister();
+            this.httpServiceReg = null;
+        }
+
+        this.contextAttributeListenerManager.close();
+        this.requestListenerManager.close();
+        this.requestAttributeListenerManager.close();
+        this.sessionListenerManager.close();
+        this.sessionAttributeListenerManager.close();
     }
 
     @Override
@@ -47,7 +125,7 @@
     {
         return new HttpServiceImpl(bundle, this.context,
                 this.handlerRegistry.getRegistry(null),
-                this.attributeListener,
+                this.contextAttributeListenerManager,
                 this.sharedContextAttributes);
     }
 
@@ -60,4 +138,57 @@
             ((HttpServiceImpl)service).unregisterAll();
         }
     }
+
+    public ServletContextAttributeListenerManager getContextAttributeListener()
+    {
+        return contextAttributeListenerManager;
+    }
+
+    public ServletRequestListenerManager getRequestListener()
+    {
+        return requestListenerManager;
+    }
+
+    public ServletRequestAttributeListenerManager getRequestAttributeListener()
+    {
+        return requestAttributeListenerManager;
+    }
+
+    public HttpSessionListener getSessionListener()
+    {
+        return sessionListenerManager;
+    }
+
+    public HttpSessionAttributeListener getSessionAttributeListener()
+    {
+        return sessionAttributeListenerManager;
+    }
+
+    public long getHttpServiceServiceId()
+    {
+        return (Long) this.httpServiceReg.getReference().getProperty(Constants.SERVICE_ID);
+    }
+
+    public void setProperties(final Hashtable<String, Object> props)
+    {
+        this.httpServiceProps.clear();
+        this.httpServiceProps.putAll(props);
+
+        if ( this.httpServiceProps.get(HttpServiceRuntimeConstants.HTTP_SERVICE_ENDPOINT_ATTRIBUTE) != null )
+        {
+            this.httpServiceProps.put(OBSOLETE_REG_PROPERTY_ENDPOINTS,
+                    this.httpServiceProps.get(HttpServiceRuntimeConstants.HTTP_SERVICE_ENDPOINT_ATTRIBUTE));
+        }
+
+        if (this.httpServiceReg != null)
+        {
+            this.httpServiceReg.setProperties(this.httpServiceProps);
+        }
+    }
+
+    private boolean getBoolean(final String property)
+    {
+        String prop = this.bundleContext.getProperty(property);
+        return (prop != null) ? Boolean.valueOf(prop).booleanValue() : false;
+    }
 }
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardHttpService.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardHttpService.java
index faca570..fe7c46e 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardHttpService.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/WhiteboardHttpService.java
@@ -17,6 +17,7 @@
 package org.apache.felix.http.base.internal.whiteboard;
 
 import java.util.ArrayList;
+import java.util.List;
 import java.util.Set;
 
 import javax.annotation.Nonnull;
@@ -59,7 +60,7 @@
 
     private final ServletContextHelperManager contextManager;
 
-    private final ArrayList<ServiceTracker<?, ?>> trackers = new ArrayList<ServiceTracker<?, ?>>();
+    private final List<ServiceTracker<?, ?>> trackers = new ArrayList<ServiceTracker<?, ?>>();
 
     /**
      * Create a new whiteboard http service
@@ -75,7 +76,7 @@
         this.handlerRegistry = handlerRegistry;
         this.bundleContext = bundleContext;
         this.contextManager = new ServletContextHelperManager(bundleContext, context, runtimeRef, this);
-        
+
         addTracker(new FilterTracker(bundleContext, contextManager));
         addTracker(new ServletTracker(bundleContext, this.contextManager));
         addTracker(new ResourceTracker(bundleContext, this.contextManager));
@@ -86,7 +87,7 @@
         addTracker(new ServletContextHelperTracker(bundleContext, this.contextManager));
         addTracker(new ServletContextListenerTracker(bundleContext, this.contextManager));
         addTracker(new ServletContextAttributeListenerTracker(bundleContext, this.contextManager));
-        
+
         addTracker(new ServletRequestListenerTracker(bundleContext, this.contextManager));
         addTracker(new ServletRequestAttributeListenerTracker(bundleContext, this.contextManager));
     }