FELIX-4726 Prevent bundle find hooks from hiding things for the system bundle



git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1644574 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 4f83e33..26362d7 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -3090,11 +3090,19 @@
                         }
                     }
                 }
-                if (bundles.isEmpty())
+
+                if (origin != this)
                 {
-                    throw new BundleException(
-                        "Bundle installation rejected by hook.",
-                        BundleException.REJECTED_BY_HOOK);
+                    // If the origin was something else than the system bundle, reject this action if
+                    // the bundle has been removed by the hooks. However, if it is the system bundle,
+                    // the install action should always succeed, regardless of whether the hooks are
+                    // trying to prevent it.
+                    if (bundles.isEmpty())
+                    {
+                        throw new BundleException(
+                            "Bundle installation rejected by hook.",
+                            BundleException.REJECTED_BY_HOOK);
+                    }
                 }
             }
         }
@@ -3175,7 +3183,12 @@
                     }
                 }
             }
-            bundle = (bundles.isEmpty()) ? null : bundle;
+
+            if (bc.getBundle() != this)
+            {
+                // If the requesting bundle is not the system bundle, return the filtered result
+                bundle = (bundles.isEmpty()) ? null : bundle;
+            }
         }
         return bundle;
     }
@@ -3222,7 +3235,7 @@
             getHooks(org.osgi.framework.hooks.bundle.FindHook.class);
         if (!hooks.isEmpty())
         {
-            bundles = new ShrinkableCollection<Bundle>(new ArrayList(bundles));
+            Collection<Bundle> shrunkBundles = new ShrinkableCollection<Bundle>(new ArrayList(bundles));
             for (ServiceReference<org.osgi.framework.hooks.bundle.FindHook> hook : hooks)
             {
                 org.osgi.framework.hooks.bundle.FindHook fh = getService(this, hook, false);
@@ -3230,7 +3243,7 @@
                 {
                     try
                     {
-                        m_secureAction.invokeBundleFindHook(fh, bc, bundles);
+                        m_secureAction.invokeBundleFindHook(fh, bc, shrunkBundles);
                     }
                     catch (Throwable th)
                     {
@@ -3243,7 +3256,15 @@
                     }
                 }
             }
+
+            if (bc.getBundle() != this)
+            {
+                // If the requesting bundle is something other than the system bundle, return the shrunk
+                // collection of bundles. If it *is* the system bundle, it should receive the unfiltered bundles.
+                bundles = shrunkBundles;
+            }
         }
+
         return bundles.toArray(new Bundle[bundles.size()]);
     }