Modify framework wiring and framework start level object to registry
the package admin and start level services directly, rather than using
an activator. (FELIX-2969, FELIX-2975)


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1128515 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/Felix.java b/framework/src/main/java/org/apache/felix/framework/Felix.java
index 1cae819..3c58ab7 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -159,11 +159,11 @@
     private long m_nextId = 1L;
     private final Object m_nextIdLock = new Object[0];
 
-    // List of event listeners.
-    private EventDispatcher m_dispatcher = null;
-
     // Service registry.
-    private ServiceRegistry m_registry = null;
+    private final ServiceRegistry m_registry;
+
+    // List of event listeners.
+    private final EventDispatcher m_dispatcher;
 
     // Reusable bundle URL stream handler.
     private final URLStreamHandler m_bundleStreamHandler;
@@ -391,10 +391,21 @@
             throw new RuntimeException(ex.getMessage());
         }
 
+        // Create service registry.
+        m_registry = new ServiceRegistry(m_logger, new ServiceRegistryCallbacks() {
+            public void serviceChanged(ServiceEvent event, Dictionary oldProps)
+            {
+                fireServiceEvent(event, oldProps);
+            }
+        });
+
+        // Create event dispatcher.
+        m_dispatcher = new EventDispatcher(m_logger, m_registry);
+
         // Create framework wiring object.
-        m_fwkWiring = new FrameworkWiringImpl(this);
+        m_fwkWiring = new FrameworkWiringImpl(this, m_registry);
         // Create framework start level object.
-        m_fwkStartLevel = new FrameworkStartLevelImpl(this);
+        m_fwkStartLevel = new FrameworkStartLevelImpl(this, m_registry);
     }
 
     Logger getLogger()
@@ -616,16 +627,8 @@
                 m_activatorList = (List) m_configMutableMap.get(FelixConstants.SYSTEMBUNDLE_ACTIVATORS_PROP);
                 m_activatorList = (m_activatorList == null) ? new ArrayList() : new ArrayList(m_activatorList);
 
-                // Create service registry.
-                m_registry = new ServiceRegistry(m_logger, new ServiceRegistryCallbacks() {
-                    public void serviceChanged(ServiceEvent event, Dictionary oldProps)
-                    {
-                        fireServiceEvent(event, oldProps);
-                    }
-                });
-
                 // Initialize event dispatcher.
-                m_dispatcher = EventDispatcher.start(m_logger, m_registry);
+                m_dispatcher.startDispatching();
 
                 // Create the bundle cache, if necessary, so that we can reload any
                 // installed bundles.
@@ -777,7 +780,7 @@
                 }
                 catch (Throwable ex)
                 {
-                    EventDispatcher.shutdown();
+                    m_dispatcher.stopDispatching();
                     m_logger.log(Logger.LOG_ERROR, "Unable to start system bundle.", ex);
                     throw new RuntimeException("Unable to start system bundle.");
                 }
@@ -4849,10 +4852,6 @@
     {
         public void start(BundleContext context) throws Exception
         {
-            // Add the bundle activator for the package admin service.
-            m_activatorList.add(0, new PackageAdminActivator(Felix.this));
-            // Add the bundle activator for the start level service.
-            m_activatorList.add(0, new StartLevelActivator(m_logger, Felix.this));
             // Add the bundle activator for the url handler service.
             m_activatorList.add(0, new URLHandlersActivator(m_configMap, Felix.this));
 
@@ -4884,7 +4883,7 @@
             m_fwkStartLevel.stop();
 
             // Shutdown event dispatching queue.
-            EventDispatcher.shutdown();
+            m_dispatcher.stopDispatching();
 
             // Since there may be updated and uninstalled bundles that
             // have not been refreshed, we will take care of refreshing
diff --git a/framework/src/main/java/org/apache/felix/framework/FrameworkStartLevelImpl.java b/framework/src/main/java/org/apache/felix/framework/FrameworkStartLevelImpl.java
index 6ce7924..dcb5fcc 100644
--- a/framework/src/main/java/org/apache/felix/framework/FrameworkStartLevelImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/FrameworkStartLevelImpl.java
@@ -22,9 +22,12 @@
 import java.util.List;
 import org.osgi.framework.AdminPermission;
 import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
 import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.ServiceRegistration;
 import org.osgi.framework.startlevel.BundleStartLevel;
 import org.osgi.framework.startlevel.FrameworkStartLevel;
+import org.osgi.service.startlevel.StartLevel;
 
 class FrameworkStartLevelImpl implements FrameworkStartLevel, Runnable
 {
@@ -37,11 +40,16 @@
     private final List m_requests = new ArrayList();
     private final List<FrameworkListener[]> m_requestListeners
         = new ArrayList<FrameworkListener[]>();
+    private final ServiceRegistration<StartLevel> m_slReg;
     private Thread m_thread = null;
 
-    FrameworkStartLevelImpl(Felix felix)
+    FrameworkStartLevelImpl(Felix felix, ServiceRegistry registry)
     {
         m_felix = felix;
+        m_slReg = registry.registerService(felix,
+            new String[] { StartLevel.class.getName() },
+            new StartLevelImpl(felix),
+            null);
     }
 
     // Should only be called hold requestList lock.
diff --git a/framework/src/main/java/org/apache/felix/framework/FrameworkWiringImpl.java b/framework/src/main/java/org/apache/felix/framework/FrameworkWiringImpl.java
index 9c14d47..da7bfee 100644
--- a/framework/src/main/java/org/apache/felix/framework/FrameworkWiringImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/FrameworkWiringImpl.java
@@ -20,14 +20,13 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 import org.osgi.framework.AdminPermission;
 import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
 import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.ServiceRegistration;
 import org.osgi.framework.wiring.FrameworkWiring;
+import org.osgi.service.packageadmin.PackageAdmin;
 
 class FrameworkWiringImpl implements FrameworkWiring, Runnable
 {
@@ -35,12 +34,17 @@
     private final List<Collection<Bundle>> m_requests = new ArrayList();
     private final List<FrameworkListener[]> m_requestListeners
         = new ArrayList<FrameworkListener[]>();
+    private final ServiceRegistration<PackageAdmin> m_paReg;
     private Thread m_thread = null;
 
 
-    public FrameworkWiringImpl(Felix felix)
+    public FrameworkWiringImpl(Felix felix, ServiceRegistry registry)
     {
         m_felix = felix;
+        m_paReg = registry.registerService(felix,
+            new String[] { PackageAdmin.class.getName() },
+            new PackageAdminImpl(felix),
+            null);
     }
 
     /**
diff --git a/framework/src/main/java/org/apache/felix/framework/PackageAdminActivator.java b/framework/src/main/java/org/apache/felix/framework/PackageAdminActivator.java
deleted file mode 100644
index 786c6b4..0000000
--- a/framework/src/main/java/org/apache/felix/framework/PackageAdminActivator.java
+++ /dev/null
@@ -1,46 +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.framework;
-
-import org.osgi.framework.*;
-
-class PackageAdminActivator implements BundleActivator
-{
-    private Felix m_felix = null;
-    private ServiceRegistration m_reg = null;
-    private PackageAdminImpl m_packageAdmin = null;
-
-    public PackageAdminActivator(Felix felix)
-    {
-        m_felix = felix;
-    }
-
-    public void start(BundleContext context) throws Exception
-    {
-        m_packageAdmin = new PackageAdminImpl(m_felix);
-        m_reg = context.registerService(
-            org.osgi.service.packageadmin.PackageAdmin.class.getName(),
-            m_packageAdmin, null);
-    }
-
-    public void stop(BundleContext context) throws Exception
-    {
-        m_reg.unregister();
-    }
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/StartLevelActivator.java b/framework/src/main/java/org/apache/felix/framework/StartLevelActivator.java
deleted file mode 100644
index 2888675..0000000
--- a/framework/src/main/java/org/apache/felix/framework/StartLevelActivator.java
+++ /dev/null
@@ -1,48 +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.framework;
-
-import org.osgi.framework.*;
-
-class StartLevelActivator implements BundleActivator
-{
-    private Logger m_logger = null;
-    private Felix m_felix = null;
-    private StartLevelImpl m_startLevel = null;
-    private ServiceRegistration m_reg = null;
-
-    public StartLevelActivator(Logger logger, Felix felix)
-    {
-        m_logger = logger;
-        m_felix = felix;
-    }
-
-    public void start(BundleContext context) throws Exception
-    {
-        m_startLevel = new StartLevelImpl(m_felix);
-        m_reg = context.registerService(
-            org.osgi.service.startlevel.StartLevel.class.getName(),
-            m_startLevel, null);
-    }
-
-    public void stop(BundleContext context) throws Exception
-    {
-        m_reg.unregister();
-    }
-}
diff --git a/framework/src/main/java/org/apache/felix/framework/util/EventDispatcher.java b/framework/src/main/java/org/apache/felix/framework/util/EventDispatcher.java
index c77ee55..a8c3a5f 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/EventDispatcher.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/EventDispatcher.java
@@ -80,16 +80,14 @@
     // Pooled requests to avoid memory allocation.
     private static final ArrayList m_requestPool = new ArrayList();
 
-    private EventDispatcher(Logger logger, ServiceRegistry registry)
+    public EventDispatcher(Logger logger, ServiceRegistry registry)
     {
         m_logger = logger;
         m_registry = registry;
     }
 
-    public static EventDispatcher start(Logger logger, ServiceRegistry registry)
+    public void startDispatching()
     {
-        EventDispatcher eventDispatcher = new EventDispatcher(logger, registry);
-
         synchronized (m_threadLock)
         {
             // Start event dispatching thread if necessary.
@@ -124,11 +122,9 @@
             // reference counting and flags
             m_references++;
         }
-
-        return eventDispatcher;
     }
 
-    public static void shutdown()
+    public void stopDispatching()
     {
         synchronized (m_threadLock)
         {
diff --git a/framework/src/test/java/org/apache/felix/framework/util/EventDispatcherTest.java b/framework/src/test/java/org/apache/felix/framework/util/EventDispatcherTest.java
index 1c04eb5..6c8bfaf 100644
--- a/framework/src/test/java/org/apache/felix/framework/util/EventDispatcherTest.java
+++ b/framework/src/test/java/org/apache/felix/framework/util/EventDispatcherTest.java
@@ -83,8 +83,7 @@
         registry.registerService(null, new String [] {EventHook.class.getName()}, eh2, new Hashtable());
 
         // -- Set up event dispatcher
-        EventDispatcher ed = EventDispatcher.start(logger, registry);
-        EventDispatcher.shutdown(); // stop the thread - would be nicer if we could create one without a thread for testing
+        EventDispatcher ed = new EventDispatcher(logger, registry);
 
         // -- Register some listeners
         final List fired = Collections.synchronizedList(new ArrayList());