516412 - Remove deprecated PackageAdmin from BundleDeployer

Also remove DS dependency in StandardApplicationDeployer

Change-Id: I3ecedbba78ab2df01e53dbc0ab8da1665af96086
diff --git a/nano/org.eclipse.virgo.nano.deployer/src/main/java/org/eclipse/virgo/nano/deployer/internal/BundleDeployer.java b/nano/org.eclipse.virgo.nano.deployer/src/main/java/org/eclipse/virgo/nano/deployer/internal/BundleDeployer.java
index 8ccb8a8..766383b 100644
--- a/nano/org.eclipse.virgo.nano.deployer/src/main/java/org/eclipse/virgo/nano/deployer/internal/BundleDeployer.java
+++ b/nano/org.eclipse.virgo.nano.deployer/src/main/java/org/eclipse/virgo/nano/deployer/internal/BundleDeployer.java
@@ -12,6 +12,7 @@
 package org.eclipse.virgo.nano.deployer.internal;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
+import static java.util.Collections.singleton;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -20,9 +21,7 @@
 import java.io.InputStreamReader;
 import java.net.URI;
 import java.net.URLDecoder;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.List;
+import java.util.*;
 import java.util.jar.JarFile;
 
 import org.eclipse.virgo.medic.eventlog.EventLogger;
@@ -35,6 +34,7 @@
 import org.eclipse.virgo.nano.deployer.util.StatusFileModificator;
 import org.eclipse.virgo.util.io.FileCopyUtils;
 import org.eclipse.virgo.util.io.IOUtils;
+import org.eclipse.virgo.util.osgi.BundleUtils;
 import org.eclipse.virgo.util.osgi.manifest.BundleManifest;
 import org.eclipse.virgo.util.osgi.manifest.BundleManifestFactory;
 import org.eclipse.virgo.util.osgi.manifest.FragmentHost;
@@ -42,7 +42,7 @@
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleException;
-import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.framework.wiring.*;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -72,18 +72,15 @@
 
     private final BundleInfosUpdater bundleInfosUpdater;
 
-    private final PackageAdmin packageAdmin;
-
     private final File workBundleInstallLocation;
 
     private final File kernelHomeFile;
 
     private final File pickupDir;
 
-    public BundleDeployer(BundleContext bundleContext, PackageAdmin packageAdmin, EventLogger eventLogger) {
+    public BundleDeployer(BundleContext bundleContext, EventLogger eventLogger) {
         this.eventLogger = eventLogger;
         this.bundleContext = bundleContext;
-        this.packageAdmin = packageAdmin;
         String kernelHome = System.getProperty(KERNEL_HOME_PROP);
         if (kernelHome != null) {
             this.kernelHomeFile = new File(kernelHome);
@@ -126,23 +123,13 @@
         return hostHolder != null && hostHolder.getBundleSymbolicName() != null;
     }
 
-    private Boolean isFragment(Bundle bundle) {
-        Enumeration<String> keys = bundle.getHeaders().keys();
-        while (keys.hasMoreElements()) {
-            if (keys.nextElement().equalsIgnoreCase(FRAGMEN_HOST_HEADER)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private void refreshHosts(FragmentHost hostHolder, Bundle fragment) {
+    private void refreshHosts(Bundle fragment) {
         try {
-            Bundle[] hosts = this.packageAdmin.getBundles(hostHolder.getBundleSymbolicName(), null);
+            Set<Bundle> hosts = BundleUtils.getHosts(fragment);
             if (hosts != null) {
                 this.eventLogger.log(NanoDeployerLogEvents.NANO_REFRESHING_HOST, fragment.getSymbolicName(), fragment.getVersion());
                 this.eventLogger.log(NanoDeployerLogEvents.NANO_REFRESHING_HOST, fragment.getSymbolicName(), fragment.getVersion());
-                this.packageAdmin.refreshPackages(hosts);
+                BundleUtils.refreshBundles(this.bundleContext, hosts);
                 this.eventLogger.log(NanoDeployerLogEvents.NANO_REFRESHED_HOST, fragment.getSymbolicName(), fragment.getVersion());
             }
         } catch (Exception e) {
@@ -184,7 +171,7 @@
 
             // if fragment, refresh hosts and update bundles.info
             if (isFragment(hostHolder)) {
-                refreshHosts(hostHolder, installed);
+                refreshHosts(installed);
                 updateBundleInfo(installed, stagedFile, true);
             }
             StatusFileModificator.createStatusFile(jarName, this.pickupDir, StatusFileModificator.OP_DEPLOY, STATUS_ERROR, installed.getBundleId(),
@@ -208,7 +195,7 @@
         if (installedBundle != null) {
             this.eventLogger.log(NanoDeployerLogEvents.NANO_STARTING, installedBundle.getSymbolicName(), installedBundle.getVersion());
             try {
-                if (!isFragment(installedBundle)) {
+                if (!BundleUtils.isFragmentBundle(installedBundle)) {
                     installedBundle.start();
                     updateBundleInfo(installedBundle, stagedFile, false);
                     this.eventLogger.log(NanoDeployerLogEvents.NANO_STARTED, installedBundle.getSymbolicName(), installedBundle.getVersion());
@@ -271,10 +258,10 @@
 
         if (hostHolder != null && hostHolder.getBundleSymbolicName() != null) {
             try {
-                Bundle[] hosts = this.packageAdmin.getBundles(hostHolder.getBundleSymbolicName(), null);
+                Set<Bundle> hosts = BundleUtils.getBundlesBySymbolicName(bundleContext, hostHolder.getBundleSymbolicName());
                 if (hosts != null) {
                     this.eventLogger.log(NanoDeployerLogEvents.NANO_REFRESHING_HOST, installed.getSymbolicName(), installed.getVersion());
-                    this.packageAdmin.refreshPackages(hosts);
+                    BundleUtils.refreshBundles(bundleContext, hosts);
                     this.eventLogger.log(NanoDeployerLogEvents.NANO_REFRESHED_HOST, installed.getSymbolicName(), installed.getVersion());
                 }
             } catch (Exception e) {
@@ -342,10 +329,8 @@
 
                 this.eventLogger.log(NanoDeployerLogEvents.NANO_UPDATING, bundle.getSymbolicName(), bundle.getVersion());
                 bundle.update();
-                if (this.packageAdmin != null) {
-                    this.packageAdmin.refreshPackages(new Bundle[] { bundle });
-                    this.logger.info("Update of file with path '" + path + "' is successful.");
-                }
+                BundleUtils.refreshBundles(this.bundleContext, singleton(bundle));
+                this.logger.info("Update of file with path '" + path + "' is successful.");
                 this.eventLogger.log(NanoDeployerLogEvents.NANO_UPDATED, bundle.getSymbolicName(), bundle.getVersion());
             } catch (Exception e) {
                 this.eventLogger.log(NanoDeployerLogEvents.NANO_UPDATE_ERROR, e, bundle.getSymbolicName(), bundle.getVersion());
diff --git a/nano/org.eclipse.virgo.nano.deployer/src/main/java/org/eclipse/virgo/nano/deployer/internal/StandardApplicationDeployer.java b/nano/org.eclipse.virgo.nano.deployer/src/main/java/org/eclipse/virgo/nano/deployer/internal/StandardApplicationDeployer.java
index 51d233a..08dcd4c 100644
--- a/nano/org.eclipse.virgo.nano.deployer/src/main/java/org/eclipse/virgo/nano/deployer/internal/StandardApplicationDeployer.java
+++ b/nano/org.eclipse.virgo.nano.deployer/src/main/java/org/eclipse/virgo/nano/deployer/internal/StandardApplicationDeployer.java
@@ -35,7 +35,6 @@
 import org.osgi.service.component.ComponentContext;
 import org.osgi.service.event.Event;
 import org.osgi.service.event.EventAdmin;
-import org.osgi.service.packageadmin.PackageAdmin;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -45,8 +44,6 @@
 
     private EventLogger eventLogger;
 
-    private PackageAdmin packageAdmin;
-
     private final List<SimpleDeployer> simpleDeployers = new ArrayList<>();
 
     private final Logger logger = LoggerFactory.getLogger(this.getClass());
@@ -63,7 +60,7 @@
 
     public void activate(ComponentContext context) {
         this.bundleContext = context.getBundleContext();
-        this.defaultDeployer = new BundleDeployer(context.getBundleContext(), this.packageAdmin, this.eventLogger);
+        this.defaultDeployer = new BundleDeployer(context.getBundleContext(), this.eventLogger);
         this.simpleDeployers.add(this.defaultDeployer);
 
         recoveryComplete();
@@ -268,14 +265,6 @@
         this.kernelConfig = null;
     }
 
-    public void bindPackageAdmin(PackageAdmin packageAdmin) {
-        this.packageAdmin = packageAdmin;
-    }
-
-    public void unbindPackageAdmin(PackageAdmin packageAdmin) {
-        this.packageAdmin = null;
-    }
-
     public void bindSimpleDeployer(SimpleDeployer deployer) {
         this.simpleDeployers.add(deployer);
     }
diff --git a/nano/org.eclipse.virgo.nano.deployer/src/main/resources/OSGI-INF/org.eclipse.virgo.nano.deployer.xml b/nano/org.eclipse.virgo.nano.deployer/src/main/resources/OSGI-INF/org.eclipse.virgo.nano.deployer.xml
index 79401e3..6485db7 100644
--- a/nano/org.eclipse.virgo.nano.deployer/src/main/resources/OSGI-INF/org.eclipse.virgo.nano.deployer.xml
+++ b/nano/org.eclipse.virgo.nano.deployer/src/main/resources/OSGI-INF/org.eclipse.virgo.nano.deployer.xml
@@ -16,13 +16,6 @@
 		bind="bindEventAdmin" 
 		unbind="unbindEventAdmin"/>
 		
-	<reference name="PackageAdmin"
-		interface="org.osgi.service.packageadmin.PackageAdmin"
-		policy="static" 
-		cardinality="1..1" 
-		bind="bindPackageAdmin" 
-		unbind="unbindPackageAdmin"/>
-		
 	<reference name="KernelConfig"
 		interface="org.eclipse.virgo.nano.core.KernelConfig"  
 		policy="static" 
diff --git a/util/org.eclipse.virgo.util.osgi/src/main/java/org/eclipse/virgo/util/osgi/BundleUtils.java b/util/org.eclipse.virgo.util.osgi/src/main/java/org/eclipse/virgo/util/osgi/BundleUtils.java
index 663ca0d..ea978e0 100644
--- a/util/org.eclipse.virgo.util.osgi/src/main/java/org/eclipse/virgo/util/osgi/BundleUtils.java
+++ b/util/org.eclipse.virgo.util.osgi/src/main/java/org/eclipse/virgo/util/osgi/BundleUtils.java
@@ -11,16 +11,20 @@
 
 package org.eclipse.virgo.util.osgi;
 
+import org.eclipse.osgi.framework.internal.core.Constants;
 import org.osgi.framework.Bundle;
-import org.osgi.framework.wiring.BundleCapability;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.framework.wiring.*;
+import org.osgi.framework.BundleContext;
 
+import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
+import static java.util.stream.Collectors.toSet;
+import static org.osgi.framework.Constants.SYSTEM_BUNDLE_LOCATION;
 import static org.osgi.framework.namespace.PackageNamespace.PACKAGE_NAMESPACE;
+import static org.osgi.framework.wiring.BundleRevision.HOST_NAMESPACE;
 import static org.osgi.framework.wiring.BundleRevision.TYPE_FRAGMENT;
 
 /**
@@ -84,4 +88,44 @@
         }
         return getExportedPackages(bundle);
     }
+
+    /**
+     * Get the host of the given fragment {@link Bundle}.
+     *
+     * @param fragment the <code>Bundle</code>.
+     * @return <code>Set</code> containing the host if the <code>bundle</code> was a fragment.
+     * @throws IllegalArgumentException if given bundle is not a fragment or <code>null</code>.
+     */
+    public static Set<Bundle> getHosts(Bundle fragment) {
+        if (!isFragmentBundle(fragment)) {
+            throw new IllegalArgumentException("Provided bundle is no fragment: " + fragment);
+        }
+        List<BundleWire> providedWires = fragment.adapt(BundleWiring.class).getProvidedWires(HOST_NAMESPACE);
+        return providedWires.stream().map(bundleWire -> bundleWire.getProviderWiring().getBundle())
+                .collect(toSet());
+    }
+
+    /**
+     * Get set of bundles with the given symbolic name.
+     *
+     * @param bundleContext the <code>BundleContext</code>.
+     * @param symbolicName the symbolic name.
+     * @return <code>Set</code> containing the bundles with the given symbolic name.
+     */
+    public static Set<Bundle> getBundlesBySymbolicName(BundleContext bundleContext, String symbolicName) {
+        return Arrays.stream(bundleContext.getBundles())
+                .filter(bundle -> symbolicName.equals(bundle.adapt(BundleRevision.class).getSymbolicName()))
+                .collect(toSet());
+    }
+
+    /**
+     * Refresh the given set of bundles.
+     *
+     * @param bundleContext the <code>BundleContext</code>.
+     * @param bundles to refresh.
+     */
+    public static void refreshBundles(BundleContext bundleContext, Set<Bundle> bundles) {
+        // Equinox regions could hide bundle ID 0
+        bundleContext.getBundle(SYSTEM_BUNDLE_LOCATION).adapt(FrameworkWiring.class).refreshBundles(bundles);
+    }
 }