diff options
author | Thomas Watson | 2010-09-01 15:50:33 +0000 |
---|---|---|
committer | Thomas Watson | 2010-09-01 15:50:33 +0000 |
commit | d117602f3f77804e2584a050caacfd604a04de1d (patch) | |
tree | ca32a82d87af205448ac9b172dd7c41a03085485 /bundles | |
parent | c6ef580c02954388a34e955675cf221c8aee538d (diff) | |
download | rt.equinox.framework-d117602f3f77804e2584a050caacfd604a04de1d.tar.gz rt.equinox.framework-d117602f3f77804e2584a050caacfd604a04de1d.tar.xz rt.equinox.framework-d117602f3f77804e2584a050caacfd604a04de1d.zip |
Bug 323426 - Implement BundleWiring(s) support
Diffstat (limited to 'bundles')
13 files changed, 412 insertions, 25 deletions
diff --git a/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/BaseDescription.java b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/BaseDescription.java index 0fef40933..0ae706f6b 100644 --- a/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/BaseDescription.java +++ b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/BaseDescription.java @@ -12,6 +12,7 @@ package org.eclipse.osgi.service.resolver; import java.util.Map; import org.osgi.framework.Version; +import org.osgi.framework.wiring.WiredCapability; /** * This class represents a base description object for a state. All description @@ -56,4 +57,14 @@ public interface BaseDescription { * @since 3.7 */ public Map<String, Object> getDeclaredAttributes(); + + /** + * Returns the wired capability representing this base description. + * Some descriptions types may not be able to be represented by + * a wired capability. In such cases <code>null</code> is + * returned. + * @return the wired capability representing this base description + * @since 3.7 + */ + public WiredCapability getWiredCapability(); } diff --git a/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/BundleDescription.java b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/BundleDescription.java index 70c1da872..7105941d7 100644 --- a/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/BundleDescription.java +++ b/bundles/org.eclipse.osgi/core/adaptor/org/eclipse/osgi/service/resolver/BundleDescription.java @@ -10,6 +10,9 @@ *******************************************************************************/ package org.eclipse.osgi.service.resolver; +import org.osgi.framework.wiring.BundleRevision; +import org.osgi.framework.wiring.BundleWiring; + /** * This class represents a specific version of a bundle in the system. * <p> @@ -19,7 +22,7 @@ package org.eclipse.osgi.service.resolver; * @since 3.1 * @noimplement This interface is not intended to be implemented by clients. */ -public interface BundleDescription extends BaseDescription { +public interface BundleDescription extends BaseDescription, BundleRevision { /** * Gets the Bundle-SymbolicName of this BundleDescription. @@ -269,4 +272,14 @@ public interface BundleDescription extends BaseDescription { * @since 3.4 */ public ExportPackageDescription[] getSubstitutedExports(); + + /** + * Returns the bundle wiring object associated with this bundle description. + * A bundle description can only have one bundle wiring object associated with + * it which is in use. A bundle description must be resolved in order + * to have a bundle wiring object associated with it. + * @return the bundle wiring object associated with this bundle description. + * @since 3.7 + */ + public BundleWiring getBundleWiring(); } diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/AbstractBundle.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/AbstractBundle.java index 7e42d18ec..01863b1a9 100644 --- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/AbstractBundle.java +++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/AbstractBundle.java @@ -29,6 +29,8 @@ import org.eclipse.osgi.signedcontent.*; import org.eclipse.osgi.util.NLS; import org.osgi.framework.*; import org.osgi.framework.startlevel.BundleStartLevel; +import org.osgi.framework.wiring.BundleRevision; +import org.osgi.framework.wiring.BundleWiring; /** * This object is given out to bundles and wraps the internal Bundle object. It @@ -1546,7 +1548,16 @@ public abstract class AbstractBundle implements Bundle, Comparable<Bundle>, Keye if (BundleStartLevel.class.equals(adapterType)) return (A) this; - // TODO need to handle BundleWiring, BundlePackageAdmin + if (BundleWiring.class.equals(adapterType)) { + if (state == UNINSTALLED || isFragment()) + return null; + BundleDescription description = getBundleDescription(); + return (A) description.getBundleWiring(); + } + + if (BundleRevision.class.equals(adapterType)) { + return (A) getBundleDescription(); + } return null; } diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleFragment.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleFragment.java index 980ea296e..468a0c85b 100644 --- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleFragment.java +++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleFragment.java @@ -13,12 +13,16 @@ package org.eclipse.osgi.framework.internal.core; import java.io.IOException; import java.net.URL; -import java.util.Enumeration; +import java.util.*; import org.eclipse.osgi.framework.adaptor.BundleData; import org.eclipse.osgi.framework.debug.Debug; import org.eclipse.osgi.internal.loader.BundleLoader; +import org.eclipse.osgi.service.resolver.BundleDescription; +import org.eclipse.osgi.service.resolver.HostSpecification; import org.eclipse.osgi.util.NLS; import org.osgi.framework.*; +import org.osgi.framework.wiring.BundleWiring; +import org.osgi.framework.wiring.BundleWirings; public class BundleFragment extends AbstractBundle { @@ -335,4 +339,43 @@ public class BundleFragment extends AbstractBundle { // Fragments cannot have a BundleContext. return null; } + + public <A> A adapt(Class<A> adapterType) { + if (BundleWirings.class.equals(adapterType)) { + return (A) new BundleWirings() { + public Bundle getBundle() { + return BundleFragment.this; + } + + public List<BundleWiring> getWirings() { + List<BundleWiring> wirings = new ArrayList<BundleWiring>(); + BundleDescription current = getBundleDescription(); + BundleDescription[] removed = framework.adaptor.getState().getRemovalPending(); + + int i = -1; + do { + HostSpecification hostSpec = null; + if (i == -1) { + if (current != null) + hostSpec = current.getHost(); + } else if (removed[i] != current && removed[i].getBundleId() == getBundleId()) { + hostSpec = removed[i].getHost(); + } + BundleDescription[] hostDescs = hostSpec == null ? null : hostSpec.getHosts(); + if (hostDescs != null) { + for (BundleDescription host : hostDescs) { + BundleWiring wiring = host.getBundleWiring(); + if (wiring != null) + wirings.add(wiring); + } + } + i++; + } while (i < removed.length); + return wirings; + } + + }; + } + return super.adapt(adapterType); + } } diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleHost.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleHost.java index 9644054e0..7c5611673 100644 --- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleHost.java +++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/BundleHost.java @@ -13,7 +13,7 @@ package org.eclipse.osgi.framework.internal.core; import java.io.IOException; import java.net.URL; -import java.util.Enumeration; +import java.util.*; import org.eclipse.osgi.framework.adaptor.*; import org.eclipse.osgi.framework.debug.Debug; import org.eclipse.osgi.framework.log.FrameworkLogEntry; @@ -22,6 +22,8 @@ import org.eclipse.osgi.internal.loader.BundleLoaderProxy; import org.eclipse.osgi.service.resolver.BundleDescription; import org.eclipse.osgi.util.NLS; import org.osgi.framework.*; +import org.osgi.framework.wiring.BundleWiring; +import org.osgi.framework.wiring.BundleWirings; public class BundleHost extends AbstractBundle { public static final int LAZY_TRIGGER = 0x40000000; @@ -674,4 +676,33 @@ public class BundleHost extends AbstractBundle { BundleClassLoader bcl = loader == null ? null : loader.createClassLoader(); return (bcl instanceof ClassLoader) ? (ClassLoader) bcl : null; } + + public <A> A adapt(Class<A> adapterType) { + if (BundleWirings.class.equals(adapterType)) { + return (A) new BundleWirings() { + public Bundle getBundle() { + return BundleHost.this; + } + + public List<BundleWiring> getWirings() { + List<BundleWiring> wirings = new ArrayList<BundleWiring>(); + BundleWiring current = adapt(BundleWiring.class); + if (current != null) + wirings.add(current); + BundleDescription[] removals = framework.adaptor.getState().getRemovalPending(); + for (BundleDescription removed : removals) { + if (removed.getBundleId() == getBundleId()) { + BundleWiring removedWiring = removed.getBundleWiring(); + if (removedWiring != null && removedWiring != current) + wirings.add(removedWiring); + } + } + return wirings; + } + + }; + } + return super.adapt(adapterType); + } + } 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 fb1e6e97a..13da52adc 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 @@ -13,7 +13,8 @@ package org.eclipse.osgi.internal.module; import java.util.*; import java.util.Map.Entry; import org.eclipse.osgi.service.resolver.*; -import org.osgi.framework.*; +import org.osgi.framework.Bundle; +import org.osgi.framework.Constants; import org.osgi.framework.wiring.BundleRevision; import org.osgi.framework.wiring.Capability; @@ -642,10 +643,7 @@ public class ResolverBundle extends VersionSupplier implements Comparable, Bundl } public Bundle getBundle() { - Object ref = getBundleDescription().getUserObject(); - if (ref instanceof BundleReference) - return ((BundleReference) ref).getBundle(); - return null; + return getBundleDescription().getBundle(); } public String getSymbolicName() { @@ -653,12 +651,20 @@ public class ResolverBundle extends VersionSupplier implements Comparable, Bundl } public List<Capability> getDeclaredCapabilities(String namespace) { - // TODO Auto-generated method stub - return null; + // This gives a view of the host and attached fragments. + Capability[] capabilities = getGenericCapabilities(); + if (namespace == null) + return new ArrayList<Capability>(Arrays.asList(capabilities)); + List<Capability> result = new ArrayList<Capability>(); + for (Capability capability : capabilities) { + if (namespace.equals(capability.getNamespace())) + result.add(capability); + } + return result; } public int getTypes() { - return getBundleDescription().getHost() != null ? BundleRevision.TYPE_FRAGMENT : 0; + return getBundleDescription().getTypes(); } public String getNamespace() { diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BaseDescriptionImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BaseDescriptionImpl.java index f0f623ddf..95dce2874 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BaseDescriptionImpl.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BaseDescriptionImpl.java @@ -13,7 +13,9 @@ package org.eclipse.osgi.internal.resolver; import java.util.*; import org.eclipse.osgi.service.resolver.BaseDescription; +import org.eclipse.osgi.service.resolver.BundleDescription; import org.osgi.framework.Version; +import org.osgi.framework.wiring.*; abstract class BaseDescriptionImpl implements BaseDescription { @@ -76,4 +78,87 @@ abstract class BaseDescriptionImpl implements BaseDescription { } return sb.toString(); } + + String getInternalNameSpace() { + return null; + } + + public WiredCapability getWiredCapability() { + synchronized (this.monitor) { + BundleDescription supplier = getSupplier(); + BundleWiring wiring = supplier.getBundleWiring(); + if (wiring == null) + return null; + return new BaseWiredCapability(wiring); + } + } + + class BaseWiredCapability implements WiredCapability { + private final BundleWiring originalWiring; + + public BaseWiredCapability(BundleWiring originalWiring) { + this.originalWiring = originalWiring; + } + + public BundleRevision getProviderRevision() { + return getSupplier(); + } + + public String getNamespace() { + return getInternalNameSpace(); + } + + public Map<String, String> getDirectives() { + return getDeclaredDirectives(); + } + + public Map<String, Object> getAttributes() { + return getDeclaredAttributes(); + } + + public Collection<BundleWiring> getRequirerWirings() { + BundleWiring wiring = getProviderWiring(); + if (wiring == null) + return null; + BundleDescription supplier = getSupplier(); + BundleDescription[] dependents = supplier.getDependents(); + Collection<BundleWiring> requirers = new ArrayList<BundleWiring>(); + for (BundleDescription dependent : dependents) { + BundleWiring dependentWiring = dependent.getBundleWiring(); + if (dependentWiring == null) // fragments have no wiring + continue; + List<WiredCapability> namespace = dependentWiring.getRequiredCapabilities(getNamespace()); + if (namespace == null) + continue; + if (namespace.contains(this)) + requirers.add(dependentWiring); + } + return requirers; + } + + public BundleWiring getProviderWiring() { + return originalWiring.isInUse() ? originalWiring : null; + } + + BaseDescriptionImpl getImpl() { + return BaseDescriptionImpl.this; + } + + public int hashCode() { + return System.identityHashCode(BaseDescriptionImpl.this) ^ System.identityHashCode(originalWiring); + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!(obj instanceof BaseWiredCapability)) + return false; + BaseWiredCapability other = (BaseWiredCapability) obj; + return (other.originalWiring == this.originalWiring) && (this.getImpl() == other.getImpl()); + } + + public String toString() { + return getNamespace() + BaseDescriptionImpl.toString(getAttributes(), false); + } + } } 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 b6f5534a0..5f3694c6b 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 @@ -13,11 +13,14 @@ package org.eclipse.osgi.internal.resolver; import java.io.IOException; +import java.net.URL; import java.util.*; import org.eclipse.osgi.framework.internal.core.Constants; import org.eclipse.osgi.framework.util.KeyedElement; import org.eclipse.osgi.service.resolver.*; -import org.osgi.framework.wiring.Capability; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleReference; +import org.osgi.framework.wiring.*; public final class BundleDescriptionImpl extends BaseDescriptionImpl implements BundleDescription, KeyedElement { static final String[] EMPTY_STRING = new String[0]; @@ -55,6 +58,8 @@ public final class BundleDescriptionImpl extends BaseDescriptionImpl implements private volatile LazyData lazyData; private volatile int equinox_ee = -1; + private DescriptionWiring bundleWiring; + public BundleDescriptionImpl() { // } @@ -345,10 +350,16 @@ public final class BundleDescriptionImpl extends BaseDescriptionImpl implements protected void setStateBit(int stateBit, boolean on) { synchronized (this.monitor) { - if (on) + if (on) { stateBits |= stateBit; - else + } else { stateBits &= ~stateBit; + if (stateBit == RESOLVED) { + if (bundleWiring != null) + bundleWiring.invalidate(); + bundleWiring = null; + } + } } } @@ -555,6 +566,12 @@ public final class BundleDescriptionImpl extends BaseDescriptionImpl implements } } + boolean hasDependents() { + synchronized (this.monitor) { + return dependents == null ? false : dependents.size() > 0; + } + } + void setFullyLoaded(boolean fullyLoaded) { synchronized (this.monitor) { if (fullyLoaded) { @@ -741,4 +758,143 @@ public final class BundleDescriptionImpl extends BaseDescriptionImpl implements result.put(Constants.BUNDLE_VERSION_ATTRIBUTE, getVersion()); return Collections.unmodifiableMap(result); } + + public List<Capability> getDeclaredCapabilities(String namespace) { + List<Capability> result = new ArrayList<Capability>(); + if (namespace == null || Capability.BUNDLE_CAPABILITY.equals(namespace)) { + result.add(BundleDescriptionImpl.this.getWiredCapability()); + } + if (namespace == null || Capability.PACKAGE_CAPABILITY.equals(namespace)) { + ExportPackageDescription[] exports = getExportPackages(); + for (ExportPackageDescription importPkg : exports) + result.add(importPkg.getWiredCapability()); + } + GenericDescription[] genericCapabilities = getGenericCapabilities(); + for (GenericDescription capabilitiy : genericCapabilities) { + if (namespace == null || namespace.equals(capabilitiy.getType())) + result.add(capabilitiy.getWiredCapability()); + } + return result; + } + + public int getTypes() { + return getHost() != null ? BundleRevision.TYPE_FRAGMENT : 0; + } + + public Bundle getBundle() { + Object ref = getUserObject(); + if (ref instanceof BundleReference) + return ((BundleReference) ref).getBundle(); + return null; + } + + String getInternalNameSpace() { + return Capability.BUNDLE_CAPABILITY; + } + + public BundleWiring getBundleWiring() { + synchronized (this.monitor) { + if (bundleWiring != null || !isResolved() || (getTypes() & BundleRevision.TYPE_FRAGMENT) != 0) + return bundleWiring; + return bundleWiring = new DescriptionWiring(); + } + } + + // Note that description wiring are identity equality based + class DescriptionWiring implements BundleWiring { + private volatile boolean valid = true; + + public Bundle getBundle() { + return BundleDescriptionImpl.this.getBundle(); + } + + public boolean isInUse() { + return valid && (isCurrent() || BundleDescriptionImpl.this.hasDependents()); + } + + void invalidate() { + valid = false; + } + + public boolean isCurrent() { + return valid && !BundleDescriptionImpl.this.isRemovalPending(); + } + + public List<WiredCapability> getRequiredCapabilities(String capabilityNamespace) { + if (!isInUse()) + return null; + List<WiredCapability> result = new ArrayList<WiredCapability>(); + if (capabilityNamespace == null || Capability.BUNDLE_CAPABILITY.equals(capabilityNamespace)) { + BundleDescription[] requires = getResolvedRequires(); + for (BundleDescription require : requires) + result.add(require.getWiredCapability()); + } + if (capabilityNamespace == null || Capability.PACKAGE_CAPABILITY.equals(capabilityNamespace)) { + ExportPackageDescription[] imports = getResolvedImports(); + for (ExportPackageDescription importPkg : imports) + result.add(importPkg.getWiredCapability()); + } + GenericDescription[] genericRequires = getResolvedGenericRequires(); + for (GenericDescription require : genericRequires) { + if (capabilityNamespace == null || capabilityNamespace.equals(require.getType())) + result.add(require.getWiredCapability()); + } + return result; + } + + public List<WiredCapability> getProvidedCapabilities(String capabilityNamespace) { + if (!isInUse()) + return null; + List<WiredCapability> result = new ArrayList<WiredCapability>(); + if (capabilityNamespace == null || Capability.BUNDLE_CAPABILITY.equals(capabilityNamespace)) { + result.add(BundleDescriptionImpl.this.getWiredCapability()); + } + if (capabilityNamespace == null || Capability.PACKAGE_CAPABILITY.equals(capabilityNamespace)) { + ExportPackageDescription[] exports = getSelectedExports(); + for (ExportPackageDescription importPkg : exports) + result.add(importPkg.getWiredCapability()); + } + GenericDescription[] genericCapabilities = getSelectedGenericCapabilities(); + for (GenericDescription capabilitiy : genericCapabilities) { + if (capabilityNamespace == null || capabilityNamespace.equals(capabilitiy.getType())) + result.add(capabilitiy.getWiredCapability()); + } + return result; + } + + public List<BundleRevision> getFragmentRevisions() { + if (!isInUse()) + return null; + return new ArrayList<BundleRevision>(Arrays.asList(getFragments())); + } + + public ClassLoader getClassLoader() { + if (!isInUse()) + return null; + // TODO Auto-generated method stub + return null; + } + + public BundleRevision getBundleRevision() { + return BundleDescriptionImpl.this; + } + + public List<URL> findEntries(String path, String filePattern, int options) { + if (!isInUse()) + return null; + // TODO Auto-generated method stub + return null; + } + + public List<String> listResources(String path, String filePattern, int options) { + if (!isInUse()) + return null; + // TODO Auto-generated method stub + return null; + } + + public String toString() { + return BundleDescriptionImpl.this.toString(); + } + } } 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 1a09645bc..a4e9a5346 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 @@ -195,4 +195,8 @@ public class ExportPackageDescriptionImpl extends BaseDescriptionImpl implements void setTableIndex(int tableIndex) { this.tableIndex = tableIndex; } + + String getInternalNameSpace() { + return Capability.PACKAGE_CAPABILITY; + } } diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/GenericDescriptionImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/GenericDescriptionImpl.java index 6108b0339..61a827182 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/GenericDescriptionImpl.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/GenericDescriptionImpl.java @@ -98,4 +98,8 @@ public class GenericDescriptionImpl extends BaseDescriptionImpl implements Gener return Collections.unmodifiableMap(result); } } + + String getInternalNameSpace() { + return getType(); + } } diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/NativeCodeDescriptionImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/NativeCodeDescriptionImpl.java index 866247a69..ce9750eff 100644 --- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/NativeCodeDescriptionImpl.java +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/NativeCodeDescriptionImpl.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2008 IBM Corporation and others. + * Copyright (c) 2007, 2010 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 @@ -16,6 +16,7 @@ import org.eclipse.osgi.framework.internal.core.Constants; import org.eclipse.osgi.framework.internal.core.FilterImpl; import org.eclipse.osgi.service.resolver.*; import org.osgi.framework.*; +import org.osgi.framework.wiring.WiredCapability; public class NativeCodeDescriptionImpl extends BaseDescriptionImpl implements NativeCodeDescription { private static final VersionRange[] EMPTY_VERSIONRANGES = new VersionRange[0]; @@ -218,4 +219,9 @@ public class NativeCodeDescriptionImpl extends BaseDescriptionImpl implements Na return Collections.EMPTY_MAP; } + public WiredCapability getWiredCapability() { + // not supported for native code + return null; + } + } 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 23149eb3a..592ccf484 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 @@ -464,7 +464,7 @@ class StateBuilder { spec.setName(name); } catch (InvalidSyntaxException e) { String message = NLS.bind(Msg.MANIFEST_INVALID_HEADER_EXCEPTION, OSGI_REQUIRE_CAPABILITY, element.toString()); - throw new BundleException(message + " : " + Constants.SELECTION_FILTER_ATTRIBUTE, BundleException.MANIFEST_ERROR, e); //$NON-NLS-1$ + throw new BundleException(message + " : filter", BundleException.MANIFEST_ERROR, e); //$NON-NLS-1$ } String resolution = element.getDirective(Constants.RESOLUTION_DIRECTIVE); if (Constants.RESOLUTION_OPTIONAL.equals(resolution)) 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 54666694d..1ecc16ea3 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 @@ -37,7 +37,7 @@ public abstract class StateImpl implements State { transient private Resolver resolver; transient private StateDeltaImpl changes; transient volatile private boolean resolving = false; - transient private HashSet removalPendings = new HashSet(); + transient private LinkedList<BundleDescription> removalPendings = new LinkedList<BundleDescription>(); private volatile boolean resolved = true; private volatile long timeStamp = System.currentTimeMillis(); @@ -128,13 +128,13 @@ public abstract class StateImpl implements State { resolver.bundleUpdated(newDescription, existing, pending); if (pending) { getDelta().recordBundleRemovalPending(existing); - removalPendings.add(existing); + addRemovalPending(existing); } else { // an existing bundle has been updated with no dependents it can safely be unresolved now try { resolving = true; resolverErrors.remove(existing); - resolveBundle(existing, false, null, null, null, null, null); + resolveBundle(existing, false, null, null, null, null, null, null, null); } finally { resolving = false; } @@ -169,7 +169,7 @@ public abstract class StateImpl implements State { resolver.bundleRemoved(toRemove, pending); if (pending) { getDelta().recordBundleRemovalPending((BundleDescriptionImpl) toRemove); - removalPendings.add(toRemove); + addRemovalPending(toRemove); } else { // a bundle has been removed with no dependents it can safely be unresolved now try { @@ -445,7 +445,7 @@ public abstract class StateImpl implements State { reResolve = getBundles(); // need to get any removal pendings before flushing if (removalPendings.size() > 0) { - BundleDescription[] removed = getRemovalPending(); + BundleDescription[] removed = internalGetRemovalPending(); reResolve = mergeBundles(reResolve, removed); } flush(reResolve); @@ -453,7 +453,7 @@ public abstract class StateImpl implements State { if (resolved && reResolve == null) return new StateDeltaImpl(this); if (removalPendings.size() > 0) { - BundleDescription[] removed = getRemovalPending(); + BundleDescription[] removed = internalGetRemovalPending(); reResolve = mergeBundles(reResolve, removed); } // use the Headers class to handle ignoring case while matching keys (bug 180817) @@ -835,12 +835,29 @@ public abstract class StateImpl implements State { */ public BundleDescription[] getRemovalPending() { synchronized (this.monitor) { - Iterator removed = removalPendings.iterator(); + return removalPendings.toArray(new BundleDescription[removalPendings.size()]); + } + } + + private void addRemovalPending(BundleDescription removed) { + synchronized (this.monitor) { + if (!removalPendings.contains(removed)) + removalPendings.addFirst(removed); + } + } + + /** + * Returns the latest versions BundleDescriptions which have old removal pending versions. + * @return the BundleDescriptions that have removal pending versions. + */ + private BundleDescription[] internalGetRemovalPending() { + synchronized (this.monitor) { + Iterator<BundleDescription> removed = removalPendings.iterator(); BundleDescription[] result = new BundleDescription[removalPendings.size()]; int i = 0; while (removed.hasNext()) // we return the latest version of the description if it is still contained in the state (bug 287636) - result[i++] = getBundle(((BundleDescription) removed.next()).getBundleId()); + result[i++] = getBundle(removed.next().getBundleId()); return result; } } |