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

Reply via email to