Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2016-06-01 16:30:24 -0400
committerThomas Watson2017-06-16 08:38:08 -0400
commit943977005bfc2a3c04daca26822418310029133f (patch)
treee8accb568fea9950462ed41e23aa2f3fa2f3673a /bundles
parentc91ca50fbdc7aa849a03bad83e51ce8141c498d5 (diff)
downloadrt.equinox.framework-943977005bfc2a3c04daca26822418310029133f.tar.gz
rt.equinox.framework-943977005bfc2a3c04daca26822418310029133f.tar.xz
rt.equinox.framework-943977005bfc2a3c04daca26822418310029133f.zip
Bug 492825 - [osgi R7] Resolver specification updates for version 1.1
Implement resovlveDynamic and findRelatedResources Change-Id: I0841246411734e191b62d24a10f7918f904f932d Signed-off-by: Thomas Watson <tjwatson@us.ibm.com>
Diffstat (limited to 'bundles')
-rw-r--r--bundles/org.eclipse.osgi/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolver.java9
-rwxr-xr-xbundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/Candidates.java4
-rwxr-xr-xbundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/FelixResolveContext.java56
-rwxr-xr-xbundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/ResolverImpl.java47
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/service/resolver/HostedCapability.java3
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/service/resolver/ResolveContext.java73
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/service/resolver/Resolver.java61
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/service/resolver/package-info.java10
-rw-r--r--bundles/org.eclipse.osgi/osgi/src/org/osgi/service/resolver/packageinfo2
10 files changed, 169 insertions, 98 deletions
diff --git a/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF
index 8104043a9..872adf90a 100644
--- a/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF
@@ -71,7 +71,7 @@ Export-Package: org.eclipse.core.runtime.adaptor;x-friends:="org.eclipse.core.ru
org.osgi.service.log.admin;version="1.0",
org.osgi.service.packageadmin;version="1.2";uses:="org.osgi.framework",
org.osgi.service.permissionadmin;version="1.2",
- org.osgi.service.resolver;version="1.0.1";uses:="org.osgi.resource",
+ org.osgi.service.resolver;version="1.1";uses:="org.osgi.resource",
org.osgi.service.startlevel;version="1.1";uses:="org.osgi.framework",
org.osgi.service.url;version="1.0",
org.osgi.util.tracker;version="1.5.1";uses:="org.osgi.framework"
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolver.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolver.java
index 90321aa1e..d58c142e6 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolver.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolver.java
@@ -600,7 +600,9 @@ final class ModuleResolver {
@Override
public List<Capability> findProviders(Requirement requirement) {
- return findProviders0(requirement, requirement);
+ Requirement origReq = requirement;
+ Requirement lookupReq = dynamicReq == null || dynamicReq.getOriginal() != requirement ? requirement : dynamicReq;
+ return findProviders0(origReq, lookupReq);
}
private List<Capability> findProviders0(Requirement origReq, Requirement lookupReq) {
@@ -846,7 +848,7 @@ final class ModuleResolver {
}
@Override
- public Collection<Resource> getOndemandResources(Resource host) {
+ public Collection<Resource> findRelatedResources(Resource host) {
List<ModuleCapability> hostCaps = ((ModuleRevision) host).getModuleCapabilities(HostNamespace.HOST_NAMESPACE);
if (hostCaps.isEmpty()) {
return Collections.emptyList();
@@ -1354,8 +1356,7 @@ final class ModuleResolver {
}
private Map<Resource, List<Wire>> resolveDynamic() throws ResolutionException {
- List<Capability> dynamicMatches = findProviders0(dynamicReq.getOriginal(), dynamicReq);
- return new ResolverImpl(new Logger(0), null).resolve(this, dynamicReq.getRevision(), dynamicReq.getOriginal(), dynamicMatches);
+ return new ResolverImpl(new Logger(0), null).resolveDynamic(this, dynamicReq.getRevision().getWiring(), dynamicReq.getOriginal());
}
private void filterResolvable() {
diff --git a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/Candidates.java b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/Candidates.java
index b87c6ac73..af597d487 100755
--- a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/Candidates.java
+++ b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/Candidates.java
@@ -184,9 +184,9 @@ class Candidates
addCandidates(result.candidates);
result.candidates = null;
result.remaining = null;
- if ((rc instanceof FelixResolveContext) && !Util.isFragment(resource))
+ if (!Util.isFragment(resource))
{
- Collection<Resource> ondemandFragments = ((FelixResolveContext) rc).getOndemandResources(resource);
+ Collection<Resource> ondemandFragments = rc.findRelatedResources(resource);
for (Resource fragment : ondemandFragments)
{
if (m_session.isValidOnDemandResource(fragment))
diff --git a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/FelixResolveContext.java b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/FelixResolveContext.java
index 9782d0a02..ddfb49bcf 100755
--- a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/FelixResolveContext.java
+++ b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/FelixResolveContext.java
@@ -18,46 +18,22 @@
*/package org.apache.felix.resolver;
import java.util.Collection;
-
import org.osgi.framework.namespace.PackageNamespace;
-import org.osgi.resource.Resource;
-import org.osgi.resource.Wire;
-import org.osgi.resource.Wiring;
-
-public interface FelixResolveContext
-{
- /**
- * Return the resources that the resolver should attempt to resolve on
- * demand for specified resource which is being resolved. Inability to
- * resolve one of the on demand resources will not result in a resolution
- * exception.
- *
- * <p>
- * The resolver will ask for on demand resources for each resource that is
- * getting pulled into a resolve operation. An example of an on demand
- * resource is a fragment. When a host is being resolved the resolve context
- * will be asked if any additional resources should be added to the resolve
- * operation. The resolve context may decide that the potential fragments of
- * the host should be resolved along with the host.
- *
- * @return A collection of the resources that the resolver should attempt to
- * resolve for this resolve context. May be empty if there are no on demand
- * resources. The returned collection may be unmodifiable.
- */
- public Collection<Resource> getOndemandResources(Resource host);
+import org.osgi.resource.*;
- /**
- * Returns the subset of {@link Wiring#getRequiredResourceWires(String) require wires}
- * that provide wires to {@link Capability capabilities} which substitute capabilities
- * of the given wiring. For example, when a {@link PackageNamespace package} name is both
- * provided and required by the same resource. If the package requirement is resolved
- * to a capability hosted by a different wiring then the package capability is
- * considered to be substituted.
- *
- * @param wiring the wiring to get the substitution wires from
- * @return A collection containing a snapshot of the substitution {@link Wire}s
- * for the {@link Requirement requirements} of this wiring, or an empty list
- * if this wiring has no substitution wires.
- */
- public Collection<Wire> getSubstitutionWires(Wiring wiring);
+public interface FelixResolveContext {
+ /**
+ * Returns the subset of {@link Wiring#getRequiredResourceWires(String) require wires}
+ * that provide wires to {@link Capability capabilities} which substitute capabilities
+ * of the given wiring. For example, when a {@link PackageNamespace package} name is both
+ * provided and required by the same resource. If the package requirement is resolved
+ * to a capability hosted by a different wiring then the package capability is
+ * considered to be substituted.
+ *
+ * @param wiring the wiring to get the substitution wires from
+ * @return A collection containing a snapshot of the substitution {@link Wire}s
+ * for the {@link Requirement requirements} of this wiring, or an empty list
+ * if this wiring has no substitution wires.
+ */
+ public Collection<Wire> getSubstitutionWires(Wiring wiring);
}
diff --git a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/ResolverImpl.java b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/ResolverImpl.java
index 128482c27..7735df71f 100755
--- a/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/ResolverImpl.java
+++ b/bundles/org.eclipse.osgi/felix/src/org/apache/felix/resolver/ResolverImpl.java
@@ -600,43 +600,18 @@ public class ResolverImpl implements Resolver
return error;
}
- /**
- * Resolves a dynamic requirement for the specified host resource using the
- * specified {@link ResolveContext}. The dynamic requirement may contain
- * wild cards in its filter for the package name. The matching candidates
- * are used to resolve the requirement and the resolve context is not asked
- * to find providers for the dynamic requirement. The host resource is
- * expected to not be a fragment, to already be resolved and have an
- * existing wiring provided by the resolve context.
- * <p>
- * This operation may resolve additional resources in order to resolve the
- * dynamic requirement. The returned map will contain entries for each
- * resource that got resolved in addition to the specified host resource.
- * The wire list for the host resource will only contain a single wire which
- * is for the dynamic requirement.
- *
- * @param rc the resolve context
- * @param host the hosting resource
- * @param dynamicReq the dynamic requirement
- * @param matches a list of matching capabilities
- * @return The new resources and wires required to satisfy the specified
- * dynamic requirement. The returned map is the property of the caller and
- * can be modified by the caller.
- * @throws ResolutionException
- */
- public Map<Resource, List<Wire>> resolve(
- ResolveContext rc, Resource host, Requirement dynamicReq,
- List<Capability> matches)
- throws ResolutionException
+ public Map<Resource,List<Wire>> resolveDynamic(ResolveContext context,
+ Wiring hostWiring, Requirement dynamicRequirement)
+ throws ResolutionException
{
+ Resource host = hostWiring.getResource();
+ List<Capability> matches = context.findProviders(dynamicRequirement);
// We can only create a dynamic import if the following
// conditions are met:
- // 1. The specified resource is resolved.
- // 2. The package in question is not already imported.
- // 3. The package in question is not accessible via require-bundle.
- // 4. The package in question is not exported by the resource.
- // 5. The package in question matches a dynamic import of the resource.
- if (!matches.isEmpty() && rc.getWirings().containsKey(host))
+ // 1. The package in question is not already imported.
+ // 2. The package in question is not accessible via require-bundle.
+ // 3. The package in question is not exported by the resource.
+ if (!matches.isEmpty())
{
// Make sure all matching candidates are packages.
for (Capability cap : matches)
@@ -647,11 +622,11 @@ public class ResolverImpl implements Resolver
"Matching candidate does not provide a package name.");
}
}
- ResolveSession session = new ResolveSession(rc, new DumbExecutor(), host, dynamicReq, matches);
+ ResolveSession session = new ResolveSession(context, new DumbExecutor(), host, dynamicRequirement, matches);
return doResolve(session);
}
- return Collections.emptyMap();
+ throw new Candidates.MissingRequirementError(dynamicRequirement).toException();
}
private static List<WireCandidate> getWireCandidates(ResolveSession session, Candidates allCandidates, Resource resource)
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/resolver/HostedCapability.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/resolver/HostedCapability.java
index b25092b5e..e6a6917f6 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/resolver/HostedCapability.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/resolver/HostedCapability.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) OSGi Alliance (2012, 2013). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2012, 2015). All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -43,6 +43,7 @@ public interface HostedCapability extends Capability {
*
* @return The Resource that hosts this Capability.
*/
+ @Override
Resource getResource();
/**
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/resolver/ResolveContext.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/resolver/ResolveContext.java
index 39b26f1a3..4cf3f3568 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/resolver/ResolveContext.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/resolver/ResolveContext.java
@@ -20,6 +20,8 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.CancellationException;
+
import org.osgi.annotation.versioning.ConsumerType;
import org.osgi.resource.Capability;
import org.osgi.resource.Requirement;
@@ -30,7 +32,6 @@ import org.osgi.resource.Wiring;
* A resolve context provides resources, options and constraints to the
* potential solution of a {@link Resolver#resolve(ResolveContext) resolve}
* operation.
- *
* <p>
* Resolve Contexts:
* <ul>
@@ -46,17 +47,16 @@ import org.osgi.resource.Wiring;
* <li>Filter requirements that are part of a resolve operation via the
* {@link #isEffective(Requirement)}.</li>
* </ul>
- *
* <p>
* A resolver may call the methods on the resolve context any number of times
* during a resolve operation using any thread. Implementors should ensure that
* this class is properly thread safe.
- *
* <p>
- * Except for {@link #insertHostedCapability(List, HostedCapability)}, the
- * resolve context methods must be <i>idempotent</i>. This means that resources
- * must have constant capabilities and requirements and the resolve context must
- * return a consistent set of capabilities, wires and effective requirements.
+ * Except for {@link #insertHostedCapability(List, HostedCapability)} and
+ * {@link #onCancel(Runnable)}, the resolve context methods must be
+ * <i>idempotent</i>. This means that resources must have constant capabilities
+ * and requirements and the resolve context must return a consistent set of
+ * capabilities, wires and effective requirements.
*
* @ThreadSafe
* @author $Id$
@@ -185,4 +185,63 @@ public abstract class ResolveContext {
* unmodifiable.
*/
public abstract Map<Resource, Wiring> getWirings();
+
+ /**
+ * Find resources that are related to the given resource.
+ * <p>
+ * The resolver attempts to resolve related resources during the current
+ * resolve operation. Failing to resolve one of the related resources will
+ * not result in a resolution exception unless the related resource is also
+ * a {@link #getMandatoryResources() mandatory} resource.
+ * <p>
+ * The resolve context is asked to return related resources for each
+ * resource that is pulled into a resolve operation. This includes the
+ * {@link #getMandatoryResources() mandatory} and
+ * {@link #getOptionalResources() optional} resources and each related
+ * resource returned by this method.
+ * <p>
+ * For example, a fragment can be considered a related resource for a host
+ * bundle. When a host is being resolved the resolve context will be asked
+ * if any related resources should be added to the resolve operation. The
+ * resolve context may decide that the potential fragments of the host
+ * should be resolved along with the host.
+ *
+ * @param resource The Resource that a resolver is attempting to find
+ * related resources for. Must not be {@code null}.
+ * @return A collection of the resources that the resolver should attempt to
+ * resolve for this resolve context. May be empty if there are no
+ * related resources. The returned collection may be unmodifiable.
+ * @since 1.1
+ */
+ public Collection<Resource> findRelatedResources(Resource resource) {
+ return Collections.emptyList();
+ }
+
+ /**
+ * Registers a callback with the resolve context that is associated with the
+ * currently running resolve operation. The callback can be executed in
+ * order to cancel the currently running resolve operation.
+ * <p>
+ * When a resolve operation begins, the resolver must call this method once
+ * and only once for the duration of the resolve operation and that call
+ * must happen before calling any other method on this resolve context. If
+ * the specified callback is executed then the resolver must cancel the
+ * currently running resolve operation and throw a
+ * {@link ResolutionException} with a cause of type
+ * {@link CancellationException}.
+ * <p>
+ * The callback allows a resolve context to cancel a long running resolve
+ * operation that appears to be running endlessly or at risk of running out
+ * of resources. The resolve context may then decide to give up on resolve
+ * operation or attempt to try another resolve operation with a smaller set
+ * of resources which may allow the resolve operation to complete normally.
+ *
+ * @param callback the callback to execute in order to cancel the resolve
+ * operation
+ * @throws IllegalStateException if the resolver attempts to register more
+ * than one callback for a resolve operation
+ */
+ public void onCancel(Runnable callback) {
+ // do nothing by default
+ }
}
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/resolver/Resolver.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/resolver/Resolver.java
index 367c005c1..7fb3ca12a 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/resolver/Resolver.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/resolver/Resolver.java
@@ -22,9 +22,14 @@ package org.osgi.service.resolver;
import java.util.List;
import java.util.Map;
+
import org.osgi.annotation.versioning.ProviderType;
+import org.osgi.framework.namespace.PackageNamespace;
+import org.osgi.resource.Namespace;
+import org.osgi.resource.Requirement;
import org.osgi.resource.Resource;
import org.osgi.resource.Wire;
+import org.osgi.resource.Wiring;
/**
* A resolver service resolves the specified resources in the context supplied
@@ -70,4 +75,60 @@ public interface Resolver {
* @throws ResolutionException If the resolution cannot be satisfied.
*/
Map<Resource, List<Wire>> resolve(ResolveContext context) throws ResolutionException;
+
+ /**
+ * Resolves a given dynamic requirement dynamically for the given host
+ * wiring using the given resolve context and return any new resources and
+ * wires to the caller.
+ * <p>
+ * The requirement must be a {@link Wiring#getResourceRequirements(String)
+ * requirement} of the wiring and must use the
+ * {@link PackageNamespace#PACKAGE_NAMESPACE package} namespace.
+ * <p>
+ * The resolve context is not asked for
+ * {@link ResolveContext#getMandatoryResources() mandatory} resources or for
+ * {@link ResolveContext#getMandatoryResources() optional} resources. The
+ * resolve context is asked to
+ * {@link ResolveContext#findProviders(Requirement) find providers} for the
+ * given requirement. The matching {@link PackageNamespace#PACKAGE_NAMESPACE
+ * package} capabilities returned by the resolve context must not have a
+ * {@link PackageNamespace#PACKAGE_NAMESPACE osgi.wiring.package} attribute
+ * equal to a {@link PackageNamespace#PACKAGE_NAMESPACE package} capability
+ * already {@link Wiring#getRequiredResourceWires(String) wired to} by the
+ * wiring or equal a {@link PackageNamespace#PACKAGE_NAMESPACE package}
+ * capability {@link Wiring#getResourceCapabilities(String) provided} by the
+ * wiring. The resolve context may be requested to
+ * {@link ResolveContext#findProviders(Requirement) find providers} for
+ * other requirements in order to resolve the resources that provide the
+ * matching capabilities to the given requirement.
+ * <p>
+ * If the requirement {@link Namespace#REQUIREMENT_CARDINALITY_DIRECTIVE
+ * cardinality} is not {@link Namespace#CARDINALITY_MULTIPLE multiple} then
+ * no new wire must be created if the
+ * {@link Wiring#getRequiredResourceWires(String) wires} of the wiring
+ * already contain a wire that uses the {@link Wire#getRequirement()
+ * requirement}
+ * <p>
+ * This operation may resolve additional resources in order to resolve the
+ * dynamic requirement. The returned map will contain entries for each
+ * resource that got resolved in addition to the specified wiring
+ * {@link Wiring#getResource() resource}. The wire list for the wiring
+ * resource will only contain one wire which is for the dynamic requirement.
+ *
+ * @param context The resolve context for the resolve operation. Must not be
+ * {@code null}.
+ * @param hostWiring The wiring with the dynamic
+ * {@link Wiring#getResourceRequirements(String) requirement}.
+ * Must not be {@code null}.
+ * @param dynamicRequirement The dynamic requirement. Must not be
+ * {@code null}.
+ * @return The new resources and wires required to satisfy the specified
+ * dynamic requirement. The returned map is the property of the
+ * caller and can be modified by the caller. If no new wires were
+ * created then a ResolutionException is thrown.
+ * @throws ResolutionException if the dynamic requirement cannot be resolved
+ */
+ public Map<Resource,List<Wire>> resolveDynamic(ResolveContext context,
+ Wiring hostWiring, Requirement dynamicRequirement)
+ throws ResolutionException;
}
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/resolver/package-info.java b/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/resolver/package-info.java
index 4fab41bbd..544d95611 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/resolver/package-info.java
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/resolver/package-info.java
@@ -15,27 +15,25 @@
*/
/**
- * Resolver Service Package Version 1.0.
- *
+ * Resolver Service Package Version 1.1.
* <p>
* Bundles wishing to use this package must list the package in the
* Import-Package header of the bundle's manifest. This package has two types of
* users: the consumers that use the API in this package and the providers that
* implement the API in this package.
- *
* <p>
* Example import for consumers using the API in this package:
* <p>
- * {@code Import-Package: org.osgi.service.resolver; version="[1.0,2.0)"}
+ * {@code Import-Package: org.osgi.service.resolver; version="[1.1,2.0)"}
* <p>
* Example import for providers implementing the API in this package:
* <p>
- * {@code Import-Package: org.osgi.service.resolver; version="[1.0,1.1)"}
+ * {@code Import-Package: org.osgi.service.resolver; version="[1.1,1.2)"}
*
* @author $Id$
*/
-@Version("1.0.1")
+@Version("1.1")
package org.osgi.service.resolver;
import org.osgi.annotation.versioning.Version;
diff --git a/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/resolver/packageinfo b/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/resolver/packageinfo
index b3d1f97f7..3987f9c4e 100644
--- a/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/resolver/packageinfo
+++ b/bundles/org.eclipse.osgi/osgi/src/org/osgi/service/resolver/packageinfo
@@ -1 +1 @@
-version 1.0.1
+version 1.1

Back to the top