Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHannes Wellmann2021-05-01 07:21:54 +0000
committerThomas Watson2021-07-12 18:40:30 +0000
commite592225cc0f760e394944b06addb65ef7be287c4 (patch)
tree094eaaee0725dcf7ed3710baf42abe2e0ba3d44d
parentc9abe2161dd06e880bb655e000ea12e89b5b0602 (diff)
downloadrt.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>
-rw-r--r--bundles/org.eclipse.osgi.tests/bundles_src/storage.hooks.a/org/eclipse/osgi/tests/hooks/framework/storage/a/TestHookConfigurator.java8
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/NamespaceListBuilderTest.java199
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/NamespaceListTest.java36
-rw-r--r--bundles/org.eclipse.osgi/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleDatabase.java22
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleResolver.java57
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleRevision.java67
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleRevisionBuilder.java51
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleWiring.java10
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/connect/ConnectHookConfigurator.java33
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/container/NamespaceList.java138
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/storage/Storage.java9
-rw-r--r--bundles/org.eclipse.osgi/pom.xml2
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>

Back to the top