diff options
author | Hannes Wellmann | 2021-05-01 07:21:54 +0000 |
---|---|---|
committer | Thomas Watson | 2021-07-12 18:40:30 +0000 |
commit | e592225cc0f760e394944b06addb65ef7be287c4 (patch) | |
tree | 094eaaee0725dcf7ed3710baf42abe2e0ba3d44d | |
parent | c9abe2161dd06e880bb655e000ea12e89b5b0602 (diff) | |
download | rt.equinox.framework-e592225cc0f760e394944b06addb65ef7be287c4.tar.gz rt.equinox.framework-e592225cc0f760e394944b06addb65ef7be287c4.tar.xz rt.equinox.framework-e592225cc0f760e394944b06addb65ef7be287c4.zip |
Bug 573026 - Apply NamespaceList to ModuleRevision and its builder
Change-Id: Ic3752324c8b166fbf06fdb76c3e3dd98b4e4a345
Signed-off-by: Hannes Wellmann <wellmann.hannes1@gmx.net>
Reviewed-on: https://git.eclipse.org/r/c/equinox/rt.equinox.framework/+/180178
Tested-by: Equinox Bot <equinox-bot@eclipse.org>
Reviewed-by: Thomas Watson <tjwatson@us.ibm.com>
13 files changed, 477 insertions, 157 deletions
diff --git a/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/org/eclipse/osgi/tests/hooks/framework/storage/a/TestHookConfigurator.java b/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/org/eclipse/osgi/tests/hooks/framework/storage/a/TestHookConfigurator.java index d25cb8ab4..1b95e51d1 100644 --- a/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/org/eclipse/osgi/tests/hooks/framework/storage/a/TestHookConfigurator.java +++ b/bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/org/eclipse/osgi/tests/hooks/framework/storage/a/TestHookConfigurator.java @@ -107,11 +107,9 @@ public class TestHookConfigurator implements HookConfigurator { builder.addCapability("test.file.path", dirs, attrs); } if (TestHookConfigurator.adaptCapabilityAttribute) { - for (GenericInfo c : builder.getCapabilities()) { - if (BundleNamespace.BUNDLE_NAMESPACE.equals(c.getNamespace())) { - c.getAttributes().put("matching.attribute", "testAttribute"); - c.getDirectives().put("matching.directive", "testDirective"); - } + for (GenericInfo c : builder.getCapabilities(BundleNamespace.BUNDLE_NAMESPACE)) { + c.getAttributes().put("matching.attribute", "testAttribute"); + c.getDirectives().put("matching.directive", "testDirective"); } } return builder; diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/NamespaceListBuilderTest.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/NamespaceListBuilderTest.java index 9e4553013..fdc33466c 100644 --- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/NamespaceListBuilderTest.java +++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/NamespaceListBuilderTest.java @@ -14,11 +14,14 @@ package org.eclipse.osgi.tests.container; import static org.eclipse.osgi.tests.container.NamespaceListTest.build; -import static org.eclipse.osgi.tests.container.NamespaceListTest.builderAddAfterLastMatch; import static org.eclipse.osgi.tests.container.NamespaceListTest.builderAddAll; +import static org.eclipse.osgi.tests.container.NamespaceListTest.builderAddAllFiltered; +import static org.eclipse.osgi.tests.container.NamespaceListTest.builderAddAllFilteredAfterLastMatch; import static org.eclipse.osgi.tests.container.NamespaceListTest.builderCreate; +import static org.eclipse.osgi.tests.container.NamespaceListTest.builderGetNamespaceElements; import static org.eclipse.osgi.tests.container.NamespaceListTest.builderRemoveElementsOfNamespaceIf; import static org.eclipse.osgi.tests.container.NamespaceListTest.builderRemoveNamespaceIf; +import static org.eclipse.osgi.tests.container.NamespaceListTest.builderTransformIntoCopy; import static org.eclipse.osgi.tests.container.NamespaceListTest.createEmptyNamespaceList; import static org.eclipse.osgi.tests.container.NamespaceListTest.getList; import static org.eclipse.osgi.tests.container.NamespaceListTest.newNamespace; @@ -26,6 +29,7 @@ import static org.eclipse.osgi.tests.container.NamespaceListTest.populate; import static org.eclipse.osgi.tests.container.NamespaceListTest.randomListSort; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; @@ -42,6 +46,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.NoSuchElementException; import java.util.function.Function; +import java.util.stream.Collectors; import org.eclipse.osgi.tests.container.NamespaceListTest.NamespaceElement; import org.junit.Test; @@ -219,6 +224,71 @@ public class NamespaceListBuilderTest { assertEquals(getList(namespaceList, "ns-1"), elements.subList(3, 6)); } + @Test + public void testGetNamespaceElements_contaiendNamespace() throws Exception { + List<NamespaceElement> elements = populate(3, 3); + + Collection<NamespaceElement> builder = builderCreate(); + builder.addAll(elements); + + List<NamespaceElement> namespaceElements = builderGetNamespaceElements(builder, "ns-1"); + assertEquals(namespaceElements, elements.subList(3, 6)); + } + + @Test + public void testGetNamespaceElements_nullNamespace() throws Exception { + List<NamespaceElement> elements = populate(3, 3); + + Collection<NamespaceElement> builder = builderCreate(); + builder.addAll(elements); + + List<NamespaceElement> namespaceElements = builderGetNamespaceElements(builder, null); + assertEquals(elements, namespaceElements); + } + + @Test + public void testGetNamespaceElements_notContainedNamespace() throws Exception { + List<NamespaceElement> elements = populate(3, 3); + Collection<NamespaceElement> builder = builderCreate(); + builder.addAll(elements); + + List<NamespaceElement> namespaceElements = builderGetNamespaceElements(builder, "ns-100"); + assertEquals(Collections.emptyList(), namespaceElements); + } + + @Test + public void testTransformIntoCopy_notEmptyBuilder() throws Exception { + List<NamespaceElement> elements = populate(3, 3); + + Collection<NamespaceElement> builder = builderCreate(); + builder.addAll(elements); + + Function<String, String> getNamespace = e -> e.substring(0, 4); + + Collection<String> transformedBuilder = builderTransformIntoCopy(builder, Object::toString, getNamespace); + + List<String> transformedElements = elements.stream().map(Object::toString).collect(Collectors.toList()); + assertStricEqualContent(transformedBuilder, transformedElements, getNamespace); + assertNotSame(builder, transformedBuilder); + // check that the original builder is not changed + assertStricEqualContent(builder, elements); + } + + @Test + public void testTransformIntoCopy_emptyBuilder() throws Exception { + + Collection<NamespaceElement> builder = builderCreate(); + + Function<String, String> getNamespace = e -> e.substring(0, 4); + + Collection<String> transformedBuilder = builderTransformIntoCopy(builder, Object::toString, getNamespace); + + assertNotSame(builder, transformedBuilder); + assertStricEqualContent(transformedBuilder, Collections.emptyList(), getNamespace); + // check that the original builder is not changed + assertStricEqualContent(builder, Collections.emptyList()); + } + // --- test addition --- @Test @@ -306,53 +376,162 @@ public class NamespaceListBuilderTest { } @Test - public void testAddAfterLastMatch_matchUpUntilTheMiddle() throws Exception { + public void testAddAll_builderArgument() throws Exception { + List<NamespaceElement> elements = populate(2, 2); + Collection<NamespaceElement> builder = builderCreate(); + builder.addAll(elements); + + Collection<NamespaceElement> builder2 = builderCreate(); + List<NamespaceElement> elements2 = populate(2, 2); + builder2.addAll(elements2); + + builder.addAll(builder2); + + elements.addAll(4, elements2.subList(2, 4)); + elements.addAll(2, elements2.subList(0, 2)); + + assertStricEqualContent(builder, elements); + } + + @Test + public void testAddAllFiltered_notEmptyBuilder() throws Exception { + List<NamespaceElement> elements = populate(4, 3); + + Collection<NamespaceElement> builder = builderCreate(); + builder.addAll(elements); + + List<NamespaceElement> newElements = new ArrayList<>(); + newElements.add(new NamespaceElement(0, "ns-1")); + newElements.add(new NamespaceElement(10, "ns-1")); + newElements.add(new NamespaceElement(2, "ns-20")); + newElements.add(new NamespaceElement(0, "ns-2")); + newElements.add(new NamespaceElement(2, "ns-0")); + newElements.add(new NamespaceElement(1, "ns-2")); + newElements.add(new NamespaceElement(10, "ns-20")); + newElements.add(new NamespaceElement(0, "ns-20")); + Object namespaceList = newNamespace(newElements); + + builderAddAllFiltered(builder, namespaceList, n -> !n.equals("ns-2"), e -> e.id < 10); + + List<NamespaceElement> expectedElements = new ArrayList<>(); + expectedElements.add(new NamespaceElement(0, "ns-0")); + expectedElements.add(new NamespaceElement(1, "ns-0")); + expectedElements.add(new NamespaceElement(2, "ns-0")); + expectedElements.add(new NamespaceElement(3, "ns-0")); + expectedElements.add(new NamespaceElement(2, "ns-0")); + + expectedElements.add(new NamespaceElement(0, "ns-1")); + expectedElements.add(new NamespaceElement(1, "ns-1")); + expectedElements.add(new NamespaceElement(2, "ns-1")); + expectedElements.add(new NamespaceElement(3, "ns-1")); + expectedElements.add(new NamespaceElement(0, "ns-1")); + + expectedElements.add(new NamespaceElement(0, "ns-2")); + expectedElements.add(new NamespaceElement(1, "ns-2")); + expectedElements.add(new NamespaceElement(2, "ns-2")); + expectedElements.add(new NamespaceElement(3, "ns-2")); + + expectedElements.add(new NamespaceElement(2, "ns-20")); + expectedElements.add(new NamespaceElement(0, "ns-20")); + + assertStricEqualContent(builder, expectedElements); + } + + @Test + public void testAddAllFiltered_emptyBuilder() throws Exception { + + Collection<NamespaceElement> builder = builderCreate(); + + List<NamespaceElement> newElements2 = new ArrayList<>(); + newElements2.add(new NamespaceElement(0, "ns-1")); + newElements2.add(new NamespaceElement(10, "ns-1")); + newElements2.add(new NamespaceElement(2, "ns-20")); + newElements2.add(new NamespaceElement(0, "ns-2")); + newElements2.add(new NamespaceElement(2, "ns-0")); + newElements2.add(new NamespaceElement(1, "ns-2")); + newElements2.add(new NamespaceElement(10, "ns-20")); + newElements2.add(new NamespaceElement(0, "ns-20")); + Object namespaceList = newNamespace(newElements2); + + builderAddAllFiltered(builder, namespaceList, n -> !n.equals("ns-2"), e -> e.id < 10); + + List<NamespaceElement> expectedElements = new ArrayList<>(); + expectedElements.add(new NamespaceElement(0, "ns-1")); + expectedElements.add(new NamespaceElement(2, "ns-20")); + expectedElements.add(new NamespaceElement(0, "ns-20")); + expectedElements.add(new NamespaceElement(2, "ns-0")); + + assertStricEqualContent(builder, expectedElements); + } + + @Test + public void testAddAllFiltered_allElementsOfNewNamespaceFiltered() throws Exception { + + Collection<NamespaceElement> builder = builderCreate(); + + List<NamespaceElement> newElements = new ArrayList<>(); + newElements.add(new NamespaceElement(10, "ns-1")); + newElements.add(new NamespaceElement(11, "ns-1")); + Object namespaceList = newNamespace(newElements); + + builderAddAllFiltered(builder, namespaceList, n -> true, e -> e.id < 5); + // All elements of namespace ns-1 are filtered + + assertStricEqualContent(builder, Collections.emptyList()); + } + + @Test + public void testAddAllFilteredAfterLastMatch_matchUpUntilTheMiddle() throws Exception { List<NamespaceElement> elements = populate(4, "ns-0"); Collection<NamespaceElement> builder = builderCreate(); builder.addAll(elements); NamespaceElement element = new NamespaceElement(5, "ns-0"); - builderAddAfterLastMatch(builder, element, e -> e.id < 2); + Object namespaceList = newNamespace(Collections.singletonList(element)); + builderAddAllFilteredAfterLastMatch(builder, namespaceList, n -> true, e -> true, (toAdd, e) -> e.id < 2); elements.add(2, element); assertStricEqualContent(builder, elements); } @Test - public void testAddAfterLastMatch_allElementsMatches() throws Exception { + public void testAddAllFilteredAfterLastMatch_allElementsMatches() throws Exception { List<NamespaceElement> elements = populate(4, "ns-0"); Collection<NamespaceElement> builder = builderCreate(); builder.addAll(elements); NamespaceElement element = new NamespaceElement(5, "ns-0"); - builderAddAfterLastMatch(builder, element, e -> true); + Object namespaceList = newNamespace(Collections.singletonList(element)); + builderAddAllFilteredAfterLastMatch(builder, namespaceList, n -> true, e -> true, (toAdd, e) -> true); elements.add(4, element); assertStricEqualContent(builder, elements); } @Test - public void testAddAfterLastMatch_noMatch() throws Exception { + public void testAddAllFilteredAfterLastMatch_noMatch() throws Exception { List<NamespaceElement> elements = populate(4, "ns-0"); Collection<NamespaceElement> builder = builderCreate(); builder.addAll(elements); NamespaceElement element = new NamespaceElement(5, "ns-0"); - builderAddAfterLastMatch(builder, element, e -> e.id > 100); + Object namespaceList = newNamespace(Collections.singletonList(element)); + builderAddAllFilteredAfterLastMatch(builder, namespaceList, n -> true, e -> true, (toAdd, e) -> e.id > 100); elements.add(0, element); assertStricEqualContent(builder, elements); } @Test - public void testAddAfterLastMatch_emptyNamespaceList() throws Exception { + public void testAddAllFilteredAfterLastMatch_emptyNamespaceList() throws Exception { Collection<NamespaceElement> builder = builderCreate(); NamespaceElement element = new NamespaceElement(5, "ns-0"); - builderAddAfterLastMatch(builder, element, e -> e.id < 2); + Object namespaceList = newNamespace(Collections.singletonList(element)); + builderAddAllFilteredAfterLastMatch(builder, namespaceList, n -> true, e -> true, (toAdd, e) -> e.id < 2); assertStricEqualContent(builder, Collections.singletonList(element)); } @@ -771,6 +950,7 @@ public class NamespaceListBuilderTest { String namespace = entry.getKey(); List<E> elements = entry.getValue(); assertEquals(elements, getList(namespaceList, namespace)); + assertEquals(elements, builderGetNamespaceElements(builder, namespace)); } assertEquals(expectedElements, getList(namespaceList, null)); @@ -794,6 +974,7 @@ public class NamespaceListBuilderTest { String namespace = entry.getKey(); List<NamespaceElement> elements = entry.getValue(); assertContentEquals(elements, getList(namespaceList, namespace)); + assertContentEquals(elements, builderGetNamespaceElements(builder, namespace)); } assertContentEquals(expectedElements, getList(namespaceList, null)); diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/NamespaceListTest.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/NamespaceListTest.java index 65a8af757..07a908e0f 100644 --- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/NamespaceListTest.java +++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/NamespaceListTest.java @@ -10,7 +10,7 @@ * * Contributors: * IBM Corporation - initial API and implementation - * Hannes Wellmann - Bug 573025: introduce and apply NamespaceList.Builder + * Hannes Wellmann - Bug 573025 & 573026: introduce and apply NamespaceList.Builder *******************************************************************************/ package org.eclipse.osgi.tests.container; @@ -26,6 +26,7 @@ import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Random; +import java.util.function.BiPredicate; import java.util.function.Function; import java.util.function.Predicate; import org.junit.Test; @@ -42,8 +43,11 @@ public class NamespaceListTest extends AbstractTest { // only access fields reflectively that are not part of the Collection-API static final Method BUILDER_CREATE; + static final Method BUILDER_GET_NAMESPACE_ELEMENTS; + static final Method BUILDER_TRANSFORM_INTO_COPY; static final Method BUILDER_ADD_ALL; - static final Method BUILDER_ADD_AFTER_LAST_MATCH; + static final Method BUILDER_ADD_ALL_FILTERED; + static final Method BUILDER_ADD_ALL_FILTERED_AFTER_LAST_MATCH; static final Method BUILDER_REMOVE_NAMESPACE_IF; static final Method BUILDER_REMOVE_ELEMENTS_OF_NAMESPACE_IF; static final Method BUILDER_BUILD; @@ -61,9 +65,14 @@ public class NamespaceListTest extends AbstractTest { NAMESPACELIST_CREATE_BUILDER = namespaceList.getMethod("createBuilder"); BUILDER_CREATE = namespaceListBuilder.getMethod("create", Function.class); + BUILDER_GET_NAMESPACE_ELEMENTS = namespaceListBuilder.getMethod("getNamespaceElements", String.class); + BUILDER_TRANSFORM_INTO_COPY = namespaceListBuilder.getMethod("transformIntoCopy", Function.class, + Function.class); BUILDER_ADD_ALL = namespaceListBuilder.getMethod("addAll", namespaceList); - BUILDER_ADD_AFTER_LAST_MATCH = namespaceListBuilder.getMethod("addAfterLastMatch", Object.class, + BUILDER_ADD_ALL_FILTERED = namespaceListBuilder.getMethod("addAllFiltered", namespaceList, Predicate.class, Predicate.class); + BUILDER_ADD_ALL_FILTERED_AFTER_LAST_MATCH = namespaceListBuilder.getMethod("addAllFilteredAfterLastMatch", + namespaceList, Predicate.class, Predicate.class, BiPredicate.class); BUILDER_REMOVE_NAMESPACE_IF = namespaceListBuilder.getMethod("removeNamespaceIf", Predicate.class); BUILDER_REMOVE_ELEMENTS_OF_NAMESPACE_IF = namespaceListBuilder.getMethod("removeElementsOfNamespaceIf", String.class, Predicate.class); @@ -104,12 +113,29 @@ public class NamespaceListTest extends AbstractTest { return (Collection<NamespaceElement>) BUILDER_CREATE.invoke(null, getNamespace); } + static <E> List<E> builderGetNamespaceElements(Collection<E> builder, String namespace) throws Exception { + return (List<E>) BUILDER_GET_NAMESPACE_ELEMENTS.invoke(builder, namespace); + } + + static <T, R> Collection<R> builderTransformIntoCopy(Collection<T> builder, Function<T, R> transformation, + Function<R, String> newGetNamespace) throws Exception { + return (Collection<R>) BUILDER_TRANSFORM_INTO_COPY.invoke(builder, transformation, newGetNamespace); + } + static <E> void builderAddAll(Collection<E> builder, Object namespaceList) throws Exception { BUILDER_ADD_ALL.invoke(builder, namespaceList); } - static <E> void builderAddAfterLastMatch(Collection<E> builder, E e, Predicate<E> matcher) throws Exception { - BUILDER_ADD_AFTER_LAST_MATCH.invoke(builder, e, matcher); + static <E> void builderAddAllFiltered(Collection<E> builder, Object namespaceList, + Predicate<? super String> namespaceFilter, Predicate<E> elementFilter) throws Exception { + BUILDER_ADD_ALL_FILTERED.invoke(builder, namespaceList, namespaceFilter, elementFilter); + } + + static <E> void builderAddAllFilteredAfterLastMatch(Collection<E> builder, Object namespaceList, + Predicate<? super String> namespaceFilter, Predicate<E> elementFilter, BiPredicate<E, E> insertionMatcher) + throws Exception { + BUILDER_ADD_ALL_FILTERED_AFTER_LAST_MATCH.invoke(builder, namespaceList, namespaceFilter, elementFilter, + insertionMatcher); } static <E> void builderRemoveNamespaceIf(Collection<E> builder, Predicate<String> filter) throws Exception { diff --git a/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF b/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF index c721058eb..0edabb25e 100644 --- a/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.osgi/META-INF/MANIFEST.MF @@ -104,7 +104,7 @@ Bundle-Activator: org.eclipse.osgi.internal.framework.SystemBundleActivator Bundle-Description: %systemBundle Bundle-Copyright: %copyright Bundle-Vendor: %eclipse.org -Bundle-Version: 3.16.400.qualifier +Bundle-Version: 3.17.0.qualifier Bundle-Localization: systembundle Bundle-DocUrl: http://www.eclipse.org Eclipse-ExtensibleAPI: true diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleDatabase.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleDatabase.java index 108714d05..3b537f487 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleDatabase.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleDatabase.java @@ -249,20 +249,18 @@ public class ModuleDatabase { if ((builder.getTypes() & BundleRevision.TYPE_FRAGMENT) != 0) { return null; } - for (GenericInfo info : builder.getCapabilities()) { - if (EquinoxModuleDataNamespace.MODULE_DATA_NAMESPACE.equals(info.getNamespace())) { - if (EquinoxModuleDataNamespace.CAPABILITY_ACTIVATION_POLICY_LAZY.equals(info.getAttributes().get(EquinoxModuleDataNamespace.CAPABILITY_ACTIVATION_POLICY))) { - String compatibilityStartLazy = adaptor.getProperty(EquinoxConfiguration.PROP_COMPATIBILITY_START_LAZY); - if (compatibilityStartLazy == null || Boolean.valueOf(compatibilityStartLazy)) { - // TODO hack until p2 is fixed (bug 177641) - EnumSet<Settings> settings = EnumSet.noneOf(Settings.class); - settings.add(Settings.USE_ACTIVATION_POLICY); - settings.add(Settings.AUTO_START); - return settings; - } + for (GenericInfo info : builder.getCapabilities(EquinoxModuleDataNamespace.MODULE_DATA_NAMESPACE)) { + if (EquinoxModuleDataNamespace.CAPABILITY_ACTIVATION_POLICY_LAZY.equals(info.getAttributes().get(EquinoxModuleDataNamespace.CAPABILITY_ACTIVATION_POLICY))) { + String compatibilityStartLazy = adaptor.getProperty(EquinoxConfiguration.PROP_COMPATIBILITY_START_LAZY); + if (compatibilityStartLazy == null || Boolean.valueOf(compatibilityStartLazy)) { + // TODO hack until p2 is fixed (bug 177641) + EnumSet<Settings> settings = EnumSet.noneOf(Settings.class); + settings.add(Settings.USE_ACTIVATION_POLICY); + settings.add(Settings.AUTO_START); + return settings; } - return null; } + return null; } return null; } 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 91eebcf11..bf8260712 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 @@ -13,8 +13,6 @@ *******************************************************************************/ package org.eclipse.osgi.container; -import static org.eclipse.osgi.internal.container.NamespaceList.CAPABILITY; -import static org.eclipse.osgi.internal.container.NamespaceList.REQUIREMENT; import static org.eclipse.osgi.internal.container.NamespaceList.WIRE; import java.security.Permission; @@ -46,7 +44,6 @@ 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.container.NamespaceList.Builder; import org.eclipse.osgi.internal.debug.Debug; import org.eclipse.osgi.internal.framework.EquinoxConfiguration; import org.eclipse.osgi.internal.framework.EquinoxContainer; @@ -234,10 +231,8 @@ final class ModuleResolver { Map<ModuleCapability, List<ModuleWire>> providedWireMap = provided.getOrDefault(revision, Collections.emptyMap()); NamespaceList<ModuleWire> requiredWires = required.getOrDefault(revision, NamespaceList.empty(WIRE)); - NamespaceList.Builder<ModuleCapability> capabilities = Builder.create(CAPABILITY); - capabilities.addAll(revision.getModuleCapabilities(null)); - NamespaceList.Builder<ModuleRequirement> requirements = Builder.create(REQUIREMENT); - requirements.addAll(revision.getModuleRequirements(null)); + 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) { @@ -341,35 +336,29 @@ final class ModuleResolver { for (ModuleWire hostWire : hostWires) { // add fragment capabilities - 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 - } - Object effective = fragmentCapability.getDirectives().get(Namespace.CAPABILITY_EFFECTIVE_DIRECTIVE); - if (effective != null && !Namespace.EFFECTIVE_RESOLVE.equals(effective)) { - continue; // don't include, not effective - } - capabilities.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 - List<ModuleRequirement> fragmentRequriements = hostWire.getRequirer().getModuleRequirements(null); - for (ModuleRequirement fragmentRequirement : fragmentRequriements) { - if (NON_PAYLOAD_REQUIREMENTS.contains(fragmentRequirement.getNamespace())) { - continue; // don't include, not a payload requirement - } - Object effective = fragmentRequirement.getDirectives().get(Namespace.REQUIREMENT_EFFECTIVE_DIRECTIVE); - if (effective != null && !Namespace.EFFECTIVE_RESOLVE.equals(effective)) { - continue; // don't include, not effective - } - if (!PackageNamespace.PACKAGE_NAMESPACE.equals(fragmentRequirement.getNamespace()) - || isDynamic(fragmentRequirement)) { - requirements.add(fragmentRequirement); - } else { - requirements.addAfterLastMatch(fragmentRequirement, r -> !isDynamic(r)); - } - } + 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)); } } diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleRevision.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleRevision.java index b7261b480..86f927087 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleRevision.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleRevision.java @@ -13,7 +13,6 @@ *******************************************************************************/ package org.eclipse.osgi.container; -import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -23,6 +22,7 @@ import java.util.Set; import org.eclipse.osgi.container.ModuleRevisionBuilder.GenericInfo; import org.eclipse.osgi.container.namespaces.EquinoxModuleDataNamespace; import org.eclipse.osgi.internal.container.InternalUtils; +import org.eclipse.osgi.internal.container.NamespaceList; import org.osgi.framework.Bundle; import org.osgi.framework.Version; import org.osgi.framework.namespace.IdentityNamespace; @@ -40,13 +40,13 @@ public final class ModuleRevision implements BundleRevision { private final String symbolicName; private final Version version; private final int types; - private final List<ModuleCapability> capabilities; - private final List<ModuleRequirement> requirements; + private final NamespaceList<ModuleCapability> capabilities; + private final NamespaceList<ModuleRequirement> requirements; private final ModuleRevisions revisions; private final Object revisionInfo; private volatile Boolean lazyActivationPolicy = null; - ModuleRevision(String symbolicName, Version version, int types, List<GenericInfo> capabilityInfos, List<GenericInfo> requirementInfos, ModuleRevisions revisions, Object revisionInfo) { + ModuleRevision(String symbolicName, Version version, int types, NamespaceList.Builder<GenericInfo> capabilityInfos, NamespaceList.Builder<GenericInfo> requirementInfos, ModuleRevisions revisions, Object revisionInfo) { this.symbolicName = symbolicName; this.version = version; this.types = types; @@ -56,18 +56,12 @@ public final class ModuleRevision implements BundleRevision { this.revisionInfo = revisionInfo; } - private List<ModuleCapability> createCapabilities(List<GenericInfo> capabilityInfos) { - if (capabilityInfos == null || capabilityInfos.isEmpty()) - return Collections.emptyList(); - List<ModuleCapability> result = new ArrayList<>(capabilityInfos.size()); - for (GenericInfo info : capabilityInfos) { - if (info.mutable) { - result.add(new ModuleCapability(info.namespace, copyUnmodifiableMap(info.directives), copyUnmodifiableMap(info.attributes), this)); - } else { - result.add(new ModuleCapability(info.namespace, info.directives, info.attributes, this)); - } - } - return result; + private NamespaceList<ModuleCapability> createCapabilities(NamespaceList.Builder<GenericInfo> capabilityInfos) { + return capabilityInfos.transformIntoCopy(i -> { + Map<String, String> directives = i.mutable ? copyUnmodifiableMap(i.directives) : i.directives; + Map<String, Object> attributes = i.mutable ? copyUnmodifiableMap(i.attributes) : i.attributes; + return new ModuleCapability(i.namespace, directives, attributes, this); + }, NamespaceList.CAPABILITY).build(); } private static <K, V> Map<K, V> copyUnmodifiableMap(Map<K, V> map) { @@ -82,14 +76,9 @@ public final class ModuleRevision implements BundleRevision { return Collections.unmodifiableMap(new HashMap<>(map)); } - private List<ModuleRequirement> createRequirements(List<GenericInfo> requirementInfos) { - if (requirementInfos == null || requirementInfos.isEmpty()) - return Collections.emptyList(); - List<ModuleRequirement> result = new ArrayList<>(requirementInfos.size()); - for (GenericInfo info : requirementInfos) { - result.add(new ModuleRequirement(info.namespace, info.directives, info.attributes, this)); - } - return result; + private NamespaceList<ModuleRequirement> createRequirements(NamespaceList.Builder<GenericInfo> infos) { + return infos.transformIntoCopy(i -> new ModuleRequirement(i.namespace, i.directives, i.attributes, this), + NamespaceList.REQUIREMENT).build(); } @Override @@ -124,15 +113,7 @@ public final class ModuleRevision implements BundleRevision { * @return An unmodifiable list containing the declared capabilities. */ public List<ModuleCapability> getModuleCapabilities(String namespace) { - if (namespace == null) - return Collections.unmodifiableList(capabilities); - List<ModuleCapability> result = new ArrayList<>(); - for (ModuleCapability capability : capabilities) { - if (namespace.equals(capability.getNamespace())) { - result.add(capability); - } - } - return Collections.unmodifiableList(result); + return capabilities.getList(namespace); } /** @@ -142,15 +123,7 @@ public final class ModuleRevision implements BundleRevision { * @return An unmodifiable list containing the declared requirements. */ public List<ModuleRequirement> getModuleRequirements(String namespace) { - if (namespace == null) - return Collections.unmodifiableList(requirements); - List<ModuleRequirement> result = new ArrayList<>(); - for (ModuleRequirement requirement : requirements) { - if (namespace.equals(requirement.getNamespace())) { - result.add(requirement); - } - } - return Collections.unmodifiableList(result); + return requirements.getList(namespace); } @Override @@ -239,7 +212,7 @@ public final class ModuleRevision implements BundleRevision { if (value instanceof List) { @SuppressWarnings("unchecked") List<Object> list = (List<Object>) value; - if (list.size() == 0) + if (list.isEmpty()) continue; Object component = list.get(0); String className = component.getClass().getName(); @@ -260,4 +233,12 @@ public final class ModuleRevision implements BundleRevision { } return sb.toString(); } + + NamespaceList<ModuleCapability> getCapabilities() { + return capabilities; + } + + NamespaceList<ModuleRequirement> getRequirements() { + return requirements; + } } diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleRevisionBuilder.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleRevisionBuilder.java index 0d9b6f37e..7549469a9 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleRevisionBuilder.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleRevisionBuilder.java @@ -14,12 +14,13 @@ package org.eclipse.osgi.container; import java.security.AllPermission; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; +import org.eclipse.osgi.internal.container.NamespaceList; +import org.eclipse.osgi.internal.container.NamespaceList.Builder; import org.eclipse.osgi.internal.framework.FilterImpl; import org.osgi.framework.AdminPermission; import org.osgi.framework.Bundle; @@ -89,8 +90,8 @@ public final class ModuleRevisionBuilder { private String symbolicName = null; private Version version = Version.emptyVersion; private int types = 0; - private final List<GenericInfo> capabilityInfos = new ArrayList<>(); - private final List<GenericInfo> requirementInfos = new ArrayList<>(); + private final NamespaceList.Builder<GenericInfo> capabilityInfos = Builder.create(GenericInfo::getNamespace); + private final NamespaceList.Builder<GenericInfo> requirementInfos = Builder.create(GenericInfo::getNamespace); private long id = -1; /** @@ -166,7 +167,20 @@ public final class ModuleRevisionBuilder { * @return the capabilities */ public List<GenericInfo> getCapabilities() { - return new ArrayList<>(capabilityInfos); + return getCapabilities(null); + } + + /** + * Returns a snapshot of the capabilities in the given namespace for this + * builder + * + * @param namespace The namespace of the capabilities to return or null to + * return the capabilities from all namespaces. + * @return the capabilities + * @since 3.17 + */ + public List<GenericInfo> getCapabilities(String namespace) { + return capabilityInfos.getNamespaceElements(namespace); } /** @@ -184,7 +198,24 @@ public final class ModuleRevisionBuilder { * @return the requirements */ public List<GenericInfo> getRequirements() { - return new ArrayList<>(requirementInfos); + return getRequirements(null); + } + + NamespaceList.Builder<GenericInfo> getRequirementsBuilder() { + return requirementInfos; + } + + /** + * Returns a snapshot of the requirements in the given namespace for this + * builder + * + * @param namespace The namespace of the requirements to return or null to + * return the requirements from all namespaces. + * @return the requirements + * @since 3.17 + */ + public List<GenericInfo> getRequirements(String namespace) { + return requirementInfos.getNamespaceElements(namespace); } /** @@ -289,18 +320,14 @@ public final class ModuleRevisionBuilder { module.getContainer().checkAdminPermission(module.getBundle(), AdminPermission.EXTENSIONLIFECYCLE); } } - } catch (InvalidSyntaxException e) { - continue; + } catch (InvalidSyntaxException e) { // ignore } } } } } - private void addGenericInfo(List<GenericInfo> infos, String namespace, Map<String, String> directives, Map<String, Object> attributes) { - if (infos == null) { - infos = new ArrayList<>(); - } + private void addGenericInfo(NamespaceList.Builder<GenericInfo> infos, String namespace, Map<String, String> directives, Map<String, Object> attributes) { infos.add(new GenericInfo(namespace, directives, attributes, true)); } @@ -312,7 +339,7 @@ public final class ModuleRevisionBuilder { basicAddGenericInfo(requirementInfos, namespace, directives, attributes); } - private static void basicAddGenericInfo(List<GenericInfo> infos, String namespace, Map<String, String> directives, Map<String, Object> attributes) { + private static void basicAddGenericInfo(NamespaceList.Builder<GenericInfo> infos, String namespace, Map<String, String> directives, Map<String, Object> attributes) { infos.add(new GenericInfo(namespace, unmodifiableMap(directives), unmodifiableMap(attributes), false)); } diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleWiring.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleWiring.java index 9e6777e9e..3772f1108 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleWiring.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleWiring.java @@ -405,9 +405,8 @@ public final class ModuleWiring implements BundleWiring { * @param builder the builder that defines the new dynamic imports. */ public void addDynamicImports(ModuleRevisionBuilder builder) { - List<GenericInfo> newImports = builder.getRequirements(); - List<ModuleRequirement> newRequirements = new ArrayList<>(); - for (GenericInfo info : newImports) { + NamespaceList.Builder<GenericInfo> newImports = builder.getRequirementsBuilder(); + NamespaceList.Builder<ModuleRequirement> newRequirements = newImports.transformIntoCopy(info -> { if (!PackageNamespace.PACKAGE_NAMESPACE.equals(info.getNamespace())) { throw new IllegalArgumentException("Invalid namespace for package imports: " + info.getNamespace()); //$NON-NLS-1$ } @@ -415,8 +414,9 @@ public final class ModuleWiring implements BundleWiring { Map<String, String> directives = new HashMap<>(info.getDirectives()); directives.put(DYNAMICALLY_ADDED_IMPORT_DIRECTIVE, "true"); //$NON-NLS-1$ directives.put(PackageNamespace.REQUIREMENT_RESOLUTION_DIRECTIVE, PackageNamespace.RESOLUTION_DYNAMIC); - newRequirements.add(new ModuleRequirement(info.getNamespace(), directives, attributes, revision)); - } + return new ModuleRequirement(info.getNamespace(), directives, attributes, revision); + }, NamespaceList.REQUIREMENT); + ModuleDatabase moduleDatabase = revision.getRevisions().getContainer().moduleDatabase; moduleDatabase.writeLock(); try { diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectHookConfigurator.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectHookConfigurator.java index a7e764c64..a5f5a656e 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectHookConfigurator.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectHookConfigurator.java @@ -89,24 +89,21 @@ public class ConnectHookConfigurator implements HookConfigurator { @Override public ModuleRevisionBuilder adaptModuleRevisionBuilder(ModuleEvent operation, Module origin, ModuleRevisionBuilder builder) { if (m != null) { - builder.getCapabilities() - .stream() // - .filter(c -> CONNECT_TAG_NAMESPACES.contains(c.getNamespace())) // - .forEach((c) -> { - c.getAttributes().compute(IdentityNamespace.CAPABILITY_TAGS_ATTRIBUTE, (k, v) -> { - if (v == null) { - return Collections.singletonList(ConnectContent.TAG_OSGI_CONNECT); - } - if (v instanceof List) { - @SuppressWarnings({"unchecked", "rawtypes"}) - List<String> l = new ArrayList<>((List) v); - l.add(ConnectContent.TAG_OSGI_CONNECT); - return Collections.unmodifiableList(l); - } - // should not get here, but just recover - return Arrays.asList(v, ConnectContent.TAG_OSGI_CONNECT); - }); - }); + CONNECT_TAG_NAMESPACES.stream().map(builder::getCapabilities).flatMap(List::stream) + .forEach(c -> c.getAttributes().compute(IdentityNamespace.CAPABILITY_TAGS_ATTRIBUTE, + (k, v) -> { + if (v == null) { + return Collections.singletonList(ConnectContent.TAG_OSGI_CONNECT); + } + if (v instanceof List) { + @SuppressWarnings({ "unchecked", "rawtypes" }) + List<String> l = new ArrayList<>((List) v); + l.add(ConnectContent.TAG_OSGI_CONNECT); + return Collections.unmodifiableList(l); + } + // should not get here, but just recover + return Arrays.asList(v, ConnectContent.TAG_OSGI_CONNECT); + })); return builder; } return null; diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/container/NamespaceList.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/container/NamespaceList.java index ce320de75..e23ef3f2c 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/container/NamespaceList.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/container/NamespaceList.java @@ -10,7 +10,7 @@ * * Contributors: * IBM Corporation - initial API and implementation - * Hannes Wellmann - Bug 573025: introduce and apply NamespaceList.Builder + * Hannes Wellmann - Bug 573025 & 573026: introduce and apply NamespaceList.Builder *******************************************************************************/ package org.eclipse.osgi.internal.container; @@ -23,6 +23,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; +import java.util.function.BiPredicate; import java.util.function.Function; import java.util.function.Predicate; import org.eclipse.osgi.container.ModuleCapability; @@ -200,6 +201,56 @@ public class NamespaceList<E> { size = 0; } + /** + * Returns an immutable list of elements with the specified namespace in this + * builder. + * <p> + * An empty list is returned if there are no elements with the specified + * namespace. For the {@code null} namespace the elements of all namespaces are + * returned as flat. + * </p> + * + * @param namespace the namespace of the elements to return. May be {@code null} + * @return the list of element with the specified namespace + */ + public List<E> getNamespaceElements(String namespace) { + if (namespace == null) { + List<E> list = new ArrayList<>(size); + namespaceElements.values().forEach(list::addAll); + return Collections.unmodifiableList(list); + } + List<E> namespaceList = namespaceElements.get(namespace); + return namespaceList != null ? Collections.unmodifiableList(new ArrayList<>(namespaceList)) + : Collections.emptyList(); + } + + /** + * Returns a new builder whose content is the result of applying the specified + * transformation to each element of this builder. + * <p> + * It is assumed that the transformation does not change the element's + * namespace, so the namespace of original and transformed element are the same! + * This builder is not modified. + * </p> + * + * @param <R> the type of elements in the returned builder + * @param transformation the transformation applied to each element + * @param newGetNamespace the function to compute the namespace of a transformed + * element + * @return a new builder containing the result of applying the transformation to + * each element in this builder + */ + public <R> Builder<R> transformIntoCopy(Function<E, R> transformation, Function<R, String> newGetNamespace) { + Builder<R> transformedBuilder = new Builder<>(newGetNamespace, this.namespaceElements.size()); + transformedBuilder.size = this.size; + this.namespaceElements.forEach((n, es) -> { + List<R> transformedElements = new ArrayList<>(es.size()); + es.forEach(e -> transformedElements.add(transformation.apply(e))); + transformedBuilder.namespaceElements.put(n, transformedElements); + }); + return transformedBuilder; + } + // --- addition --- @Override @@ -219,6 +270,11 @@ public class NamespaceList<E> { } prepareModification(); + if (c instanceof Builder) { + @SuppressWarnings("unchecked") + Builder<E> builder = (Builder<E>) c; + return addAll(builder.namespaceElements); + } String currentNamespace = null; // $NON-NLS-1$ List<E> currentNamespaceList = null; for (E e : c) { @@ -246,7 +302,11 @@ public class NamespaceList<E> { } prepareModification(); - list.namespaces().forEach((n, es) -> { + return addAll(list.namespaces()); + } + + private boolean addAll(Map<String, List<E>> perNamespaceElements) { + perNamespaceElements.forEach((n, es) -> { getNamespaceList(n).addAll(es); this.size += es.size(); }); @@ -257,13 +317,77 @@ public class NamespaceList<E> { return namespaceElements.computeIfAbsent(namespace, n -> new ArrayList<>()); } - public void addAfterLastMatch(E toAdd, Predicate<E> matcher) { + /** + * Appends all elements in the specified NamespaceList to this builder that + * satisfy both specified predicates for themselves and their namespace. + * <p> + * For an element to be added both predicates, the one for the namespace as well + * as the one for the element itself must be satisfied. + * </p> + * + * @param list the NamespaceList containing elements to be added + * @param namespaceFilter the predicate that returns true for namespaces whose + * elements should not be excluded from being added + * @param elementFilter the predicate that returns true for elements to be + * added + * + */ + public void addAllFiltered(NamespaceList<E> list, Predicate<? super String> namespaceFilter, + Predicate<? super E> elementFilter) { + + addAllFilteredAfterLastMatch(list, namespaceFilter, elementFilter, null); + } + + /** + * Inserts all elements in the specified NamespaceList to this builder that + * satisfy both specified predicates for themselves and their namespace, after + * the last element in this builder for the corresponding namespace that + * satisfies the specified bi-predicate together with the corresponding element + * to be added. + * <p> + * For an element to be added both predicates, the one for the namespace as well + * as the one for the element itself must be satisfied. If both predicates are + * satisfied by an element of the specified list, it is added after the <em> + * last</em> element with the same namespace in this builder that satisfies the + * specified bi-predicate together with the element to add. + * </p> + * + * @param list the NamespaceList containing elements to be added + * @param namespaceFilter the predicate that returns true for namespaces whose + * elements should not be excluded from being added + * @param elementFilter the predicate that returns true for elements to be + * added + * @param insertionMatcher the bi-predicate whose first argument is the element + * to add and second argument is an element for the same + * namespace in this builder, which returns true if the + * element to add can be added after this builder's + * element + */ + public void addAllFilteredAfterLastMatch(NamespaceList<E> list, Predicate<? super String> namespaceFilter, + Predicate<? super E> elementFilter, BiPredicate<E, E> insertionMatcher) { + if (list.isEmpty()) { + return; + } prepareModification(); - String namespace = getNamespace.apply(toAdd); - List<E> namespaceList = getNamespaceList(namespace); - addAfterLastMatch(toAdd, namespaceList, matcher); - this.size++; + list.namespaces().forEach((namespace, elementsToAdd) -> { + if (namespaceFilter.test(namespace)) { + List<E> targetList = getNamespaceList(namespace); + for (E toAdd : elementsToAdd) { + if (elementFilter.test(toAdd)) { + if (insertionMatcher == null) { + targetList.add(toAdd); + } else { + addAfterLastMatch(toAdd, targetList, e -> insertionMatcher.test(toAdd, e)); + } + this.size++; + } + } + if (targetList.isEmpty()) { // maybe no elements are added + namespaceElements.remove(namespace); + } + } + }); } private void addAfterLastMatch(E e, List<E> list, Predicate<E> matcher) { diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/Storage.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/Storage.java index 34000ee59..19f988b41 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/Storage.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/Storage.java @@ -826,11 +826,10 @@ public class Storage { (generation.getContentType() == Type.CONNECT ? "" : null), //$NON-NLS-1$ (allowRestrictedProvides ? "" : null)); //$NON-NLS-1$ if ((builder.getTypes() & BundleRevision.TYPE_FRAGMENT) != 0) { - for (ModuleRevisionBuilder.GenericInfo reqInfo : builder.getRequirements()) { - if (HostNamespace.HOST_NAMESPACE.equals(reqInfo.getNamespace())) { - if (HostNamespace.EXTENSION_BOOTCLASSPATH.equals(reqInfo.getDirectives().get(HostNamespace.REQUIREMENT_EXTENSION_DIRECTIVE))) { - throw new BundleException("Boot classpath extensions are not supported.", BundleException.UNSUPPORTED_OPERATION, new UnsupportedOperationException()); //$NON-NLS-1$ - } + for (ModuleRevisionBuilder.GenericInfo reqInfo : builder.getRequirements(HostNamespace.HOST_NAMESPACE)) { + if (HostNamespace.EXTENSION_BOOTCLASSPATH.equals(reqInfo.getDirectives().get(HostNamespace.REQUIREMENT_EXTENSION_DIRECTIVE))) { + throw new BundleException("Boot classpath extensions are not supported.", //$NON-NLS-1$ + BundleException.UNSUPPORTED_OPERATION, new UnsupportedOperationException()); } } } diff --git a/bundles/org.eclipse.osgi/pom.xml b/bundles/org.eclipse.osgi/pom.xml index cbd9ecd38..c70978d44 100644 --- a/bundles/org.eclipse.osgi/pom.xml +++ b/bundles/org.eclipse.osgi/pom.xml @@ -19,7 +19,7 @@ </parent> <groupId>org.eclipse.osgi</groupId> <artifactId>org.eclipse.osgi</artifactId> - <version>3.16.400-SNAPSHOT</version> + <version>3.17.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> <build> |