001: /*******************************************************************************
002: * Copyright (c) 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.ui.search.dependencies;
011:
012: import java.util.HashMap;
013: import java.util.Set;
014:
015: import org.eclipse.osgi.service.resolver.BaseDescription;
016: import org.eclipse.osgi.service.resolver.BundleDescription;
017: import org.eclipse.osgi.service.resolver.BundleSpecification;
018: import org.eclipse.osgi.service.resolver.ExportPackageDescription;
019: import org.eclipse.osgi.service.resolver.HostSpecification;
020: import org.eclipse.osgi.service.resolver.ImportPackageSpecification;
021: import org.eclipse.pde.core.plugin.IPluginModelBase;
022: import org.eclipse.pde.core.plugin.PluginRegistry;
023: import org.osgi.framework.Constants;
024:
025: public class DependencyCalculator {
026:
027: boolean fIncludeOptional;
028: protected HashMap fDependencies;
029:
030: /*
031: * Object[] can be IPluginModelBases, BundleDescriptions, or Strings (id's of bundles)
032: */
033: public DependencyCalculator(boolean includeOptional) {
034: super ();
035: fIncludeOptional = includeOptional;
036: }
037:
038: public void findDependencies(Object[] includedBundles) {
039: if (fDependencies == null)
040: fDependencies = new HashMap();
041: for (int i = 0; i < includedBundles.length; i++) {
042: findObjectDependencies(includedBundles[i]);
043: }
044: }
045:
046: public void findDependency(Object bundle) {
047: if (fDependencies == null)
048: fDependencies = new HashMap();
049: findObjectDependencies(bundle);
050: }
051:
052: private void findObjectDependencies(Object obj) {
053: if (obj instanceof IPluginModelBase) {
054: IPluginModelBase base = ((IPluginModelBase) obj);
055: BundleDescription desc = base.getBundleDescription();
056: if (desc != null)
057: obj = desc;
058: }
059: if (obj instanceof BundleDescription)
060: findDependencies((BundleDescription) obj);
061: }
062:
063: /*
064: * Returns a Set of Bundle Ids
065: */
066: public Set getBundleIDs() {
067: Set temp = fDependencies.keySet();
068: fDependencies = null;
069: return temp;
070: }
071:
072: protected void findDependencies(BundleDescription desc) {
073: if (desc == null)
074: return;
075: String id = desc.getSymbolicName();
076: if (fDependencies.containsKey(id))
077: return;
078: IPluginModelBase model = PluginRegistry.findModel(desc);
079: if (model == null)
080: return;
081: fDependencies.put(id, model);
082:
083: addRequiredBundles(desc.getRequiredBundles());
084: addImportedPackages(desc.getImportPackages());
085:
086: HostSpecification host = desc.getHost();
087: if (host != null) {
088: // if current BundleDescription is a fragment, include host bundle
089: BaseDescription bd = host.getSupplier();
090: if (bd != null && bd instanceof BundleDescription)
091: findDependencies((BundleDescription) bd);
092: } else {
093: // otherwise, include applicable fragments for bundle
094: addFragments(desc);
095: }
096: }
097:
098: protected void addRequiredBundles(
099: BundleSpecification[] requiredBundles) {
100: for (int i = 0; i < requiredBundles.length; i++) {
101: if (requiredBundles[i].isOptional() && !fIncludeOptional)
102: continue;
103: BaseDescription bd = requiredBundles[i].getSupplier();
104: // only recursively search statisfied require-bundles
105: if (bd != null && bd instanceof BundleDescription)
106: findDependencies((BundleDescription) bd);
107: }
108: }
109:
110: protected void addImportedPackages(
111: ImportPackageSpecification[] packages) {
112: for (int i = 0; i < packages.length; i++) {
113: if (!fIncludeOptional)
114: if (Constants.RESOLUTION_OPTIONAL.equals(packages[i]
115: .getDirective(Constants.RESOLUTION_DIRECTIVE))) {
116: continue;
117: }
118: BaseDescription bd = packages[i].getSupplier();
119: // only recursively search statisfied import-packages
120: if (bd != null && bd instanceof ExportPackageDescription) {
121: BundleDescription exporter = ((ExportPackageDescription) bd)
122: .getExporter();
123: if (exporter != null)
124: findDependencies(exporter);
125: }
126: }
127: }
128:
129: protected void addFragments(BundleDescription desc) {
130: BundleDescription[] fragments = desc.getFragments();
131: for (int i = 0; i < fragments.length; i++)
132: if (fragments[i].isResolved()
133: && !fragments[i].getSymbolicName().equals(
134: "org.eclipse.ui.workbench.compatibility")) { //$NON-NLS-1$
135: findDependencies(fragments[i]);
136: }
137: }
138:
139: public boolean containsPluginId(String id) {
140: return fDependencies.containsKey(id);
141: }
142:
143: }
|