/******************************************************************************* * Copyright (c) 2008, 2010 VMware Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VMware Inc. - initial contribution *******************************************************************************/ package org.eclipse.virgo.kernel.model.internal.bundle; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import org.eclipse.equinox.region.RegionDigraph; import org.eclipse.virgo.kernel.model.Artifact; import org.eclipse.virgo.kernel.model.RuntimeArtifactRepository; import org.eclipse.virgo.kernel.model.internal.DependencyDeterminer; import org.eclipse.virgo.kernel.osgi.quasi.QuasiBundle; import org.eclipse.virgo.kernel.osgi.quasi.QuasiExportPackage; import org.eclipse.virgo.kernel.osgi.quasi.QuasiFramework; import org.eclipse.virgo.kernel.osgi.quasi.QuasiFrameworkFactory; import org.eclipse.virgo.kernel.osgi.quasi.QuasiImportPackage; import org.eclipse.virgo.kernel.osgi.quasi.QuasiRequiredBundle; import org.eclipse.virgo.nano.serviceability.NonNull; /** * Implementation of {@link DependencyDeterminer} that returns the dependents of a {@link org.osgi.framework.Bundle * Bundle}. The dependents consist of any bundle that has been wired to as a result of <code>Import-Package</code>. * <p /> * * <strong>Concurrent Semantics</strong><br /> * * Threadsafe * */ public final class BundleDependencyDeterminer implements DependencyDeterminer { private final QuasiFrameworkFactory quasiFrameworkFactory; private final RuntimeArtifactRepository artifactRepository; private final RegionDigraph regionDigraph; public BundleDependencyDeterminer(@NonNull QuasiFrameworkFactory quasiFrameworkFactory, @NonNull RuntimeArtifactRepository artifactRepository, @NonNull RegionDigraph regionDigraph) { this.quasiFrameworkFactory = quasiFrameworkFactory; this.artifactRepository = artifactRepository; this.regionDigraph = regionDigraph; } /** * {@inheritDoc} */ public Set<Artifact> getDependents(Artifact rootArtifact) { if (!rootArtifact.getType().equalsIgnoreCase("bundle")) { return Collections.<Artifact> emptySet(); } QuasiBundle rootBundle = getBundle(rootArtifact); if (rootBundle == null) { return Collections.<Artifact> emptySet(); } Set<Artifact> artifacts = new HashSet<Artifact>(); for (QuasiImportPackage importPackage : rootBundle.getImportPackages()) { QuasiExportPackage provider = importPackage.getProvider(); if (provider != null) { QuasiBundle bundle = provider.getExportingBundle(); addDependentBundle(artifacts, bundle); } } addDependents(artifacts, rootBundle.getHosts()); List<QuasiRequiredBundle> requiredBundles = rootBundle.getRequiredBundles(); if (requiredBundles != null) { for (QuasiRequiredBundle requiredBundle : requiredBundles) { addDependentBundle(artifacts, requiredBundle.getProvider()); } } return artifacts; } public void addDependents(Set<Artifact> artifacts, List<QuasiBundle> dependents) { if (dependents != null) { for (QuasiBundle dependent : dependents) { addDependentBundle(artifacts, dependent); } } } public void addDependentBundle(Set<Artifact> artifacts, QuasiBundle bundle) { if (bundle != null) { Artifact artifact = artifactRepository.getArtifact(NativeBundleArtifact.TYPE, bundle.getSymbolicName(), bundle.getVersion(), this.regionDigraph.getRegion(bundle.getBundleId())); artifacts.add(artifact); } } private QuasiBundle getBundle(Artifact artifact) { QuasiFramework framework = quasiFrameworkFactory.create(); for (QuasiBundle bundle : framework.getBundles()) { if (artifact.getName().equals(bundle.getSymbolicName()) && artifact.getVersion().equals(bundle.getVersion()) && artifact.getRegion().getName().equals(this.regionDigraph.getRegion(bundle.getBundleId()).getName())) { return bundle; } } return null; } }