Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolver.java')
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolver.java367
1 files changed, 143 insertions, 224 deletions
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 c55afa11e..37b6c0dc9 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012, 2017 IBM Corporation and others.
+ * Copyright (c) 2012, 2021 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -7,12 +7,14 @@
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
- *
+ *
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.osgi.container;
+import static org.eclipse.osgi.internal.container.NamespaceList.WIRE;
+
import java.security.Permission;
import java.util.ArrayList;
import java.util.Arrays;
@@ -25,7 +27,6 @@ import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
-import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CancellationException;
@@ -42,6 +43,7 @@ import org.apache.felix.resolver.ResolverImpl;
import org.eclipse.osgi.container.ModuleRequirement.DynamicModuleRequirement;
import org.eclipse.osgi.container.namespaces.EquinoxFragmentNamespace;
import org.eclipse.osgi.internal.container.InternalUtils;
+import org.eclipse.osgi.internal.container.NamespaceList;
import org.eclipse.osgi.internal.debug.Debug;
import org.eclipse.osgi.internal.framework.EquinoxConfiguration;
import org.eclipse.osgi.internal.framework.EquinoxContainer;
@@ -77,7 +79,7 @@ import org.osgi.service.resolver.Resolver;
* in a module {@link ModuleContainer container}.
*/
final class ModuleResolver {
- static final String SEPARATOR = System.getProperty("line.separator"); //$NON-NLS-1$
+ static final String SEPARATOR = System.lineSeparator();
static final char TAB = '\t';
private static final String OPTION_RESOLVER = EquinoxContainer.NAME + "/resolver"; //$NON-NLS-1$
@@ -150,11 +152,11 @@ final class ModuleResolver {
/**
* Attempts to resolve all unresolved modules installed in the specified module database.
- * returns a delta containing the new wirings or modified wirings that should be
+ * returns a delta containing the new wirings or modified wirings that should be
* merged into the specified moduleDatabase.
* <p>
* This method only does read operations on the database no wirings are modified
- * directly by this method. The returned wirings need to be merged into
+ * directly by this method. The returned wirings need to be merged into
* the database.
* @param triggers the triggers that caused the resolver operation to occur
* @param triggersMandatory true if the triggers must be resolved by the resolve process
@@ -177,12 +179,12 @@ final class ModuleResolver {
Map<ModuleRevision, ModuleWiring> generateDelta(Map<Resource, List<Wire>> result, Map<ModuleRevision, ModuleWiring> wiringCopy) {
Map<ModuleRevision, Map<ModuleCapability, List<ModuleWire>>> provided = new HashMap<>();
- Map<ModuleRevision, List<ModuleWire>> required = new HashMap<>();
+ Map<ModuleRevision, NamespaceList<ModuleWire>> required = new HashMap<>(result.size() * 4 / 3 + 1);
// First populate the list of provided and required wires for revision
// This is done this way to share the wire object between both the provider and requirer
for (Map.Entry<Resource, List<Wire>> resultEntry : result.entrySet()) {
ModuleRevision revision = (ModuleRevision) resultEntry.getKey();
- List<ModuleWire> requiredWires = new ArrayList<>(resultEntry.getValue().size());
+ NamespaceList.Builder<ModuleWire> requiredWires = NamespaceList.Builder.create(WIRE);
for (Wire wire : resultEntry.getValue()) {
ModuleWire moduleWire = new ModuleWire((ModuleCapability) wire.getCapability(), (ModuleRevision) wire.getProvider(), (ModuleRequirement) wire.getRequirement(), (ModuleRevision) wire.getRequirer());
requiredWires.add(moduleWire);
@@ -198,7 +200,7 @@ final class ModuleResolver {
}
providedWires.add(moduleWire);
}
- required.put(revision, requiredWires);
+ required.put(revision, requiredWires.build());
}
Map<ModuleRevision, ModuleWiring> delta = new HashMap<>();
@@ -224,122 +226,94 @@ final class ModuleResolver {
return delta;
}
- private ModuleWiring createNewWiring(ModuleRevision revision, Map<ModuleRevision, Map<ModuleCapability, List<ModuleWire>>> provided, Map<ModuleRevision, List<ModuleWire>> required) {
- Map<ModuleCapability, List<ModuleWire>> providedWireMap = provided.get(revision);
- if (providedWireMap == null)
- providedWireMap = Collections.emptyMap();
- List<ModuleWire> requiredWires = required.get(revision);
- if (requiredWires == null)
- requiredWires = Collections.emptyList();
+ private ModuleWiring createNewWiring(ModuleRevision revision, Map<ModuleRevision, Map<ModuleCapability, List<ModuleWire>>> provided, Map<ModuleRevision, NamespaceList<ModuleWire>> required) {
+
+ Map<ModuleCapability, List<ModuleWire>> providedWireMap = provided.getOrDefault(revision, Collections.emptyMap());
+ NamespaceList<ModuleWire> requiredWires = required.getOrDefault(revision, NamespaceList.empty(WIRE));
- List<ModuleCapability> capabilities = new ArrayList<>(revision.getModuleCapabilities(null));
- ListIterator<ModuleCapability> iCapabilities = capabilities.listIterator(capabilities.size());
- List<ModuleRequirement> requirements = new ArrayList<>(revision.getModuleRequirements(null));
- ListIterator<ModuleRequirement> iRequirements = requirements.listIterator(requirements.size());
+ NamespaceList.Builder<ModuleCapability> capabilities = revision.getCapabilities().createBuilder();
+ NamespaceList.Builder<ModuleRequirement> requirements = revision.getRequirements().createBuilder();
// if revision is a fragment remove payload requirements and capabilities
if ((BundleRevision.TYPE_FRAGMENT & revision.getTypes()) != 0) {
- removePayloadContent(iCapabilities, iRequirements);
+ removePayloadContent(capabilities, requirements);
} else {
// add fragment capabilities and requirements
List<ModuleCapability> hostCapabilities = revision.getModuleCapabilities(HostNamespace.HOST_NAMESPACE);
ModuleCapability hostCapability = hostCapabilities.isEmpty() ? null : hostCapabilities.get(0);
if (hostCapability != null) {
- addPayloadContent(providedWireMap.get(hostCapability), iCapabilities, iRequirements);
+ addPayloadContent(providedWireMap.get(hostCapability), capabilities, requirements);
}
}
- removeNonEffectiveCapabilities(iCapabilities);
- removeNonEffectiveRequirements(iRequirements, requiredWires);
- Collection<String> substituted = removeSubstitutedCapabilities(iCapabilities, requiredWires);
+ removeNonEffectiveCapabilities(capabilities);
+ removeNonEffectiveRequirements(requirements, requiredWires);
+ Collection<String> substituted = removeSubstitutedCapabilities(capabilities, requiredWires);
- List<ModuleWire> providedWires = new ArrayList<>();
+ NamespaceList.Builder<ModuleWire> providedWires = NamespaceList.Builder.create(WIRE);
addProvidedWires(providedWireMap, providedWires, capabilities);
InternalUtils.filterCapabilityPermissions(capabilities);
- return new ModuleWiring(revision, capabilities, requirements, providedWires, requiredWires, substituted);
+ return new ModuleWiring(revision, capabilities.build(), requirements.build(), providedWires.build(),
+ requiredWires, substituted);
+
}
- private static void removePayloadContent(ListIterator<ModuleCapability> iCapabilities, ListIterator<ModuleRequirement> iRequirements) {
- rewind(iCapabilities);
- while (iCapabilities.hasNext()) {
- if (!NON_PAYLOAD_CAPABILITIES.contains(iCapabilities.next().getNamespace())) {
- iCapabilities.remove();
- }
- }
+ private static void removePayloadContent(NamespaceList.Builder<ModuleCapability> capabilities,
+ NamespaceList.Builder<ModuleRequirement> requirements) {
- rewind(iRequirements);
- while (iRequirements.hasNext()) {
- if (!NON_PAYLOAD_REQUIREMENTS.contains(iRequirements.next().getNamespace())) {
- iRequirements.remove();
- }
- }
+ capabilities.removeNamespaceIf(namespace -> !NON_PAYLOAD_CAPABILITIES.contains(namespace));
+ requirements.removeNamespaceIf(namespace -> !NON_PAYLOAD_REQUIREMENTS.contains(namespace));
}
- private static Collection<String> removeSubstitutedCapabilities(ListIterator<ModuleCapability> iCapabilities, List<ModuleWire> requiredWires) {
- Collection<String> substituted = null;
- for (ModuleWire moduleWire : requiredWires) {
- if (!PackageNamespace.PACKAGE_NAMESPACE.equals(moduleWire.getCapability().getNamespace()))
- continue;
+ private static Collection<String> removeSubstitutedCapabilities(NamespaceList.Builder<ModuleCapability> capabilities, NamespaceList<ModuleWire> requiredWires) {
+ Collection<String> substituted = new ArrayList<>();
+ for (ModuleWire moduleWire : requiredWires.getList(PackageNamespace.PACKAGE_NAMESPACE)) {
String packageName = (String) moduleWire.getCapability().getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE);
- rewind(iCapabilities);
- while (iCapabilities.hasNext()) {
- ModuleCapability capability = iCapabilities.next();
- if (PackageNamespace.PACKAGE_NAMESPACE.equals(capability.getNamespace())) {
- if (packageName.equals(capability.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE))) {
- // found a package capability with the same name as a package that got imported
- // this indicates a substitution
- iCapabilities.remove();
- if (substituted == null) {
- substituted = new ArrayList<>();
- }
- if (!substituted.contains(packageName)) {
- substituted.add(packageName);
- }
+ capabilities.removeElementsOfNamespaceIf(PackageNamespace.PACKAGE_NAMESPACE, capability -> {
+ if (packageName.equals(capability.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE))) {
+ // found a package capability with the same name as a package that got imported
+ // this indicates a substitution
+ if (!substituted.contains(packageName)) {
+ substituted.add(packageName);
}
+ return true;
}
- }
+ return false;
+ });
}
- return substituted == null ? Collections.<String> emptyList() : substituted;
+ return substituted.isEmpty() ? Collections.emptyList() : substituted;
}
- private static void removeNonEffectiveRequirements(ListIterator<ModuleRequirement> iRequirements, List<ModuleWire> requiredWires) {
+ private static void removeNonEffectiveRequirements(NamespaceList.Builder<ModuleRequirement> requirements, NamespaceList<ModuleWire> requiredWires) {
Set<ModuleRequirement> wireRequirements = new HashSet<>();
- for (ModuleWire mw : requiredWires) {
+ for (ModuleWire mw : requiredWires.getList(null)) {
wireRequirements.add(mw.getRequirement());
}
-
- rewind(iRequirements);
- while (iRequirements.hasNext()) {
- ModuleRequirement requirement = iRequirements.next();
+ requirements.removeIf(requirement -> {
// check the effective directive;
Object effective = requirement.getDirectives().get(Namespace.REQUIREMENT_EFFECTIVE_DIRECTIVE);
if (effective != null && !Namespace.EFFECTIVE_RESOLVE.equals(effective)) {
- iRequirements.remove();
- } else {
-
- if (!wireRequirements.contains(requirement)) {
- if (!PackageNamespace.PACKAGE_NAMESPACE.equals(requirement.getNamespace())) {
- iRequirements.remove();
- } else {
- Object resolution = requirement.getDirectives().get(Namespace.REQUIREMENT_RESOLUTION_DIRECTIVE);
- if (!PackageNamespace.RESOLUTION_DYNAMIC.equals(resolution)) {
- iRequirements.remove();
- }
- }
+ return true;
+ }
+ if (!wireRequirements.contains(requirement)) {
+ if (!PackageNamespace.PACKAGE_NAMESPACE.equals(requirement.getNamespace())) {
+ return true;
+ }
+ Object resolution = requirement.getDirectives().get(Namespace.REQUIREMENT_RESOLUTION_DIRECTIVE);
+ if (!PackageNamespace.RESOLUTION_DYNAMIC.equals(resolution)) {
+ return true;
}
}
- }
+ return false;
+ });
}
- void removeNonEffectiveCapabilities(ListIterator<ModuleCapability> iCapabilities) {
- rewind(iCapabilities);
- while (iCapabilities.hasNext()) {
- Capability capability = iCapabilities.next();
+ void removeNonEffectiveCapabilities(Collection<ModuleCapability> capabilities) {
+ capabilities.removeIf(capability -> {
Object effective = capability.getDirectives().get(Namespace.CAPABILITY_EFFECTIVE_DIRECTIVE);
if (effective != null && !Namespace.EFFECTIVE_RESOLVE.equals(effective)) {
- iCapabilities.remove();
if (DEBUG_PROVIDERS) {
Debug.println(new StringBuilder("RESOLVER: Capability filtered because it was not effective") //$NON-NLS-1$
.append(SEPARATOR).append(TAB) //
@@ -350,56 +324,41 @@ final class ModuleResolver {
.append(capability.getResource()) //
.toString());
}
+ return true;
}
- }
+ return false;
+ });
}
- private static void addPayloadContent(List<ModuleWire> hostWires, ListIterator<ModuleCapability> iCapabilities, ListIterator<ModuleRequirement> iRequirements) {
+ private static void addPayloadContent(List<ModuleWire> hostWires, NamespaceList.Builder<ModuleCapability> capabilities, NamespaceList.Builder<ModuleRequirement> requirements) {
if (hostWires == null)
return;
for (ModuleWire hostWire : hostWires) {
+
// add fragment capabilities
- String currentNamespace = null;
- List<ModuleCapability> fragmentCapabilities = hostWire.getRequirer().getModuleCapabilities(null);
- for (ModuleCapability fragmentCapability : fragmentCapabilities) {
- if (NON_PAYLOAD_CAPABILITIES.contains(fragmentCapability.getNamespace())) {
- continue; // don't include, not a payload capability
- }
- if (!fragmentCapability.getNamespace().equals(currentNamespace)) {
- currentNamespace = fragmentCapability.getNamespace();
- fastForward(iCapabilities);
- while (iCapabilities.hasPrevious()) {
- if (iCapabilities.previous().getNamespace().equals(currentNamespace)) {
- iCapabilities.next(); // put position after the last one
- break;
- }
- }
- }
- iCapabilities.add(fragmentCapability);
- }
+ NamespaceList<ModuleCapability> fragmentCapabilities = hostWire.getRequirer().getCapabilities();
+ capabilities.addAllFiltered(fragmentCapabilities,
+
+ n -> !NON_PAYLOAD_CAPABILITIES.contains(n),
+
+ fc -> { // don't include, not effective
+ Object effective = fc.getDirectives().get(Namespace.CAPABILITY_EFFECTIVE_DIRECTIVE);
+ return effective == null || Namespace.EFFECTIVE_RESOLVE.equals(effective);
+ });
+
// add fragment requirements
- currentNamespace = null;
- List<ModuleRequirement> fragmentRequriements = hostWire.getRequirer().getModuleRequirements(null);
- for (ModuleRequirement fragmentRequirement : fragmentRequriements) {
- if (NON_PAYLOAD_REQUIREMENTS.contains(fragmentRequirement.getNamespace())) {
- continue; // don't inlcude, not a payload requirement
- }
- if (!fragmentRequirement.getNamespace().equals(currentNamespace)) {
- currentNamespace = fragmentRequirement.getNamespace();
- boolean isDynamic = isDynamic(fragmentRequirement);
- fastForward(iRequirements);
- while (iRequirements.hasPrevious()) {
- ModuleRequirement previous = iRequirements.previous();
- if (previous.getNamespace().equals(currentNamespace)) {
- if (isDynamic || !isDynamic(previous)) {
- iRequirements.next(); // put position after the last one
- break;
- }
- }
- }
- }
- iRequirements.add(fragmentRequirement);
- }
+ NamespaceList<ModuleRequirement> fragmentRequriements = hostWire.getRequirer().getRequirements();
+ requirements.addAllFilteredAfterLastMatch(fragmentRequriements,
+
+ n -> !NON_PAYLOAD_REQUIREMENTS.contains(n),
+
+ fr -> { // don't include, not effective
+ Object effective = fr.getDirectives().get(Namespace.REQUIREMENT_EFFECTIVE_DIRECTIVE);
+ return !(effective != null && !Namespace.EFFECTIVE_RESOLVE.equals(effective));
+ },
+
+ (fr, r) -> !PackageNamespace.PACKAGE_NAMESPACE.equals(fr.getNamespace()) || isDynamic(fr)
+ || !isDynamic(r));
}
}
@@ -407,61 +366,24 @@ final class ModuleResolver {
return PackageNamespace.PACKAGE_NAMESPACE.equals(requirement.getNamespace()) && PackageNamespace.RESOLUTION_DYNAMIC.equals(requirement.getDirectives().get(Namespace.REQUIREMENT_RESOLUTION_DIRECTIVE));
}
- private static void addProvidedWires(Map<ModuleCapability, List<ModuleWire>> toAdd, List<ModuleWire> existing, final List<ModuleCapability> orderedCapabilities) {
+ private static void addProvidedWires(Map<ModuleCapability, List<ModuleWire>> toAdd,
+ NamespaceList.Builder<ModuleWire> existing, NamespaceList.Builder<ModuleCapability> capabilities) {
if (toAdd == null)
return;
- int originalSize = existing.size();
- for (ModuleCapability capability : orderedCapabilities) {
+ for (ModuleCapability capability : capabilities) {
List<ModuleWire> newWires = toAdd.get(capability);
if (newWires != null) {
existing.addAll(newWires);
}
}
- if (originalSize != 0) {
- Collections.sort(existing, new Comparator<ModuleWire>() {
- @Override
- public int compare(ModuleWire w1, ModuleWire w2) {
- int index1 = orderedCapabilities.indexOf(w1.getCapability());
- int index2 = orderedCapabilities.indexOf(w2.getCapability());
- return index1 - index2;
- }
- });
- }
}
- private static void addRequiredWires(List<ModuleWire> toAdd, List<ModuleWire> existing, final List<ModuleRequirement> orderedRequirements) {
- if (toAdd == null)
- return;
- int originalSize = existing.size();
- existing.addAll(toAdd);
- if (originalSize != 0) {
- Collections.sort(existing, new Comparator<ModuleWire>() {
- @Override
- public int compare(ModuleWire w1, ModuleWire w2) {
- int index1 = orderedRequirements.indexOf(w1.getRequirement());
- int index2 = orderedRequirements.indexOf(w2.getRequirement());
- return index1 - index2;
- }
- });
- }
- }
-
- private static void fastForward(ListIterator<?> listIterator) {
- while (listIterator.hasNext())
- listIterator.next();
- }
-
- static void rewind(ListIterator<?> listIterator) {
- while (listIterator.hasPrevious())
- listIterator.previous();
- }
-
- private static ModuleWiring createWiringDelta(ModuleRevision revision, ModuleWiring existingWiring, Map<ModuleCapability, List<ModuleWire>> providedWireMap, List<ModuleWire> requiredWires) {
+ private static ModuleWiring createWiringDelta(ModuleRevision revision, ModuleWiring existingWiring, Map<ModuleCapability, List<ModuleWire>> providedWireMap, NamespaceList<ModuleWire> requiredWires) {
// No null checks are done here on the wires since this is a copy.
- List<ModuleWire> existingProvidedWires = existingWiring.getProvidedModuleWires(null);
- List<ModuleCapability> existingCapabilities = existingWiring.getModuleCapabilities(null);
- List<ModuleWire> existingRequiredWires = existingWiring.getRequiredModuleWires(null);
- List<ModuleRequirement> existingRequirements = existingWiring.getModuleRequirements(null);
+ NamespaceList.Builder<ModuleWire> existingProvidedWires = existingWiring.getProvidedWires().createBuilder();
+ NamespaceList.Builder<ModuleCapability> existingCapabilities = existingWiring.getCapabilities().createBuilder();
+ NamespaceList.Builder<ModuleWire> existingRequiredWires = existingWiring.getRequiredWires().createBuilder();
+ NamespaceList.Builder<ModuleRequirement> existingRequirements = existingWiring.getRequirements().createBuilder();
// First, add newly resolved fragment capabilities and requirements
if (providedWireMap != null) {
@@ -469,7 +391,7 @@ final class ModuleResolver {
ModuleCapability hostCapability = hostCapabilities.isEmpty() ? null : hostCapabilities.get(0);
List<ModuleWire> newHostWires = hostCapability == null ? null : providedWireMap.get(hostCapability);
if (newHostWires != null) {
- addPayloadContent(newHostWires, existingCapabilities.listIterator(), existingRequirements.listIterator());
+ addPayloadContent(newHostWires, existingCapabilities, existingRequirements);
}
}
@@ -478,10 +400,13 @@ final class ModuleResolver {
// Also need to include any new required wires that may have be added for fragment hosts
// Also will be needed for dynamic imports
- addRequiredWires(requiredWires, existingRequiredWires, existingRequirements);
+ if (requiredWires != null) {
+ existingRequiredWires.addAll(requiredWires);
+ }
InternalUtils.filterCapabilityPermissions(existingCapabilities);
- return new ModuleWiring(revision, existingCapabilities, existingRequirements, existingProvidedWires, existingRequiredWires, Collections.EMPTY_LIST);
+ return new ModuleWiring(revision, existingCapabilities.build(), existingRequirements.build(),
+ existingProvidedWires.build(), existingRequiredWires.build(), existingWiring.getSubstitutedNames());
}
static boolean isSingleton(ModuleRevision revision) {
@@ -540,7 +465,7 @@ final class ModuleResolver {
}
Map<Resource, ResolutionException> getUsesConstraintViolations() {
- return errors == null ? Collections.<Resource, ResolutionException> emptyMap() : errors;
+ return errors == null ? Collections.emptyMap() : errors;
}
@Override
@@ -563,12 +488,12 @@ final class ModuleResolver {
private final Collection<ModuleRevision> unresolved;
/*
* Contains unresolved revisions that should not be resolved as part of
- * this process. The reasons they should not be resolved will vary. For
+ * this process. The reasons they should not be resolved will vary. For
* example, some might have been filtered out by the resolver hook while
* others represent singleton collisions. It is assumed that all
* unresolved revisions are disabled at the start of the resolve
* process (see initialization in constructors). Any not filtered out
- * by ResolverHook.filterResolvable are then removed but may be added
+ * by ResolverHook.filterResolvable are then removed but may be added
* back later for other reasons.
*/
private final Collection<ModuleRevision> disabled;
@@ -589,7 +514,7 @@ final class ModuleResolver {
private AtomicReference<ScheduledFuture<?>> timoutFuture = new AtomicReference<>();
/*
* Used to generate the UNRESOLVED_PROVIDER resolution report entries.
- *
+ *
* The inner map associates a requirement to the set of all matching
* capabilities that were found. The outer map associates the requiring
* resource to the inner map so that its contents may easily be looked
@@ -672,17 +597,16 @@ final class ModuleResolver {
}
List<Capability> filterProviders(Requirement requirement, List<ModuleCapability> candidates, boolean filterResolvedHosts) {
- ListIterator<ModuleCapability> iCandidates = candidates.listIterator();
- filterDisabled(iCandidates);
- removeNonEffectiveCapabilities(iCandidates);
- removeSubstituted(iCandidates);
- filterPermissions((BundleRequirement) requirement, iCandidates);
+ filterDisabled(candidates);
+ removeNonEffectiveCapabilities(candidates);
+ removeSubstituted(candidates);
+ filterPermissions((BundleRequirement) requirement, candidates);
List<ModuleCapability> filteredMatches = null;
if (DEBUG_PROVIDERS || DEBUG_HOOKS) {
filteredMatches = new ArrayList<>(candidates);
}
- hook.filterMatches((BundleRequirement) requirement, InternalUtils.asListBundleCapability(candidates));
+ hook.filterMatches((BundleRequirement) requirement, InternalUtils.asList(candidates));
if (DEBUG_PROVIDERS || DEBUG_HOOKS) {
filteredMatches.removeAll(candidates);
if (!filteredMatches.isEmpty()) {
@@ -719,7 +643,7 @@ final class ModuleResolver {
filterFailedToResolve(candidates);
Collections.sort(candidates, this);
- return InternalUtils.asListCapability(candidates);
+ return InternalUtils.asList(candidates);
}
private void filterFailedToResolve(List<ModuleCapability> candidates) {
@@ -751,9 +675,8 @@ final class ModuleResolver {
}
}
- private void filterPermissions(BundleRequirement requirement, ListIterator<ModuleCapability> iCandidates) {
- rewind(iCandidates);
- if (System.getSecurityManager() == null || !iCandidates.hasNext()) {
+ private void filterPermissions(BundleRequirement requirement, List<ModuleCapability> candidates) {
+ if (System.getSecurityManager() == null) {
return;
}
@@ -762,18 +685,16 @@ final class ModuleResolver {
return;
}
- candidates: while (iCandidates.hasNext()) {
- ModuleCapability candidate = iCandidates.next();
+ candidates.removeIf(candidate -> {
// TODO this is a hack for when a bundle imports and exports the same package
if (PackageNamespace.PACKAGE_NAMESPACE.equals(requirement.getNamespace())) {
if (requirement.getRevision().equals(candidate.getRevision())) {
- continue candidates;
+ return false;
}
}
Permission requirePermission = InternalUtils.getRequirePermission(candidate);
Permission providePermission = InternalUtils.getProvidePermission(candidate);
if (!requirement.getRevision().getBundle().hasPermission(requirePermission)) {
- iCandidates.remove();
if (DEBUG_PROVIDERS) {
Debug.println(new StringBuilder("RESOLVER: Capability filtered because requirer did not have permission") //$NON-NLS-1$
.append(SEPARATOR).append(TAB) //
@@ -784,8 +705,8 @@ final class ModuleResolver {
.append(candidate.getResource()) //
.toString());
}
+ return true;
} else if (!candidate.getRevision().getBundle().hasPermission(providePermission)) {
- iCandidates.remove();
if (DEBUG_PROVIDERS) {
Debug.println(new StringBuilder("RESOLVER: Capability filtered because provider did not have permission") //$NON-NLS-1$
.append(SEPARATOR).append(TAB) //
@@ -796,16 +717,15 @@ final class ModuleResolver {
.append(candidate.getResource()) //
.toString());
}
+ return true;
}
- }
+ return false;
+ });
}
- private void filterDisabled(ListIterator<ModuleCapability> iCandidates) {
- rewind(iCandidates);
- while (iCandidates.hasNext()) {
- Capability capability = iCandidates.next();
+ private void filterDisabled(List<ModuleCapability> candidates) {
+ candidates.removeIf(capability -> {
if (disabled.contains(capability.getResource())) {
- iCandidates.remove();
if (DEBUG_PROVIDERS) {
Debug.println(new StringBuilder("RESOLVER: Capability filtered because it was disabled") //$NON-NLS-1$
.append(SEPARATOR).append(TAB) //
@@ -816,17 +736,16 @@ final class ModuleResolver {
.append(capability.getResource()) //
.toString());
}
+ return true;
}
- }
+ return false;
+ });
}
- private void removeSubstituted(ListIterator<ModuleCapability> iCapabilities) {
- rewind(iCapabilities);
- while (iCapabilities.hasNext()) {
- ModuleCapability capability = iCapabilities.next();
+ private void removeSubstituted(List<ModuleCapability> capabilities) {
+ capabilities.removeIf(capability -> {
ModuleWiring wiring = wirings.get(capability.getRevision());
if (wiring != null && wiring.isSubtituted(capability)) {
- iCapabilities.remove();
if (DEBUG_PROVIDERS) {
Debug.println(new StringBuilder("RESOLVER: Capability filtered because it was substituted") //$NON-NLS-1$
.append(SEPARATOR).append(TAB) //
@@ -837,8 +756,10 @@ final class ModuleResolver {
.append(capability.getResource()) //
.toString());
}
+ return true;
}
- }
+ return false;
+ });
}
@Override
@@ -890,12 +811,11 @@ final class ModuleResolver {
Collection<Resource> relatedFragments = new ArrayList<>();
for (String hostBSN : getHostBSNs(hostCaps)) {
String matchFilter = "(" + EquinoxFragmentNamespace.FRAGMENT_NAMESPACE + "=" + hostBSN + ")"; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
- Requirement fragmentRequirement = ModuleContainer.createRequirement(EquinoxFragmentNamespace.FRAGMENT_NAMESPACE, Collections.<String, String> singletonMap(Namespace.REQUIREMENT_FILTER_DIRECTIVE, matchFilter), Collections.<String, Object> emptyMap());
+ Requirement fragmentRequirement = ModuleContainer.createRequirement(EquinoxFragmentNamespace.FRAGMENT_NAMESPACE, Collections.singletonMap(Namespace.REQUIREMENT_FILTER_DIRECTIVE, matchFilter), Collections.emptyMap());
List<ModuleCapability> candidates = moduleDatabase.findCapabilities(fragmentRequirement);
// filter out disabled fragments and singletons
- filterDisabled(candidates.listIterator());
- for (Iterator<ModuleCapability> iCandidates = candidates.iterator(); iCandidates.hasNext();) {
- ModuleCapability candidate = iCandidates.next();
+ filterDisabled(candidates);
+ for (ModuleCapability candidate : candidates) {
ModuleRequirement hostReq = candidate.getRevision().getModuleRequirements(HostNamespace.HOST_NAMESPACE).get(0);
for (ModuleCapability hostCap : hostCaps) {
if (hostReq.matches(hostCap)) {
@@ -945,12 +865,12 @@ final class ModuleResolver {
threadResolving.set(Boolean.TRUE);
try {
try {
- hook = adaptor.getResolverHookFactory().begin(InternalUtils.asListBundleRevision((List<? extends BundleRevision>) triggers));
+ hook = adaptor.getResolverHookFactory().begin(InternalUtils.asList((List<? extends BundleRevision>) triggers));
} catch (RuntimeException e) {
if (e.getCause() instanceof BundleException) {
BundleException be = (BundleException) e.getCause();
if (be.getType() == BundleException.REJECTED_BY_HOOK) {
- return new ModuleResolutionReport(null, Collections.<Resource, List<Entry>> emptyMap(), new ResolutionException(be));
+ return new ModuleResolutionReport(null, Collections.emptyMap(), new ResolutionException(be));
}
}
throw e;
@@ -974,7 +894,7 @@ final class ModuleResolver {
Map<Resource, List<Wire>> dynamicAttachWirings = resolveNonPayLoadFragments();
applyInterimResultToWiringCopy(dynamicAttachWirings);
if (!dynamicAttachWirings.isEmpty()) {
- // be sure to remove the revisions from the optional and triggers
+ // be sure to remove the revisions from the optional and triggers
// so they no longer attempt to be resolved
Set<Resource> fragmentResources = dynamicAttachWirings.keySet();
triggers.removeAll(fragmentResources);
@@ -1181,7 +1101,7 @@ final class ModuleResolver {
private void computeUnresolvedProviderResolutionReportEntries(Map<Resource, List<Wire>> resolution) {
// Create a collection representing the resources asked to be
// resolved.
- Collection<Resource> shouldHaveResolvedResources = new ArrayList<Resource>(unresolved);
+ Collection<Resource> shouldHaveResolvedResources = new ArrayList<>(unresolved);
// Remove disabled resources.
shouldHaveResolvedResources.removeAll(disabled);
// Remove resolved resources, if necessary. The resolution will be
@@ -1303,6 +1223,9 @@ final class ModuleResolver {
}
private boolean failToWire(ModuleRequirement requirement, ModuleRevision requirer, List<Wire> wires) {
+ if (!isEffective(requirement)) {
+ return false;
+ }
List<ModuleCapability> matching = moduleDatabase.findCapabilities(requirement);
List<Wire> newWires = new ArrayList<>(0);
filterProviders(requirement, matching, false);
@@ -1356,13 +1279,8 @@ final class ModuleResolver {
if (dynamicAttachableFrags.isEmpty()) {
return Collections.emptyMap();
}
- Collections.sort(dynamicAttachableFrags, new Comparator<ModuleRevision>() {
- @Override
- public int compare(ModuleRevision r1, ModuleRevision r2) {
- // we only care about versions here
- return -(r1.getVersion().compareTo(r2.getVersion()));
- }
- });
+ // we only care about versions here
+ Collections.sort(dynamicAttachableFrags, Comparator.comparing(ModuleRevision::getVersion).reversed());
Map<ModuleCapability, DynamicFragments> hostDynamicFragments = new HashMap<>();
// first find the hosts to dynamically attach to
@@ -1399,12 +1317,13 @@ final class ModuleResolver {
}
private Map<Resource, List<Wire>> resolveDynamic() throws ResolutionException {
- return new ResolverImpl(new Logger(0), null).resolveDynamic(this, dynamicReq.getRevision().getWiring(), dynamicReq.getOriginal());
+ return new ResolverImpl(new Logger(0), null).resolveDynamic(this, wirings.get(dynamicReq.getResource()),
+ dynamicReq.getOriginal());
}
private void filterResolvable() {
Collection<ModuleRevision> enabledCandidates = new ArrayList<>(unresolved);
- hook.filterResolvable(InternalUtils.asListBundleRevision((List<? extends BundleRevision>) enabledCandidates));
+ hook.filterResolvable(InternalUtils.asList((List<? extends BundleRevision>) enabledCandidates));
// do this the hard way because the 'optimization' in removeAll hurts us
for (ModuleRevision enabledRevision : enabledCandidates) {
disabled.remove(enabledRevision);

Back to the top