From 24bf22274a62fa2b11318d82bad1d215a4725986 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Tue, 12 Feb 2008 16:20:17 +0000 Subject: Bug 217724 Substitutable exports and require-bundle --- .../osgi/internal/module/GroupingChecker.java | 21 +++-- .../osgi/internal/module/ResolverBundle.java | 36 +++++-- .../osgi/internal/module/ResolverConstraint.java | 4 +- .../eclipse/osgi/internal/module/ResolverImpl.java | 103 +++++---------------- .../osgi/internal/module/VersionHashMap.java | 13 --- .../osgi/internal/module/VersionSupplier.java | 14 +-- .../internal/resolver/BundleDescriptionImpl.java | 14 ++- .../resolver/ExportPackageDescriptionImpl.java | 12 +-- .../osgi/internal/resolver/ReadOnlyState.java | 11 ++- .../osgi/internal/resolver/StateBuilder.java | 26 ++---- .../osgi/internal/resolver/StateHelperImpl.java | 15 ++- .../eclipse/osgi/internal/resolver/StateImpl.java | 48 ++++++++-- .../internal/resolver/StateMessages.properties | 1 - .../eclipse/osgi/internal/resolver/StateMsg.java | 1 - .../internal/resolver/StateObjectFactoryImpl.java | 3 +- .../osgi/internal/resolver/StateReader.java | 13 ++- .../osgi/internal/resolver/StateWriter.java | 12 ++- 17 files changed, 174 insertions(+), 173 deletions(-) (limited to 'bundles/org.eclipse.osgi/resolver') diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/GroupingChecker.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/GroupingChecker.java index e8a6abb16..a0522d09f 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/GroupingChecker.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/GroupingChecker.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2007 IBM Corporation and others. All rights reserved. + * Copyright (c) 2004, 2008 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 @@ -61,9 +61,10 @@ public class GroupingChecker { // check that the packages exported by the matching bundle are consistent ResolverExport[] matchingExports = matchingBundle.getExportPackages(); for (int i = 0; i < matchingExports.length; i++) { - if (matchingExports[i].isDropped()) - continue; - results = isConsistentInternal(requiringBundle, matchingExports[i], dynamicImport, results); + ResolverExport matchingExport = matchingExports[i]; + if (matchingExports[i].getSubstitute() != null) + matchingExport = (ResolverExport) matchingExports[i].getSubstitute(); + results = isConsistentInternal(requiringBundle, matchingExport, dynamicImport, results); } // check that the packages from reexported bundles are consistent BundleConstraint[] supplierRequires = matchingBundle.getRequires(); @@ -266,24 +267,24 @@ public class GroupingChecker { public ArrayList isConsistentClassSpace(ResolverBundle importingBundle, ArrayList visited, ArrayList results) { if (roots == null) return results; + if (visited == null) + visited = new ArrayList(1); + if (visited.contains(this)) + return results; + visited.add(this); int size = roots.length; for (int i = 0; i < size; i++) { ResolverExport root = roots[i]; String[] uses = root.getUsesDirective(); if (uses == null) continue; - if (visited == null) - visited = new ArrayList(1); - if (visited.contains(this)) - return results; - visited.add(this); for (int j = 0; j < uses.length; j++) { if (uses[j].equals(root.getName())) continue; PackageRoots thisUsedRoots = getPackageRoots(root.getExporter(), uses[j], null); PackageRoots importingUsedRoots = getPackageRoots(importingBundle, uses[j], null); if (thisUsedRoots == importingUsedRoots) - return results; + continue; if (thisUsedRoots != nullPackageRoots && importingUsedRoots != nullPackageRoots) if (!(subSet(thisUsedRoots.roots, importingUsedRoots.roots) || subSet(importingUsedRoots.roots, thisUsedRoots.roots))) { if (results == null) diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverBundle.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverBundle.java index 0b3968e45..977f2ffa1 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverBundle.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverBundle.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2007 IBM Corporation and others. + * Copyright (c) 2004, 2008 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 @@ -131,6 +131,10 @@ public class ResolverBundle extends VersionSupplier implements Comparable { GenericConstraint[] allGenericRequires = getGenericRequires(); for (int i = 0; i < allGenericRequires.length; i++) allGenericRequires[i].setMatchingCapability(null); + + ResolverExport[] allExports = getExportPackages(); + for (int i = 0; i < allExports.length; i++) + allExports[i].setSubstitute(null); } boolean isResolved() { @@ -184,19 +188,27 @@ public class ResolverBundle extends VersionSupplier implements Comparable { } ResolverExport[] getSelectedExports() { - ResolverExport[] allExports = getExportPackages(); + return getExports(true); + } + + ResolverExport[] getSubstitutedExports() { + return getExports(false); + } + + private ResolverExport[] getExports(boolean selected) { + ResolverExport[] results = getExportPackages(); int removedExports = 0; - for (int i = 0; i < allExports.length; i++) - if (allExports[i].isDropped()) + for (int i = 0; i < results.length; i++) + if (selected ? results[i].getSubstitute() != null : results[i].getSubstitute() == null) removedExports++; if (removedExports == 0) - return allExports; - ResolverExport[] selectedExports = new ResolverExport[allExports.length - removedExports]; + return results; + ResolverExport[] selectedExports = new ResolverExport[results.length - removedExports]; int index = 0; - for (int i = 0; i < allExports.length; i++) { - if (allExports[i].isDropped()) + for (int i = 0; i < results.length; i++) { + if (selected ? results[i].getSubstitute() != null : results[i].getSubstitute() == null) continue; - selectedExports[index] = allExports[i]; + selectedExports[index] = results[i]; index++; } return selectedExports; @@ -490,7 +502,11 @@ public class ResolverBundle extends VersionSupplier implements Comparable { } } } - return removedExports == null ? new ResolverExport[0] : (ResolverExport[]) removedExports.toArray(new ResolverExport[removedExports.size()]); + ResolverExport[] results = removedExports == null ? new ResolverExport[0] : (ResolverExport[]) removedExports.toArray(new ResolverExport[removedExports.size()]); + for (int i = 0; i < results.length; i++) + // TODO this is a hack; need to figure out how to indicate that a fragment export is no longer attached + results[i].setSubstitute(results[i]); + return results; } private boolean hasUnresolvedConstraint(ResolverConstraint reason, ResolverBundle detachedFragment, ResolverBundle remainingFragment, ResolverImport[] oldImports, BundleConstraint[] oldRequires, ArrayList additionalImports, ArrayList additionalRequires) { diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverConstraint.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverConstraint.java index d50635357..49713ee0f 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverConstraint.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverConstraint.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. All rights reserved. This + * Copyright (c) 2005, 2008 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 @@ -44,7 +44,7 @@ public abstract class ResolverConstraint { boolean isSatisfiedBy(VersionSupplier vs) { if (!bundle.getResolver().getPermissionChecker().checkPermission(constraint, vs.getBaseDescription())) return false; - return !vs.getResolverBundle().isUninstalled() && constraint.isSatisfiedBy(vs.getBaseDescription()); + return vs.getSubstitute() == null && !vs.getResolverBundle().isUninstalled() && constraint.isSatisfiedBy(vs.getBaseDescription()); } // returns the companion VersionConstraint object from the State diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java index a8384c7ec..61d541260 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java @@ -211,15 +211,6 @@ public class ResolverImpl implements org.eclipse.osgi.service.resolver.Resolver } } imp.addPossibleSupplier(matchingExport); - // Check if we wired to a reprovided package (in which case the ResolverExport doesn't exist) - if (matchingExport == null && exporter != null) { - ResolverExport reprovidedExport = new ResolverExport(exporter, importSupplier); - if (exporter.getExport(imp.getName()) == null) { - exporter.addExport(reprovidedExport); - resolverExports.put(reprovidedExport.getName(), reprovidedExport); - } - imp.addPossibleSupplier(reprovidedExport); - } // If we still have a null wire and it's not optional, then we have an error if (imp.getSelectedSupplier() == null && !imp.isOptional()) { System.err.println("Could not find matching export for " + imp.getVersionConstraint()); //$NON-NLS-1$ @@ -483,7 +474,7 @@ public class ResolverImpl implements org.eclipse.osgi.service.resolver.Resolver resolvedOptional = true; } if (resolvedOptional) { - state.resolveBundle(bundle.getBundle(), false, null, null, null, null); + state.resolveBundle(bundle.getBundle(), false, null, null, null, null, null); stateResolveConstraints(bundle); stateResolveBundle(bundle); } @@ -917,7 +908,7 @@ public class ResolverImpl implements org.eclipse.osgi.service.resolver.Resolver // check for dropped exports while (imports[j].getSelectedSupplier() != null) { ResolverExport importSupplier = (ResolverExport) imports[j].getSelectedSupplier(); - if (importSupplier.isDropped()) + if (importSupplier.getSubstitute() != null) imports[j].selectNextSupplier(); else break; @@ -1273,8 +1264,6 @@ public class ResolverImpl implements org.eclipse.osgi.service.resolver.Resolver int originalState = export.getExporter().getState(); if (imp.isDynamic() && originalState != ResolverBundle.RESOLVED) continue; // Must not attempt to resolve an exporter when dynamic - if (imp.getBundle() == export.getExporter() && !export.getExportPackageDescription().isRoot()) - continue; // Can't wire to our own re-export if (imp.getSelectedSupplier() != null && ((ResolverExport) imp.getSelectedSupplier()).getExporter() == imp.getBundle()) break; // We wired to ourselves; nobody else matters export.getExporter().addRef(imp.getBundle()); @@ -1284,22 +1273,21 @@ public class ResolverImpl implements org.eclipse.osgi.service.resolver.Resolver if (imp.getBundle() != export.getExporter()) { // Save the exports of this package from the importer in case we need to add them back importerExps = imp.getBundle().getExports(imp.getName()); - for (int j = 0; j < importerExps.length; j++) { - if (importerExps[j].getExportPackageDescription().isRoot() && !export.getExportPackageDescription().isRoot()) - continue exportsloop; // to prevent imports from getting wired to re-exports if we offer a root export - if (importerExps[j].getExportPackageDescription().isRoot()) // do not drop reexports when import wins - resolverExports.remove(importerExps[j]); // Import wins, remove export - } + for (int j = 0; j < importerExps.length; j++) + if (importerExps[j].getSubstitute() == null) + importerExps[j].setSubstitute(export); // Import wins, drop export // if in dev mode then allow a constraint to resolve to an unresolved bundle - if ((originalState != ResolverBundle.RESOLVED && !resolveBundle(export.getExporter(), cycle) && !developmentMode) || export.isDropped()) { + if ((originalState != ResolverBundle.RESOLVED && !resolveBundle(export.getExporter(), cycle) && !developmentMode) || export.getSubstitute() != null) { // remove the possible supplier imp.removePossibleSupplier(export); // add back the exports of this package from the importer - for (int j = 0; j < importerExps.length; j++) - resolverExports.put(importerExps[j].getName(), importerExps[j]); + if (imp.getSelectedSupplier() == null) + for (int j = 0; j < importerExps.length; j++) + if (importerExps[j].getSubstitute() == export) + importerExps[j].setSubstitute(null); continue; // Bundle hasn't resolved || export has not been selected and is unavailable } - } else if (export.isDropped()) + } else if (export.getSubstitute() != null) continue; // we already found a possible import that satisifies us; our export is dropped // Record any cyclic dependencies @@ -1320,66 +1308,11 @@ public class ResolverImpl implements org.eclipse.osgi.service.resolver.Resolver if (result) return true; - if (resolveImportReprovide(imp, cycle)) - return true; if (imp.isOptional()) return true; // If the import is optional then just return true return false; } - // Check if the import can be resolved to a re-exported package (has no export object to match to) - private boolean resolveImportReprovide(ResolverImport imp, ArrayList cycle) { - String bsn = ((ImportPackageSpecification) imp.getVersionConstraint()).getBundleSymbolicName(); - // If no symbolic name specified then just return (since this is a - // re-export an import not specifying a bsn will wire to the root) - if (bsn == null) - return false; - if (DEBUG_IMPORTS) - ResolverImpl.log("Checking reprovides: " + imp.getName()); //$NON-NLS-1$ - // Find bundle with specified bsn - Object[] bundles = resolverBundles.get(bsn); - for (int i = 0; i < bundles.length; i++) - if (resolveBundle((ResolverBundle) bundles[i], cycle)) - if (resolveImportReprovide0(imp, (ResolverBundle) bundles[i], (ResolverBundle) bundles[i], cycle, new ArrayList(5))) - return true; - return false; - } - - private boolean resolveImportReprovide0(ResolverImport imp, ResolverBundle reexporter, ResolverBundle rb, ArrayList cycle, ArrayList visited) { - if (visited.contains(rb)) - return false; // make sure we don't endless recurse cycles - visited.add(rb); - BundleConstraint[] requires = rb.getRequires(); - for (int i = 0; i < requires.length; i++) { - if (!((BundleSpecification) requires[i].getVersionConstraint()).isExported()) - continue; // Skip require if it doesn't re-export the packages - // Check exports to see if we've found the root - if (requires[i].getSelectedSupplier() == null) - continue; - ResolverExport[] exports = ((ResolverBundle) requires[i].getSelectedSupplier()).getExports(imp.getName()); - for (int j = 0; j < exports.length; j++) { - Map directives = exports[j].getExportPackageDescription().getDirectives(); - directives.remove(Constants.USES_DIRECTIVE); - ExportPackageDescription epd = state.getFactory().createExportPackageDescription(exports[j].getName(), exports[j].getVersion(), directives, exports[j].getExportPackageDescription().getAttributes(), false, reexporter.getBundle()); - if (imp.getVersionConstraint().isSatisfiedBy(epd)) { - // Create reexport and add to bundle and resolverExports - if (DEBUG_IMPORTS) - ResolverImpl.log(" - Creating re-export for reprovide: " + reexporter + ":" + epd.getName()); //$NON-NLS-1$ //$NON-NLS-2$ - ResolverExport re = new ResolverExport(reexporter, epd); - reexporter.addExport(re); - resolverExports.put(re.getName(), re); - // Resolve import - imp.addPossibleSupplier(re); - return true; - } - } - // Check requires of matching bundle (recurse down the chain) - if (resolveImportReprovide0(imp, reexporter, (ResolverBundle) requires[i].getSelectedSupplier(), cycle, visited)) - return true; - } - return false; - } - // Move a bundle to UNRESOLVED private void setBundleUnresolved(ResolverBundle bundle, boolean removed, boolean keepFragsAttached) { if (bundle.getState() == ResolverBundle.UNRESOLVED && !developmentMode) @@ -1487,6 +1420,14 @@ public class ResolverImpl implements org.eclipse.osgi.service.resolver.Resolver } ExportPackageDescription[] selectedExportsArray = (ExportPackageDescription[]) selectedExports.toArray(new ExportPackageDescription[selectedExports.size()]); + // Gather substitute exports + ResolverExport[] substituted = rb.getSubstitutedExports(); + ArrayList substitutedExports = new ArrayList(substituted.length); + for (int i = 0; i < substituted.length; i++) { + substitutedExports.add(substituted[i].getExportPackageDescription()); + } + ExportPackageDescription[] substitutedExportsArray = (ExportPackageDescription[]) substitutedExports.toArray(new ExportPackageDescription[substitutedExports.size()]); + // Gather exports that have been wired to ResolverImport[] imports = rb.getImportPackages(); ArrayList exportsWiredTo = new ArrayList(imports.length); @@ -1516,14 +1457,14 @@ public class ResolverImpl implements org.eclipse.osgi.service.resolver.Resolver ExportPackageDescription[] hostExportsArray = new ExportPackageDescription[hostExports.length]; for (int j = 0; j < hostExports.length; j++) hostExportsArray[j] = hostExports[j].getExportPackageDescription(); - state.resolveBundle(hostBundles[i], true, null, hostExportsArray, hostBundles[i].getResolvedRequires(), hostBundles[i].getResolvedImports()); + state.resolveBundle(hostBundles[i], true, null, hostExportsArray, hostBundles[i].getSubstitutedExports(), hostBundles[i].getResolvedRequires(), hostBundles[i].getResolvedImports()); } } } } // Resolve the bundle in the state - state.resolveBundle(rb.getBundle(), rb.isResolved(), hostBundles, selectedExportsArray, bundlesWiredToArray, exportsWiredToArray); + state.resolveBundle(rb.getBundle(), rb.isResolved(), hostBundles, selectedExportsArray, substitutedExportsArray, bundlesWiredToArray, exportsWiredToArray); } // Resolve dynamic import @@ -1675,7 +1616,7 @@ public class ResolverImpl implements org.eclipse.osgi.service.resolver.Resolver setBundleUnresolved(bundle, removed, false); // Get bundles dependent on 'bundle' BundleDescription[] dependents = bundle.getBundle().getDependents(); - state.resolveBundle(bundle.getBundle(), false, null, null, null, null); + state.resolveBundle(bundle.getBundle(), false, null, null, null, null, null); // Unresolve dependents of 'bundle' for (int i = 0; i < dependents.length; i++) unresolveBundle((ResolverBundle) bundleMapping.get(dependents[i]), false); diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/VersionHashMap.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/VersionHashMap.java index a94f9ab2a..142461eb2 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/VersionHashMap.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/VersionHashMap.java @@ -30,11 +30,6 @@ public class VersionHashMap extends MappedList implements Comparator { put(versionSuppliers[i].getName(), versionSuppliers[i]); } - public void put(Object key, Object value) { - super.put(key, value); - ((VersionSupplier) value).setDropped(false); - } - public boolean contains(VersionSupplier vs) { return contains(vs, false) != null; } @@ -46,7 +41,6 @@ public class VersionHashMap extends MappedList implements Comparator { for (int i = 0; i < existing.length; i++) if (existing[i] == vs) { if (remove) { - vs.setDropped(true); if (existing.length == 1) { internal.remove(vs.getName()); return vs; @@ -71,13 +65,6 @@ public class VersionHashMap extends MappedList implements Comparator { remove(versionSuppliers[i]); } - public Object[] remove(Object key) { - Object[] results = super.remove(key); - for (int i = 0; i < results.length; i++) - ((VersionSupplier) results[i]).setDropped(true); - return results; - } - // Once we have resolved bundles, we need to make sure that version suppliers // from the resolved bundles are ahead of those from unresolved bundles void reorder() { diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/VersionSupplier.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/VersionSupplier.java index 777afdb86..d4c8a2ed8 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/VersionSupplier.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/VersionSupplier.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2007 IBM Corporation and others. + * Copyright (c) 2004, 2008 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 @@ -18,8 +18,8 @@ import org.osgi.framework.Version; * A companion to BaseDescription from the state used while resolving. */ public abstract class VersionSupplier { - BaseDescription base; - boolean dropped = false; + protected BaseDescription base; + private VersionSupplier substitute; VersionSupplier(BaseDescription base) { this.base = base; @@ -38,14 +38,14 @@ public abstract class VersionSupplier { } // returns true if this version supplier has been dropped and is no longer available as a wire - boolean isDropped() { - return dropped; + VersionSupplier getSubstitute() { + return substitute; } // sets the dropped status. This should only be called by the VersionHashMap // when VersionSuppliers are removed - void setDropped(boolean dropped) { - this.dropped = dropped; + void setSubstitute(VersionSupplier substitute) { + this.substitute = substitute; } /* diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleDescriptionImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleDescriptionImpl.java index 4b89dabb7..41a0dc94f 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleDescriptionImpl.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleDescriptionImpl.java @@ -172,6 +172,13 @@ public class BundleDescriptionImpl extends BaseDescriptionImpl implements Bundle return lazyData.selectedExports; } + public ExportPackageDescription[] getSubstitutedExports() { + fullyLoad(); + if (lazyData.substitutedExports == null) + return EMPTY_EXPORTS; + return lazyData.substitutedExports; + } + public BundleDescription[] getResolvedRequires() { fullyLoad(); if (lazyData.resolvedRequires == null) @@ -317,6 +324,11 @@ public class BundleDescriptionImpl extends BaseDescriptionImpl implements Bundle } } + protected void setSubstitutedExports(ExportPackageDescription[] substitutedExports) { + checkLazyData(); + lazyData.substitutedExports = substitutedExports; + } + protected void setResolvedImports(ExportPackageDescription[] resolvedImports) { checkLazyData(); lazyData.resolvedImports = resolvedImports; @@ -570,7 +582,7 @@ public class BundleDescriptionImpl extends BaseDescriptionImpl implements Bundle ExportPackageDescription[] selectedExports; BundleDescription[] resolvedRequires; ExportPackageDescription[] resolvedImports; - + ExportPackageDescription[] substitutedExports; String[] executionEnvironments; HashMap dynamicStamps; diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ExportPackageDescriptionImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ExportPackageDescriptionImpl.java index 76c6ee821..d7f98fd6a 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ExportPackageDescriptionImpl.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ExportPackageDescriptionImpl.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2006 IBM Corporation and others. + * Copyright (c) 2004, 2008 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 @@ -11,7 +11,8 @@ package org.eclipse.osgi.internal.resolver; -import java.util.*; +import java.util.HashMap; +import java.util.Map; import org.eclipse.osgi.framework.internal.core.Constants; import org.eclipse.osgi.service.resolver.BundleDescription; import org.eclipse.osgi.service.resolver.ExportPackageDescription; @@ -28,7 +29,6 @@ public class ExportPackageDescriptionImpl extends BaseDescriptionImpl implements private String[] mandatory; private Boolean internal = Boolean.FALSE; private int equinox_ee = -1; - private boolean root; private int tableIndex; public Map getDirectives() { @@ -111,7 +111,7 @@ public class ExportPackageDescriptionImpl extends BaseDescriptionImpl implements } public boolean isRoot() { - return root; + return true; } protected void setAttributes(Map attributes) { @@ -122,10 +122,6 @@ public class ExportPackageDescriptionImpl extends BaseDescriptionImpl implements this.exporter = exporter; } - protected void setRoot(boolean root) { - this.root = root; - } - public String toString() { return "Export-Package: " + getName() + "; version=\"" + getVersion() + "\""; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ } diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ReadOnlyState.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ReadOnlyState.java index 5b39faadc..c06c8320f 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ReadOnlyState.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ReadOnlyState.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2007 IBM Corporation and others. + * Copyright (c) 2004, 2008 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 @@ -111,7 +111,14 @@ public class ReadOnlyState implements State { throw new UnsupportedOperationException(); } - public void resolveBundle(BundleDescription bundle, boolean status, BundleDescription[] host, ExportPackageDescription[] selectedExports, BundleDescription[] resolvedRequires, ExportPackageDescription[] resolveImports) { + /** + * @deprecated + */ + public void resolveBundle(BundleDescription bundle, boolean status, BundleDescription[] hosts, ExportPackageDescription[] selectedExports, BundleDescription[] resolvedRequires, ExportPackageDescription[] resolvedImports) { + throw new UnsupportedOperationException(); + } + + public void resolveBundle(BundleDescription bundle, boolean status, BundleDescription[] host, ExportPackageDescription[] selectedExports, ExportPackageDescription[] substitutedExports, BundleDescription[] resolvedRequires, ExportPackageDescription[] resolveImports) { throw new UnsupportedOperationException(); } diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateBuilder.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateBuilder.java index 1202922ee..1047f3b20 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateBuilder.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateBuilder.java @@ -24,7 +24,7 @@ import org.osgi.framework.*; */ class StateBuilder { static final String[] DEFINED_MATCHING_ATTRS = {Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE, Constants.BUNDLE_VERSION_ATTRIBUTE, Constants.PACKAGE_SPECIFICATION_VERSION, Constants.VERSION_ATTRIBUTE}; - static final String[] DEFINED_OSGI_VALIDATE_HEADERS = {Constants.IMPORT_PACKAGE, Constants.DYNAMICIMPORT_PACKAGE, Constants.EXPORT_PACKAGE, Constants.FRAGMENT_HOST, Constants.BUNDLE_SYMBOLICNAME, Constants.REEXPORT_PACKAGE, Constants.REQUIRE_BUNDLE}; + static final String[] DEFINED_OSGI_VALIDATE_HEADERS = {Constants.IMPORT_PACKAGE, Constants.DYNAMICIMPORT_PACKAGE, Constants.EXPORT_PACKAGE, Constants.FRAGMENT_HOST, Constants.BUNDLE_SYMBOLICNAME, Constants.REQUIRE_BUNDLE}; static final String GENERIC_REQUIRE = "Eclipse-GenericRequire"; //$NON-NLS-1$ static final String GENERIC_CAPABILITY = "Eclipse-GenericCapability"; //$NON-NLS-1$ @@ -87,11 +87,10 @@ class StateBuilder { if (host != null) result.setHost(createHostSpecification(host[0])); ManifestElement[] exports = ManifestElement.parseHeader(Constants.EXPORT_PACKAGE, (String) manifest.get(Constants.EXPORT_PACKAGE)); - ManifestElement[] reexports = ManifestElement.parseHeader(Constants.REEXPORT_PACKAGE, (String) manifest.get(Constants.REEXPORT_PACKAGE)); ManifestElement[] provides = ManifestElement.parseHeader(Constants.PROVIDE_PACKAGE, (String) manifest.get(Constants.PROVIDE_PACKAGE)); // TODO this is null for now until the framwork is updated to handle the new re-export semantics boolean strict = state != null && state.inStrictMode(); ArrayList providedExports = new ArrayList(provides == null ? 0 : provides.length); - result.setExportPackages(createExportPackages(exports, reexports, provides, providedExports, manifestVersion, strict)); + result.setExportPackages(createExportPackages(exports, provides, providedExports, manifestVersion, strict)); ManifestElement[] imports = ManifestElement.parseHeader(Constants.IMPORT_PACKAGE, (String) manifest.get(Constants.IMPORT_PACKAGE)); ManifestElement[] dynamicImports = ManifestElement.parseHeader(Constants.DYNAMICIMPORT_PACKAGE, (String) manifest.get(Constants.DYNAMICIMPORT_PACKAGE)); result.setImportPackages(createImportPackages(result.getExportPackages(), providedExports, imports, dynamicImports, manifestVersion)); @@ -182,8 +181,6 @@ class StateBuilder { if (header != null) { ManifestElement[] elements = ManifestElement.parseHeader(DEFINED_OSGI_VALIDATE_HEADERS[i], header); checkForDuplicateDirectives(elements); - if (DEFINED_OSGI_VALIDATE_HEADERS[i] == Constants.REEXPORT_PACKAGE) - checkForUsesDirective(elements); if (DEFINED_OSGI_VALIDATE_HEADERS[i] == Constants.IMPORT_PACKAGE) checkImportExportSyntax(elements, false, false, jreBundle); if (DEFINED_OSGI_VALIDATE_HEADERS[i] == Constants.DYNAMICIMPORT_PACKAGE) @@ -287,23 +284,20 @@ class StateBuilder { return result; } - static ExportPackageDescription[] createExportPackages(ManifestElement[] exported, ManifestElement[] reexported, ManifestElement[] provides, ArrayList providedExports, int manifestVersion, boolean strict) throws BundleException { - int numExports = (exported == null ? 0 : exported.length) + (reexported == null ? 0 : reexported.length) + (provides == null ? 0 : provides.length); + static ExportPackageDescription[] createExportPackages(ManifestElement[] exported, ManifestElement[] provides, ArrayList providedExports, int manifestVersion, boolean strict) throws BundleException { + int numExports = (exported == null ? 0 : exported.length) + (provides == null ? 0 : provides.length); if (numExports == 0) return null; ArrayList allExports = new ArrayList(numExports); if (exported != null) for (int i = 0; i < exported.length; i++) - addExportPackages(exported[i], allExports, manifestVersion, false, strict); - if (reexported != null) - for (int i = 0; i < reexported.length; i++) - addExportPackages(reexported[i], allExports, manifestVersion, true, strict); + addExportPackages(exported[i], allExports, manifestVersion, strict); if (provides != null) addProvidePackages(provides, allExports, providedExports); return (ExportPackageDescription[]) allExports.toArray(new ExportPackageDescription[allExports.size()]); } - private static void addExportPackages(ManifestElement exportPackage, ArrayList allExports, int manifestVersion, boolean reexported, boolean strict) throws BundleException { + private static void addExportPackages(ManifestElement exportPackage, ArrayList allExports, int manifestVersion, boolean strict) throws BundleException { String[] exportNames = exportPackage.getValueComponents(); for (int i = 0; i < exportNames.length; i++) { // if we are in strict mode and the package is marked as internal, skip it. @@ -323,7 +317,6 @@ class StateBuilder { result.setDirective(Constants.INTERNAL_DIRECTIVE, Boolean.valueOf(exportPackage.getDirective(Constants.INTERNAL_DIRECTIVE))); result.setDirective(Constants.MANDATORY_DIRECTIVE, ManifestElement.getArrayFromList(exportPackage.getDirective(Constants.MANDATORY_DIRECTIVE))); result.setAttributes(getAttributes(exportPackage, DEFINED_MATCHING_ATTRS)); - result.setRoot(!reexported); allExports.add(result); } } @@ -340,7 +333,6 @@ class StateBuilder { if (!duplicate) { ExportPackageDescriptionImpl result = new ExportPackageDescriptionImpl(); result.setName(provides[i].getValue()); - result.setRoot(true); allExports.add(result); } providedExports.add(provides[i].getValue()); @@ -577,12 +569,6 @@ class StateBuilder { } } - private static void checkForUsesDirective(ManifestElement[] elements) throws BundleException { - for (int i = 0; i < elements.length; i++) - if (elements[i].getDirective(Constants.USES_DIRECTIVE) != null) - throw new BundleException(NLS.bind(StateMsg.HEADER_REEXPORT_USES, Constants.USES_DIRECTIVE, Constants.REEXPORT_PACKAGE)); - } - private static void checkExtensionBundle(ManifestElement[] elements) throws BundleException { if (elements.length == 0 || elements[0].getDirective(Constants.EXTENSION_DIRECTIVE) == null) return; diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateHelperImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateHelperImpl.java index 39a18343b..53aea0764 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateHelperImpl.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateHelperImpl.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2006 IBM Corporation and others. + * Copyright (c) 2004, 2008 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 @@ -282,6 +282,7 @@ public class StateHelperImpl implements StateHelper { boolean strict = false; if (state != null) strict = state.inStrictMode(); + BundleDescription host = (BundleDescription) (bundle.getHost() == null ? bundle : bundle.getHost().getSupplier()); ArrayList orderedPkgList = new ArrayList(); // list of all ExportPackageDescriptions that are visible (ArrayList is used to keep order) Set pkgSet = new HashSet(); Set importList = new HashSet(); // list of package names which are directly imported @@ -289,7 +290,7 @@ public class StateHelperImpl implements StateHelper { ImportPackageSpecification[] imports = bundle.getImportPackages(); for (int i = 0; i < imports.length; i++) { ExportPackageDescription pkgSupplier = (ExportPackageDescription) imports[i].getSupplier(); - if (pkgSupplier == null) + if (pkgSupplier == null || pkgSupplier.getExporter() == host) // do not return the bundle'sr own imports continue; if (!isSystemExport(pkgSupplier, options) && !pkgSet.contains(pkgSupplier)) { orderedPkgList.add(pkgSupplier); @@ -325,6 +326,16 @@ public class StateHelperImpl implements StateHelper { return; // prevent duplicate entries and infinate loops incase of cycles visited.add(requiredBundle); // add all the exported packages from the required bundle; take x-friends into account. + ExportPackageDescription[] substitutedExports = requiredBundle.getSubstitutedExports(); + for (int i = 0; i < substitutedExports.length; i++) { + ExportPackageDescription[] imports = requiredBundle.getResolvedImports(); + for (int j = 0; j < imports.length; j++) { + if (substitutedExports[i].getName().equals(imports[j].getName()) && !pkgSet.contains(imports[j])) { + getPackages(imports[j].getSupplier(), symbolicName, importList, orderedPkgList, pkgSet, visited, strict, pkgNames, options); + return; // should not continue to local exports or required bundles + } + } + } ExportPackageDescription[] exports = requiredBundle.getSelectedExports(); HashSet exportNames = new HashSet(exports.length); // set is used to improve performance of duplicate check. for (int i = 0; i < exports.length; i++) diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateImpl.java index a83c99c6a..9838191e9 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateImpl.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateImpl.java @@ -126,7 +126,7 @@ public abstract class StateImpl implements State { try { resolving = true; resolverErrors.remove(existing); - resolveBundle(existing, false, null, null, null, null); + resolveBundle(existing, false, null, null, null, null, null); } finally { resolving = false; } @@ -166,7 +166,7 @@ public abstract class StateImpl implements State { try { resolving = true; resolverErrors.remove(toRemove); - resolveBundle(toRemove, false, null, null, null, null); + resolveBundle(toRemove, false, null, null, null, null, null); } finally { resolving = false; } @@ -268,7 +268,11 @@ public abstract class StateImpl implements State { ((VersionConstraintImpl) constraint).setSupplier(supplier); } - public synchronized void resolveBundle(BundleDescription bundle, boolean status, BundleDescription[] hosts, ExportPackageDescription[] selectedExports, BundleDescription[] resolvedRequires, ExportPackageDescription[] resolvedImports) { + public void resolveBundle(BundleDescription bundle, boolean status, BundleDescription[] hosts, ExportPackageDescription[] selectedExports, BundleDescription[] resolvedRequires, ExportPackageDescription[] resolvedImports) { + resolveBundle(bundle, status, hosts, selectedExports, null, resolvedRequires, resolvedImports); + } + + public synchronized void resolveBundle(BundleDescription bundle, boolean status, BundleDescription[] hosts, ExportPackageDescription[] selectedExports, ExportPackageDescription[] substitutedExports, BundleDescription[] resolvedRequires, ExportPackageDescription[] resolvedImports) { if (!resolving) throw new IllegalStateException(); // TODO need error message here! BundleDescriptionImpl modifiable = (BundleDescriptionImpl) bundle; @@ -291,7 +295,7 @@ public abstract class StateImpl implements State { if (selectedExports == null || resolvedRequires == null || resolvedImports == null) unresolveConstraints(modifiable); else - resolveConstraints(modifiable, hosts, selectedExports, resolvedRequires, resolvedImports); + resolveConstraints(modifiable, hosts, selectedExports, substitutedExports, resolvedRequires, resolvedImports); } public synchronized void removeBundleComplete(BundleDescription bundle) { @@ -301,19 +305,22 @@ public abstract class StateImpl implements State { removalPendings.remove(bundle); } - private void resolveConstraints(BundleDescriptionImpl bundle, BundleDescription[] hosts, ExportPackageDescription[] selectedExports, BundleDescription[] resolvedRequires, ExportPackageDescription[] resolvedImports) { + private void resolveConstraints(BundleDescriptionImpl bundle, BundleDescription[] hosts, ExportPackageDescription[] selectedExports, ExportPackageDescription[] substitutedExports, BundleDescription[] resolvedRequires, ExportPackageDescription[] resolvedImports) { HostSpecificationImpl hostSpec = (HostSpecificationImpl) bundle.getHost(); if (hostSpec != null) { if (hosts != null) { hostSpec.setHosts(hosts); - for (int i = 0; i < hosts.length; i++) + for (int i = 0; i < hosts.length; i++) { ((BundleDescriptionImpl) hosts[i]).addDependency(bundle, true); + checkHostForSubstitutedExports((BundleDescriptionImpl) hosts[i], bundle); + } } } bundle.setSelectedExports(selectedExports); bundle.setResolvedRequires(resolvedRequires); bundle.setResolvedImports(resolvedImports); + bundle.setSubstitutedExports(substitutedExports); bundle.addDependencies(hosts, true); bundle.addDependencies(resolvedRequires, true); @@ -332,6 +339,30 @@ public abstract class StateImpl implements State { } } + private void checkHostForSubstitutedExports(BundleDescriptionImpl host, BundleDescriptionImpl fragment) { + // TODO need to handle this case where a fragment has its own export substituted + // there are issues here because the order in which fragments are resolved is not always the same ... + } + + // private void checkForSubstitutedExports(BundleDescriptionImpl bundle, ExportPackageDescription[] selectedExports) { + // ExportPackageDescription[] existingSubstitutes = bundle.getSubstitutedExports(); + // ExportPackageDescription[] declaredExports = bundle.getExportPackages(); + // ArrayList substitutes = new ArrayList(); + // for (int i = 0; i < declaredExports.length; i++) { + // boolean selected = false; + // for (int j = 0; !selected && j < selectedExports.length; j++) + // selected = declaredExports[i] == selectedExports[j]; + // if (!selected) + // substitutes.add(declaredExports[i]); + // } + // if (substitutes.size() > 0) { + // substitutes.ensureCapacity(substitutes.size() + existingSubstitutes.length); + // for (int i = 0; i < existingSubstitutes.length; i++) + // substitutes.add(0, existingSubstitutes[i]); + // bundle.setSubstitutedExports((ExportPackageDescription[]) substitutes.toArray(new ExportPackageDescription[substitutes.size()])); + // } + // } + private void unresolveConstraints(BundleDescriptionImpl bundle) { HostSpecificationImpl host = (HostSpecificationImpl) bundle.getHost(); if (host != null) @@ -340,6 +371,7 @@ public abstract class StateImpl implements State { bundle.setSelectedExports(null); bundle.setResolvedImports(null); bundle.setResolvedRequires(null); + bundle.setSubstitutedExports(null); // remove suppliers for generics GenericSpecification[] genericRequires = bundle.getGenericRequires(); @@ -433,7 +465,7 @@ public abstract class StateImpl implements State { if (resolvedBundles.isEmpty()) return; for (int i = 0; i < bundles.length; i++) { - resolveBundle(bundles[i], false, null, null, null, null); + resolveBundle(bundles[i], false, null, null, null, null, null); } resolvedBundles.clear(); } @@ -655,7 +687,7 @@ public abstract class StateImpl implements State { if (elements == null) continue; // we can pass false for strict mode here because we never want to mark the system exports as internal. - ExportPackageDescription[] systemExports = StateBuilder.createExportPackages(elements, null, null, null, 2, false); + ExportPackageDescription[] systemExports = StateBuilder.createExportPackages(elements, null, null, 2, false); Integer profInx = new Integer(i); for (int j = 0; j < systemExports.length; j++) { ((ExportPackageDescriptionImpl) systemExports[j]).setDirective(ExportPackageDescriptionImpl.EQUINOX_EE, profInx); diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateMessages.properties b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateMessages.properties index 6c17d2f96..15cae023a 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateMessages.properties +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateMessages.properties @@ -21,7 +21,6 @@ HEADER_PACKAGE_JAVA=Cannot specify java.* packages in Import/Export headers \"{0 HEADER_VERSION_ERROR=The attributes \"{0}\" and \"{1}\" must match HEADER_EXPORT_ATTR_ERROR=Specifying \"{0}\" in the \"{1}\" header is not permitted HEADER_DIRECTIVE_DUPLICATES=Duplicate directives are not permitted \"{0}\" -HEADER_REEXPORT_USES=Cannot specify the \"{0}\" directive on the header \"{1}\" HEADER_EXTENSION_ERROR=Extension bundle is not a fragment to the system bundle \"{0}\" RES_ERROR_DISABLEDBUNDLE=The bundle is disabled: {0} diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateMsg.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateMsg.java index 32ab014f9..199f55e59 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateMsg.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateMsg.java @@ -26,7 +26,6 @@ public class StateMsg extends NLS { public static String HEADER_VERSION_ERROR; public static String HEADER_EXPORT_ATTR_ERROR; public static String HEADER_DIRECTIVE_DUPLICATES; - public static String HEADER_REEXPORT_USES; public static String HEADER_EXTENSION_ERROR; public static String RES_ERROR_DISABLEDBUNDLE; diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateObjectFactoryImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateObjectFactoryImpl.java index 566249c57..7d2dcb55a 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateObjectFactoryImpl.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateObjectFactoryImpl.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2003, 2007 IBM Corporation and others. + * Copyright (c) 2003, 2008 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 @@ -231,7 +231,6 @@ public class StateObjectFactoryImpl implements StateObjectFactory { exportPackage.setVersion(version); exportPackage.setDirectives(directives); exportPackage.setAttributes(attributes); - exportPackage.setRoot(root); exportPackage.setExporter(exporter); return exportPackage; } diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateReader.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateReader.java index 8b42020c4..8358aef59 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateReader.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateReader.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2003, 2007 IBM Corporation and others. + * Copyright (c) 2003, 2008 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 @@ -40,7 +40,7 @@ class StateReader { private int numBundles; private boolean accessedFlag = false; - public static final byte STATE_CACHE_VERSION = 28; + public static final byte STATE_CACHE_VERSION = 30; public static final byte NULL = 0; public static final byte OBJECT = 1; public static final byte INDEX = 2; @@ -283,6 +283,14 @@ class StateReader { result.setSelectedExports(selected); } + int substitutedCount = in.readInt(); + if (substitutedCount > 0) { + ExportPackageDescription[] selected = new ExportPackageDescription[substitutedCount]; + for (int i = 0; i < selected.length; i++) + selected[i] = readExportPackageDesc(in); + result.setSubstitutedExports(selected); + } + int resolvedCount = in.readInt(); if (resolvedCount > 0) { ExportPackageDescription[] resolved = new ExportPackageDescription[resolvedCount]; @@ -363,7 +371,6 @@ class StateReader { exportPackageDesc.setTableIndex(tableIndex); readBaseDescription(exportPackageDesc, in); exportPackageDesc.setExporter(readBundleDescription(in)); - exportPackageDesc.setRoot(in.readBoolean()); exportPackageDesc.setAttributes(readMap(in)); exportPackageDesc.setDirectives(readMap(in)); return exportPackageDesc; diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateWriter.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateWriter.java index a8bdb1394..dfb2f1980 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateWriter.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateWriter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2003, 2007 IBM Corporation and others. + * Copyright (c) 2003, 2008 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 @@ -246,6 +246,15 @@ class StateWriter { writeExportPackageDesc((ExportPackageDescriptionImpl) selectedExports[i], out); } + ExportPackageDescription[] substitutedExports = bundle.getSubstitutedExports(); + if (substitutedExports == null) { + out.writeInt(0); + } else { + out.writeInt(substitutedExports.length); + for (int i = 0; i < substitutedExports.length; i++) + writeExportPackageDesc((ExportPackageDescriptionImpl) substitutedExports[i], out); + } + ExportPackageDescription[] resolvedImports = bundle.getResolvedImports(); if (resolvedImports == null) { out.writeInt(0); @@ -323,7 +332,6 @@ class StateWriter { return; writeBaseDescription(exportPackageDesc, out); writeBundleDescription(exportPackageDesc.getExporter(), out, false); - out.writeBoolean(exportPackageDesc.isRoot()); writeMap(out, exportPackageDesc.getAttributes()); writeMap(out, exportPackageDesc.getDirectives()); } -- cgit v1.2.3