Fixed an incorrect interpretation of the spec where we were equating
"is removal pending" with "is stale" for exported packages, but this is
not correct. A package is removal pending if it has been updated or
uninstalled, while a package is stale if it has been refreshed and is
no longer valid.


git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@422679 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/BundleInfo.java b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/BundleInfo.java
index e8cfe4e..42e00b4 100644
--- a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/BundleInfo.java
+++ b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/BundleInfo.java
@@ -24,6 +24,9 @@
 
 class BundleInfo
 {
+    private static final int REMOVAL_PENDING_FLAG = 1;
+    private static final int STALE_FLAG = 2;
+
     private Logger m_logger = null;
     private BundleArchive m_archive = null;
     private IModule[] m_modules = null;
@@ -31,9 +34,11 @@
     private long m_modified = 0;
     private BundleActivator m_activator = null;
     private BundleContext m_context = null;
-    // Indicates that the bundle was either updated
-    // or uninstalled and is waiting to be removed or refreshed.
-    private boolean m_removalPending = false;
+    // Indicates that the bundle was either updated or
+    // uninstalled and is waiting to be removed or refreshed,
+    // or whether the bundle is stale because it was already
+    // refreshed.
+    private int m_removalState = 0;
 
     // Used for bundle locking.
     private int m_lockCount = 0;
@@ -47,7 +52,7 @@
         m_modules = (module == null) ? new IModule[0] : new IModule[] { module };
 
         m_state = Bundle.INSTALLED;
-        m_removalPending = false;
+        m_removalState = 0;
         m_activator = null;
         m_context = null;
     }
@@ -302,12 +307,22 @@
 
     public boolean isRemovalPending()
     {
-        return m_removalPending;
+        return (m_removalState & REMOVAL_PENDING_FLAG) != 0;
     }
 
     public void setRemovalPending()
     {
-        m_removalPending = true;
+        m_removalState = (m_removalState | REMOVAL_PENDING_FLAG);
+    }
+
+    public boolean isStale()
+    {
+        return (m_removalState & STALE_FLAG) != 0;
+    }
+
+    public void setStale()
+    {
+        m_removalState = (m_removalState | STALE_FLAG | REMOVAL_PENDING_FLAG);
     }
 
     //
diff --git a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/ExportedPackageImpl.java b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/ExportedPackageImpl.java
index 0db0a84..87a5146 100644
--- a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/ExportedPackageImpl.java
+++ b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/ExportedPackageImpl.java
@@ -40,33 +40,18 @@
 
     public Bundle getExportingBundle()
     {
-        // If remove is pending due to a bundle update, then
-        // return null per the spec.
-        if (m_exporter.getInfo().isRemovalPending())
+        // If the package is stale, then return null per the spec.
+        if (m_exporter.getInfo().isStale())
         {
             return null;
         }
         return m_exporter;
     }
 
-    /**
-     * Returns the exporting bundle whether the package is state or
-     * not. This is called internally to get access to the exporting
-     * bundle during a refresh operation, which is not possible using
-     * <tt>getExportingBundle</tt> since the specification says that
-     * method must return <tt>null</tt> for stale packages.
-     * @return the exporting bundle for the package.
-    **/
-    protected Bundle getExportingBundleInternal()
-    {
-        return m_exporter;
-    }
-    
     public Bundle[] getImportingBundles()
     {
-        // If remove is pending due to a bundle update, then
-        // return null per the spec.
-        if (m_exporter.getInfo().isRemovalPending())
+        // If the package is stale, then return null per the spec.
+        if (m_exporter.getInfo().isStale())
         {
             return null;
         }
diff --git a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/Felix.java b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/Felix.java
index 21ba7d1..6a56bc8 100644
--- a/org.apache.felix.framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/org.apache.felix.framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -2626,11 +2626,9 @@
 
     protected Bundle[] getImportingBundles(ExportedPackage ep)
     {
-        // Get exporting bundle; we need to use this internal
-        // method because the spec says ep.getExportingBundle()
-        // should return null if the package is stale.
+        // Get exporting bundle.
         BundleImpl exporter = (BundleImpl)
-            ((ExportedPackageImpl) ep).getExportingBundleInternal();
+            ((ExportedPackage) ep).getExportingBundle();
         BundleInfo exporterInfo = exporter.getInfo();
 
         // Create list for storing importing bundles.
@@ -3649,6 +3647,9 @@
             {
                 BundleInfo info = m_bundle.getInfo();
 
+                // Mark the bundle as stale.
+                info.setStale();
+
                 // Remove or purge the bundle depending on its
                 // current state.
                 if (info.getState() == Bundle.UNINSTALLED)