blob: f75f51f2c8b3cbecdf2d3ca43d6dbcde820b449a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2007 IBM Corporation and others.
* 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.pde.internal.ui.views.dependencies;
import java.util.HashMap;
import org.eclipse.osgi.service.resolver.*;
import org.eclipse.pde.core.plugin.IPluginModelBase;
import org.osgi.framework.Constants;
public class CalleesContentProvider extends DependenciesViewPageContentProvider {
private BundleDescription fFragmentDescription;
public CalleesContentProvider(DependenciesView view) {
super(view);
}
protected Object[] findCallees(IPluginModelBase model) {
BundleDescription desc = model.getBundleDescription();
if (desc == null)
return new Object[0];
fFragmentDescription = null;
HostSpecification spec = desc.getHost();
if (spec != null) {
fFragmentDescription = desc;
Object[] fragmentDependencies = getDependencies(desc);
BaseDescription host = spec.getSupplier();
if (host instanceof BundleDescription) {
BundleDescription hostDesc = (BundleDescription) host;
// check to see if the host is already included as a dependency. If so, we don't need to include the host manually.
for (int i = 0; i < fragmentDependencies.length; i++) {
BundleDescription dependency = null;
if (fragmentDependencies[i] instanceof BundleSpecification)
dependency = ((BundleSpecification) fragmentDependencies[i]).getBundle();
else if (fragmentDependencies[i] instanceof ImportPackageSpecification) {
ExportPackageDescription epd = (ExportPackageDescription) ((ImportPackageSpecification) fragmentDependencies[i]).getSupplier();
if (epd != null)
dependency = epd.getSupplier();
}
if (dependency != null && dependency.equals(hostDesc))
return fragmentDependencies;
}
// host not included as dependency, include it manually.
Object[] result = new Object[fragmentDependencies.length + 1];
result[0] = hostDesc;
System.arraycopy(fragmentDependencies, 0, result, 1, fragmentDependencies.length);
return result;
}
return fragmentDependencies;
}
return getDependencies(desc);
}
protected Object[] findCallees(BundleDescription desc) {
if (desc == null)
return new Object[0];
return getDependencies(desc);
}
private Object[] getDependencies(BundleDescription desc) {
// use map to store dependencies so if Import-Package is supplied by same BundleDescription as supplier of Require-Bundle, it only shows up once
// Also, have to use BundleSpecficiation instead of BundleDescroption to show re-exported icon on re-exported Required-Bundles
// Have to use ImportPackageSpecification to determine if an import is optional and should be filtered.
HashMap dependencies = new HashMap();
BundleSpecification[] requiredBundles = desc.getRequiredBundles();
for (int i = 0; i < requiredBundles.length; i++) {
BaseDescription bd = requiredBundles[i].getSupplier();
if (bd != null)
dependencies.put(bd, requiredBundles[i]);
else
dependencies.put(requiredBundles[i], requiredBundles[i]);
}
ImportPackageSpecification[] importedPkgs = desc.getImportPackages();
for (int i = 0; i < importedPkgs.length; i++) {
BaseDescription bd = importedPkgs[i].getSupplier();
if (bd != null && bd instanceof ExportPackageDescription) {
BundleDescription exporter = ((ExportPackageDescription) bd).getExporter();
if (exporter != null) {
Object obj = dependencies.get(exporter);
if (obj == null) {
dependencies.put(exporter, importedPkgs[i]);
} else if (!Constants.RESOLUTION_OPTIONAL.equals(importedPkgs[i].getDirective(Constants.RESOLUTION_DIRECTIVE)) && obj instanceof ImportPackageSpecification && Constants.RESOLUTION_OPTIONAL.equals(((ImportPackageSpecification) obj).getDirective(Constants.RESOLUTION_DIRECTIVE))) {
// if we have a non-optional Import-Package dependency on a bundle which we already depend on, check to make sure our
// current dependency is not optional. If it is, replace the optional dependency with the non-optional one
dependencies.put(exporter, importedPkgs[i]);
}
}
}
// ignore unresolved packages
}
// include fragments which are "linked" to this bundle
BundleDescription frags[] = desc.getFragments();
for (int i = 0; i < frags.length; i++) {
if (!frags[i].equals(fFragmentDescription))
dependencies.put(frags[i], frags[i]);
}
return dependencies.values().toArray();
}
}