diff options
Diffstat (limited to 'bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleRevisionBuilder.java')
-rw-r--r-- | bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/container/ModuleRevisionBuilder.java | 108 |
1 files changed, 70 insertions, 38 deletions
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 67070e5f2..2c5493946 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012, 2017 IBM Corporation and others. + * Copyright (c) 2012, 2021 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -7,20 +7,21 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.osgi.container; import java.security.AllPermission; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.function.Function; +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; @@ -33,9 +34,9 @@ import org.osgi.framework.wiring.BundleRevision; import org.osgi.resource.Namespace; /** - * A builder for creating module {@link ModuleRevision} objects. A builder can only be used by - * the module {@link ModuleContainer container} to build revisions when - * {@link ModuleContainer#install(Module, String, ModuleRevisionBuilder, Object) + * A builder for creating module {@link ModuleRevision} objects. A builder can only be used by + * the module {@link ModuleContainer container} to build revisions when + * {@link ModuleContainer#install(Module, String, ModuleRevisionBuilder, Object) * installing} or {@link ModuleContainer#update(Module, ModuleRevisionBuilder, Object) updating} a module. * <p> * The builder provides the instructions to the container for creating a {@link ModuleRevision}. @@ -50,14 +51,21 @@ public final class ModuleRevisionBuilder { * Provides information about a capability or requirement */ public static class GenericInfo { + final static Function<GenericInfo, String> GETNAMESPACE = new Function<GenericInfo, String>() { + public String apply(GenericInfo info) { + return info.getNamespace(); + } + }; final String namespace; final Map<String, String> directives; final Map<String, Object> attributes; + final boolean mutable; - GenericInfo(String namespace, Map<String, String> directives, Map<String, Object> attributes) { + GenericInfo(String namespace, Map<String, String> directives, Map<String, Object> attributes, boolean mutable) { this.namespace = namespace; this.directives = directives; this.attributes = attributes; + this.mutable = mutable; } /** @@ -88,8 +96,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; /** @@ -165,7 +173,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); } /** @@ -183,7 +204,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); } /** @@ -248,6 +286,9 @@ public final class ModuleRevisionBuilder { } private void checkFrameworkExtensionPermission(Module module, ModuleRevision revision) { + if (System.getSecurityManager() == null) { + return; + } if ((revision.getTypes() & BundleRevision.TYPE_FRAGMENT) != 0) { Collection<?> systemNames = Collections.emptyList(); Module systemModule = module.getContainer().getModule(0); @@ -275,7 +316,8 @@ public final class ModuleRevisionBuilder { if (systemNames.contains(hostName)) { Bundle b = module.getBundle(); if (b != null && !b.hasPermission(new AllPermission())) { - SecurityException se = new SecurityException("Must have AllPermission granted to install an extension bundle"); //$NON-NLS-1$ + SecurityException se = new SecurityException( + "Must have AllPermission granted to install an extension bundle: " + b); //$NON-NLS-1$ // TODO this is such a hack: making the cause a bundle exception so we can throw the right one later BundleException be = new BundleException(se.getMessage(), BundleException.SECURITY_ERROR, se); se.initCause(be); @@ -284,31 +326,15 @@ public final class ModuleRevisionBuilder { module.getContainer().checkAdminPermission(module.getBundle(), AdminPermission.EXTENSIONLIFECYCLE); } } - } catch (InvalidSyntaxException e) { - continue; + } catch (InvalidSyntaxException e) { // ignore } } } } } - private static void addGenericInfo(List<GenericInfo> infos, String namespace, Map<String, String> directives, Map<String, Object> attributes) { - if (infos == null) { - infos = new ArrayList<>(); - } - infos.add(new GenericInfo(namespace, copyUnmodifiableMap(directives), copyUnmodifiableMap(attributes))); - } - - private static <K, V> Map<K, V> copyUnmodifiableMap(Map<K, V> map) { - int size = map.size(); - if (size == 0) { - return Collections.emptyMap(); - } - if (size == 1) { - Map.Entry<K, V> entry = map.entrySet().iterator().next(); - return Collections.singletonMap(entry.getKey(), entry.getValue()); - } - return Collections.unmodifiableMap(new HashMap<>(map)); + 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)); } void basicAddCapability(String namespace, Map<String, String> directives, Map<String, Object> attributes) { @@ -319,11 +345,8 @@ 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) { - if (infos == null) { - infos = new ArrayList<>(); - } - infos.add(new GenericInfo(namespace, unmodifiableMap(directives), unmodifiableMap(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)); } @SuppressWarnings("unchecked") @@ -335,7 +358,7 @@ public final class ModuleRevisionBuilder { if (size == 1) { if (map.getClass() != SINGLETON_MAP_CLASS) { Map.Entry<? extends K, ? extends V> entry = map.entrySet().iterator().next(); - map = Collections.<K, V> singletonMap(entry.getKey(), entry.getValue()); + map = Collections.singletonMap(entry.getKey(), entry.getValue()); } } else { if (map.getClass() != UNMODIFIABLE_MAP_CLASS) { @@ -344,4 +367,13 @@ public final class ModuleRevisionBuilder { } return (Map<K, V>) map; } + + void clear() { + capabilityInfos.clear(); + requirementInfos.clear(); + id = -1; + symbolicName = null; + version = Version.emptyVersion; + types = 0; + } } |