001: /*******************************************************************************
002: * Copyright (c) 2000, 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.wizards;
011:
012: import java.util.HashMap;
013: import java.util.HashSet;
014:
015: import org.eclipse.osgi.service.resolver.ExportPackageDescription;
016: import org.eclipse.osgi.service.resolver.VersionRange;
017: import org.eclipse.pde.core.plugin.IFragment;
018: import org.eclipse.pde.core.plugin.IFragmentModel;
019: import org.eclipse.pde.core.plugin.IPluginImport;
020: import org.eclipse.pde.core.plugin.IPluginModel;
021: import org.eclipse.pde.core.plugin.IPluginModelBase;
022: import org.eclipse.pde.core.plugin.PluginRegistry;
023: import org.eclipse.pde.internal.core.PDECore;
024: import org.eclipse.pde.internal.core.ibundle.IBundleModel;
025: import org.eclipse.pde.internal.core.ibundle.IBundlePluginModelBase;
026: import org.eclipse.pde.internal.core.text.bundle.ImportPackageHeader;
027: import org.eclipse.pde.internal.core.text.bundle.ImportPackageObject;
028: import org.eclipse.pde.internal.ui.PDEPlugin;
029: import org.eclipse.pde.internal.ui.PDEUIMessages;
030: import org.eclipse.swt.widgets.Shell;
031: import org.eclipse.ui.dialogs.ElementListSelectionDialog;
032: import org.osgi.framework.Constants;
033:
034: public class PluginSelectionDialog extends ElementListSelectionDialog {
035:
036: public PluginSelectionDialog(Shell parentShell,
037: boolean includeFragments, boolean multipleSelection) {
038: this (parentShell, getElements(includeFragments),
039: multipleSelection);
040: }
041:
042: public PluginSelectionDialog(Shell parentShell,
043: IPluginModelBase[] models, boolean multipleSelection) {
044: super (parentShell, PDEPlugin.getDefault().getLabelProvider());
045: setTitle(PDEUIMessages.PluginSelectionDialog_title);
046: setMessage(PDEUIMessages.PluginSelectionDialog_message);
047: setElements(models);
048: setMultipleSelection(multipleSelection);
049: PDEPlugin.getDefault().getLabelProvider().connect(this );
050: }
051:
052: public boolean close() {
053: PDEPlugin.getDefault().getLabelProvider().disconnect(this );
054: return super .close();
055: }
056:
057: private static IPluginModelBase[] getElements(
058: boolean includeFragments) {
059: return PluginRegistry.getActiveModels(includeFragments);
060: }
061:
062: public static HashSet getExistingImports(IPluginModelBase model,
063: boolean includeImportPkg) {
064: HashSet existingImports = new HashSet();
065: addSelfAndDirectImports(existingImports, model);
066: if (model instanceof IFragmentModel) {
067: IFragment fragment = ((IFragmentModel) model).getFragment();
068: IPluginModelBase host = PluginRegistry.findModel(fragment
069: .getPluginId());
070: if (host instanceof IPluginModel) {
071: addSelfAndDirectImports(existingImports, host);
072: }
073: }
074: if (includeImportPkg && model instanceof IBundlePluginModelBase) {
075: addImportedPackages((IBundlePluginModelBase) model,
076: existingImports);
077: }
078: return existingImports;
079: }
080:
081: private static void addSelfAndDirectImports(HashSet set,
082: IPluginModelBase model) {
083: set.add(model.getPluginBase().getId());
084: IPluginImport[] imports = model.getPluginBase().getImports();
085: for (int i = 0; i < imports.length; i++) {
086: String id = imports[i].getId();
087: if (set.add(id)) {
088: addReexportedImport(set, id);
089: }
090: }
091: }
092:
093: private static void addReexportedImport(HashSet set, String id) {
094: IPluginModelBase model = PluginRegistry.findModel(id);
095: if (model != null) {
096: IPluginImport[] imports = model.getPluginBase()
097: .getImports();
098: for (int i = 0; i < imports.length; i++) {
099: if (imports[i].isReexported()
100: && set.add(imports[i].getId())) {
101: addReexportedImport(set, imports[i].getId());
102: }
103: }
104: }
105: }
106:
107: private static void addImportedPackages(
108: IBundlePluginModelBase base, HashSet existingImports) {
109: HashMap map = getImportPackages(base);
110: if (map == null)
111: return;
112:
113: ExportPackageDescription exported[] = PDECore.getDefault()
114: .getModelManager().getState().getState()
115: .getExportedPackages();
116: for (int i = 0; i < exported.length; i++) {
117: // iterate through all the exported packages
118: ImportPackageObject ipo = (ImportPackageObject) map
119: .get(exported[i].getName());
120: // if we find an exported package that matches a pkg in the map, then the exported package matches a package on our import-package statement
121: if (ipo != null) {
122: // check version to make sure we only add bundles from valid packages
123: String version = ipo.getVersion();
124: if (version != null)
125: try {
126: if (!new VersionRange(version)
127: .isIncluded(exported[i].getVersion()))
128: continue;
129: // NFE if ImportPackageObject's version is improperly formatted - ignore any matching imported packages since version is invalid
130: } catch (NumberFormatException e) {
131: continue;
132: }
133: existingImports.add(exported[i].getSupplier()
134: .getSymbolicName());
135: }
136: }
137: }
138:
139: // returns null instead of empty map so we know not to iterate through exported packages
140: private static HashMap getImportPackages(IBundlePluginModelBase base) {
141: IBundleModel bmodel = base.getBundleModel();
142: if (bmodel != null) {
143: ImportPackageHeader header = (ImportPackageHeader) bmodel
144: .getBundle().getManifestHeader(
145: Constants.IMPORT_PACKAGE);
146: if (header != null) {
147: // create a map of all the packages we import
148: HashMap map = new HashMap();
149: ImportPackageObject[] packages = header.getPackages();
150: for (int i = 0; i < packages.length; i++)
151: map.put(packages[i].getName(), packages[i]);
152: return map;
153: }
154: }
155: return null;
156: }
157: }
|