Applied patch (FELIX-713) to support transiently starting/stopping bundles.


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@700183 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
index f996c01..b60723c 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
@@ -360,6 +360,17 @@
 
     public void start() throws BundleException
     {
+        start(0);
+    }
+
+    public void start(int options) throws BundleException
+    {
+        if ((options & Bundle.START_ACTIVATION_POLICY) > 0)
+        {
+            throw new UnsupportedOperationException(
+                "The activation policy feature has not yet been implemented.");
+        }
+
         Object sm = System.getSecurityManager();
 
         if (sm != null)
@@ -368,12 +379,7 @@
                 AdminPermission.EXECUTE));
         }
 
-        m_felix.startBundle(this, true);
-    }
-
-	public void start(int options) throws BundleException
-    {
-        throw new UnsupportedOperationException("This feature has not yet been implemented.");
+        m_felix.startBundle(this, ((options & Bundle.START_TRANSIENT) == 0));
     }
 
     public void update() throws BundleException
@@ -396,6 +402,11 @@
 
     public void stop() throws BundleException
     {
+        stop(0);
+    }
+
+    public void stop(int options) throws BundleException
+    {
         Object sm = System.getSecurityManager();
 
         if (sm != null)
@@ -404,12 +415,7 @@
                 AdminPermission.EXECUTE));
         }
 
-        m_felix.stopBundle(this, true);
-    }
-
-	public void stop(int options) throws BundleException
-    {
-        throw new UnsupportedOperationException("This feature has not yet been implemented.");
+        m_felix.stopBundle(this, ((options & Bundle.STOP_TRANSIENT) == 0));
     }
 
     public void uninstall() throws BundleException
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 13c0c57..a368c7d 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -896,9 +896,11 @@
         fireFrameworkEvent(FrameworkEvent.STARTED, this, null);
     }
 
-	public void start(int options) throws BundleException
+    public void start(int options) throws BundleException
     {
-        throw new UnsupportedOperationException("This feature has not yet been implemented.");
+        // TODO: FRAMEWORK - For now, ignore all options when starting the
+        //       system bundle.
+        start();
     }
 
     /**
@@ -918,9 +920,11 @@
         stopBundle(this, true);
     }
 
-	public void stop(int options) throws BundleException
+    public void stop(int options) throws BundleException
     {
-        throw new UnsupportedOperationException("This feature has not yet been implemented.");
+        // TODO: FRAMEWORK - For now, ignore all options when stopping the
+        //       system bundle.
+        stop();
     }
 
     public void stopAndWait()
@@ -1553,9 +1557,12 @@
     private void _startBundle(FelixBundle bundle, boolean record)
         throws BundleException
     {
+        // Get bundle info object.
+        BundleInfo info = bundle.getInfo();
+
         // The spec doesn't say whether it is possible to start an extension
         // We just do nothing
-        if (bundle.getInfo().isExtension())
+        if (info.isExtension())
         {
             return;
         }
@@ -1564,17 +1571,23 @@
         // if we are supposed to record state change.
         if (record)
         {
-            bundle.getInfo().setPersistentStateActive();
+            info.setPersistentStateActive();
         }
 
-        // Try to start the bundle.
-        BundleInfo info = bundle.getInfo();
-
-        // Ignore bundles whose persistent state is not active
-        // or whose start level is greater than the framework's.
-        if ((info.getPersistentState() != Bundle.ACTIVE)
-            || (info.getStartLevel(getInitialBundleStartLevel()) > getStartLevel()))
+        // Check to see if the bundle's start level is greater than the
+        // the framework's start level.
+        if (info.getStartLevel(getInitialBundleStartLevel()) > getStartLevel())
         {
+            // Throw an exception for transient starts.
+            if (!record)
+            {
+                throw new BundleException(
+                    "Cannot start the bundle because its start level is "
+                    + info.getStartLevel(getInitialBundleStartLevel())
+                    + ", which is greater than the framework's start level of "
+                    + getStartLevel() + ".");
+            }
+            // Ignore persistent starts.
             return;
         }
 
@@ -1767,7 +1780,8 @@
 
             // Cannot update an uninstalled bundle.
             BundleInfo info = bundle.getInfo();
-            if (info.getState() == Bundle.UNINSTALLED)
+            final int oldState = info.getState();
+            if (oldState == Bundle.UNINSTALLED)
             {
                 throw new IllegalStateException("The bundle is uninstalled.");
             }
@@ -1914,10 +1928,12 @@
                 }
             }
 
-            // Restart bundle, but do not change the persistent state.
-            // This will not start the bundle if it was not previously
-            // active.
-            startBundle(bundle, false);
+            // Restart the bundle if necessary, but do not change its
+            // persistent state.
+            if (oldState == Bundle.ACTIVE)
+            {
+                startBundle(bundle, false);
+            }
 
             // If update failed, rethrow exception.
             if (rethrow != null)
@@ -3920,6 +3936,7 @@
     private class RefreshHelper
     {
         private FelixBundle m_bundle = null;
+        private int m_oldState = Bundle.INSTALLED;
 
         public RefreshHelper(Bundle bundle)
         {
@@ -3930,6 +3947,7 @@
         {
             if (m_bundle.getInfo().getState() == Bundle.ACTIVE)
             {
+                m_oldState = Bundle.ACTIVE;
                 try
                 {
                     stopBundle(m_bundle, false);
@@ -3996,7 +4014,7 @@
 
         public void restart()
         {
-            if (m_bundle != null)
+            if ((m_bundle != null) && (m_oldState == Bundle.ACTIVE))
             {
                 try
                 {