Fix problem with the same bundle being available in 2 unrelated features Project: http://git-wip-us.apache.org/repos/asf/karaf/repo Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/23f64732 Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/23f64732 Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/23f64732
Branch: refs/heads/master Commit: 23f647322be5df9478c84c21c3944a07f882d571 Parents: dc6f6be Author: Guillaume Nodet <[email protected]> Authored: Mon Jun 22 20:13:02 2015 +0200 Committer: Guillaume Nodet <[email protected]> Committed: Mon Jun 22 20:13:02 2015 +0200 ---------------------------------------------------------------------- .../region/SubsystemResolveContext.java | 46 +++++++++++++++----- .../features/internal/region/SubsystemTest.java | 22 ++++++++++ .../karaf/features/internal/region/data6/a.mf | 5 +++ .../karaf/features/internal/region/data6/b.mf | 5 +++ .../karaf/features/internal/region/data6/c.mf | 5 +++ .../features/internal/region/data6/features.xml | 42 ++++++++++++++++++ 6 files changed, 113 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/karaf/blob/23f64732/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolveContext.java ---------------------------------------------------------------------- diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolveContext.java b/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolveContext.java index c25d9f4..104fb24 100644 --- a/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolveContext.java +++ b/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolveContext.java @@ -161,26 +161,48 @@ public class SubsystemResolveContext extends ResolveContext { // need to remove the one from the child if it can view // the parent one if (caps.size() > 1) { - Map<String, Resource> providers = new HashMap<String, Resource>(); + Set<Resource> providers = new HashSet<>(); for (Capability cap : caps) { Resource resource = cap.getResource(); String id = ResolverUtil.getSymbolicName(resource) + "|" + ResolverUtil.getVersion(resource); - Resource prev = providers.get(id); - if (prev != null && prev != resource) { - String r1 = getRegion(prev).getName(); - String r2 = getRegion(resource).getName(); - int c = r1.compareTo(r2); - if (c == 0) { - // One of the resource has to be a bundle, use that one - c = (prev instanceof BundleRevision) ? -1 : +1; + if (!providers.contains(resource)) { + Set<Resource> newRes = new HashSet<>(); + String r1 = getRegion(resource).getName(); + boolean superceded = false; + for (Resource r : providers) { + String id2 = ResolverUtil.getSymbolicName(r) + "|" + ResolverUtil.getVersion(r); + if (id.equals(id2)) { + String r2 = getRegion(r).getName(); + if (r1.equals(r2)) { + if (r instanceof BundleRevision) { + newRes.add(r); + superceded = true; + } else if (resource instanceof BundleRevision) { + newRes.add(resource); + } else { + throw new InternalError(); + } + } else if (r1.startsWith(r2)) { + newRes.add(r); + superceded = true; + } else if (r2.startsWith(r1)) { + newRes.add(resource); + } else { + newRes.add(r); + } + } else { + newRes.add(r); + } } - resource = c < 0 ? prev : resource; + if (!superceded) { + newRes.add(resource); + } + providers = newRes; } - providers.put(id, resource); } for (Iterator<Capability> it = caps.iterator(); it.hasNext();) { Capability cap = it.next(); - if (!providers.values().contains(cap.getResource())) { + if (!providers.contains(cap.getResource())) { it.remove(); } } http://git-wip-us.apache.org/repos/asf/karaf/blob/23f64732/features/core/src/test/java/org/apache/karaf/features/internal/region/SubsystemTest.java ---------------------------------------------------------------------- diff --git a/features/core/src/test/java/org/apache/karaf/features/internal/region/SubsystemTest.java b/features/core/src/test/java/org/apache/karaf/features/internal/region/SubsystemTest.java index 846a2c9..d957ae6 100644 --- a/features/core/src/test/java/org/apache/karaf/features/internal/region/SubsystemTest.java +++ b/features/core/src/test/java/org/apache/karaf/features/internal/region/SubsystemTest.java @@ -231,6 +231,28 @@ public class SubsystemTest { verify(resolver, expected); } + @Test + public void testFeatureOptionalAlreadyProvided2() throws Exception { + RepositoryImpl repo = new RepositoryImpl(getClass().getResource("data6/features.xml").toURI()); + + Map<String, Set<String>> features = new HashMap<String, Set<String>>(); + addToMapSet(features, "root", "pax-http"); + addToMapSet(features, "root", "pax-http-tomcat"); + Map<String, Set<String>> expected = new HashMap<String, Set<String>>(); + addToMapSet(expected, "root", "a/1.0.0"); + addToMapSet(expected, "root", "c/1.0.0"); + + SubsystemResolver resolver = new SubsystemResolver(this.resolver, new TestDownloadManager(getClass(), "data6")); + resolver.prepare(Arrays.asList(repo.getFeatures()), + features, + Collections.<String, Set<BundleRevision>>emptyMap()); + resolver.resolve(Collections.<String>emptySet(), + FeaturesService.DEFAULT_FEATURE_RESOLUTION_RANGE, + null, null); + + verify(resolver, expected); + } + private void verify(SubsystemResolver resolver, Map<String, Set<String>> expected) { Map<String, Set<String>> mapping = getBundleNamesPerRegions(resolver); if (!expected.equals(mapping)) { http://git-wip-us.apache.org/repos/asf/karaf/blob/23f64732/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/a.mf ---------------------------------------------------------------------- diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/a.mf b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/a.mf new file mode 100644 index 0000000..20a7811 --- /dev/null +++ b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/a.mf @@ -0,0 +1,5 @@ +Manifest-Version: 1 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: a +Bundle-Version: 1.0.0 + http://git-wip-us.apache.org/repos/asf/karaf/blob/23f64732/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/b.mf ---------------------------------------------------------------------- diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/b.mf b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/b.mf new file mode 100644 index 0000000..dc96158 --- /dev/null +++ b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/b.mf @@ -0,0 +1,5 @@ +Manifest-Version: 1 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: b +Bundle-Version: 1.0.0 + http://git-wip-us.apache.org/repos/asf/karaf/blob/23f64732/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/c.mf ---------------------------------------------------------------------- diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/c.mf b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/c.mf new file mode 100644 index 0000000..8535efa --- /dev/null +++ b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/c.mf @@ -0,0 +1,5 @@ +Manifest-Version: 1 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: c +Bundle-Version: 1.0.0 + http://git-wip-us.apache.org/repos/asf/karaf/blob/23f64732/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/features.xml ---------------------------------------------------------------------- diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/features.xml b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/features.xml new file mode 100644 index 0000000..08982f7 --- /dev/null +++ b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/features.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--> +<features name="test" xmlns="http://karaf.apache.org/xmlns/features/v1.3.0"> + + <feature name="pax-http"> + <feature dependency="true">pax-http-jetty</feature> + <requirement>pax-http-provider</requirement> + </feature> + + <feature name="pax-jetty"> + <bundle>b</bundle> + </feature> + + <feature name="pax-http-jetty"> + <capability>pax-http-provider;provider:=jetty</capability> + <feature>pax-jetty</feature> + <bundle>a</bundle> + </feature> + + <feature name="pax-http-tomcat"> + <capability>pax-http-provider;provider:=tomcat</capability> + <bundle>c</bundle> + <bundle>a</bundle> + </feature> + +</features> \ No newline at end of file
