You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by jb...@apache.org on 2016/06/23 08:13:12 UTC

[1/2] karaf git commit: [KARAF-4571] Use version range in feature.xml if useVersionRange is true

Repository: karaf
Updated Branches:
  refs/heads/master ce69d7dfe -> 13d887424


[KARAF-4571] Use version range in feature.xml if useVersionRange is true


Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/f69e9b8f
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/f69e9b8f
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/f69e9b8f

Branch: refs/heads/master
Commit: f69e9b8f55a6447659a7c3bbef2d609af84631b9
Parents: ce69d7d
Author: Roland Hauser <so...@gmail.com>
Authored: Tue Jun 14 21:08:51 2016 +0200
Committer: Jean-Baptiste Onofr� <jb...@apache.org>
Committed: Thu Jun 23 09:34:43 2016 +0200

----------------------------------------------------------------------
 .../test-feature-use-base-version/control.xml   | 26 ++++++
 .../it/test-feature-use-base-version/pom.xml    | 48 ++++++++++
 .../it/test-feature-use-base-version/verify.bsh | 35 +++++++
 .../control.xml                                 | 28 ++++++
 .../feature/pom.xml                             | 52 +++++++++++
 .../pom.xml                                     | 33 +++++++
 .../transitive/pom.xml                          | 48 ++++++++++
 .../verify.bsh                                  | 35 +++++++
 .../test-feature-use-version-range/control.xml  | 27 ++++++
 .../it/test-feature-use-version-range/pom.xml   | 51 +++++++++++
 .../test-feature-use-version-range/verify.bsh   | 35 +++++++
 .../features/GenerateDescriptorMojo.java        | 96 ++++++++++++++++++--
 .../karaf/tooling/utils/Dependency30Helper.java | 82 +++++++++++------
 .../karaf/tooling/utils/Dependency31Helper.java | 53 +++++++----
 .../karaf/tooling/utils/DependencyHelper.java   | 16 +++-
 .../karaf/tooling/utils/LocalDependency.java    | 35 +++++++
 .../karaf/tooling/features/MavenUtilTest.java   | 27 ++++--
 17 files changed, 664 insertions(+), 63 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/f69e9b8f/tooling/karaf-maven-plugin/src/it/test-feature-use-base-version/control.xml
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/it/test-feature-use-base-version/control.xml b/tooling/karaf-maven-plugin/src/it/test-feature-use-base-version/control.xml
new file mode 100644
index 0000000..60e46d6
--- /dev/null
+++ b/tooling/karaf-maven-plugin/src/it/test-feature-use-base-version/control.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+  ~ 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 xmlns="http://karaf.apache.org/xmlns/features/v1.4.0" name="test-feature-use-base-version">
+    <feature name="test-feature-use-base-version" description="test-feature-use-base-version" version="1.0.0.SNAPSHOT">
+        <bundle>mvn:org.apache.commons/commons-lang3/3.4</bundle>
+    </feature>
+</features>
+

http://git-wip-us.apache.org/repos/asf/karaf/blob/f69e9b8f/tooling/karaf-maven-plugin/src/it/test-feature-use-base-version/pom.xml
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/it/test-feature-use-base-version/pom.xml b/tooling/karaf-maven-plugin/src/it/test-feature-use-base-version/pom.xml
new file mode 100644
index 0000000..c8b8dc9
--- /dev/null
+++ b/tooling/karaf-maven-plugin/src/it/test-feature-use-base-version/pom.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <!--
+
+        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.
+    -->
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>test</groupId>
+    <artifactId>test-feature-use-base-version</artifactId>
+    <version>1.0-SNAPSHOT</version>
+    <packaging>feature</packaging>
+
+	<dependencies>
+		<dependency>
+    		<groupId>org.apache.commons</groupId>
+    		<artifactId>commons-lang3</artifactId>
+    		<version>3.4</version>
+		</dependency>
+	</dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.karaf.tooling</groupId>
+                <artifactId>karaf-maven-plugin</artifactId>
+                <version>@pom.version@</version>
+                <extensions>true</extensions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/karaf/blob/f69e9b8f/tooling/karaf-maven-plugin/src/it/test-feature-use-base-version/verify.bsh
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/it/test-feature-use-base-version/verify.bsh b/tooling/karaf-maven-plugin/src/it/test-feature-use-base-version/verify.bsh
new file mode 100644
index 0000000..6af1a7c
--- /dev/null
+++ b/tooling/karaf-maven-plugin/src/it/test-feature-use-base-version/verify.bsh
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+import org.custommonkey.xmlunit.*;
+import java.io.*;
+import java.lang.*;
+
+Reader r = new FileReader(new File(basedir, "control.xml"));
+
+// load the features file pushed to the repository
+File generated = new File(basedir, "target/feature/feature.xml" );
+if (generated.exists()) {
+    try {
+        XMLAssert.assertXMLEqual(r, new FileReader(generated));
+        return true;
+    } catch (Throwable ignored) { }
+}
+
+return false;

http://git-wip-us.apache.org/repos/asf/karaf/blob/f69e9b8f/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range-transitive/control.xml
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range-transitive/control.xml b/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range-transitive/control.xml
new file mode 100644
index 0000000..131f23f
--- /dev/null
+++ b/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range-transitive/control.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+  ~ 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 xmlns="http://karaf.apache.org/xmlns/features/v1.4.0" name="feature">
+    <feature name="feature" description="feature" version="1.0.0.SNAPSHOT">
+        <bundle>mvn:test/transitive/[0.9,1.9)</bundle>
+        <bundle>mvn:org.apache.commons/commons-lang3/[3.0,3.4)</bundle>
+    </feature>
+</features>
+
+

http://git-wip-us.apache.org/repos/asf/karaf/blob/f69e9b8f/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range-transitive/feature/pom.xml
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range-transitive/feature/pom.xml b/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range-transitive/feature/pom.xml
new file mode 100644
index 0000000..f6d3f1e
--- /dev/null
+++ b/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range-transitive/feature/pom.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <!--
+
+        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.
+    -->
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>test</groupId>
+    <artifactId>feature</artifactId>
+    <version>1.0-SNAPSHOT</version>
+    <packaging>feature</packaging>
+    
+	<dependencies>
+		<dependency>
+			<groupId>test</groupId>
+    		<artifactId>transitive</artifactId>
+    		<version>[0.9,1.9)</version>
+		</dependency>
+	</dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.karaf.tooling</groupId>
+                <artifactId>karaf-maven-plugin</artifactId>
+                <version>@pom.version@</version>
+                <extensions>true</extensions>
+                <configuration>
+                	<useVersionRange>true</useVersionRange>
+                	<includeTransitiveVersionRanges>true</includeTransitiveVersionRanges>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/karaf/blob/f69e9b8f/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range-transitive/pom.xml
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range-transitive/pom.xml b/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range-transitive/pom.xml
new file mode 100644
index 0000000..20808ac
--- /dev/null
+++ b/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range-transitive/pom.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <!--
+
+        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.
+    -->
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>test</groupId>
+    <artifactId>test-feature-use-version-range-transitive</artifactId>
+    <version>1.0-SNAPSHOT</version>
+    <packaging>pom</packaging>
+    
+    <modules>
+    	<module>transitive</module>
+    	<module>feature</module>
+    </modules>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/karaf/blob/f69e9b8f/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range-transitive/transitive/pom.xml
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range-transitive/transitive/pom.xml b/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range-transitive/transitive/pom.xml
new file mode 100644
index 0000000..95a0da4
--- /dev/null
+++ b/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range-transitive/transitive/pom.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <!--
+
+        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.
+    -->
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>test</groupId>
+    <artifactId>transitive</artifactId>
+    <version>1.0-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+
+	<dependencies>
+		<dependency>
+    		<groupId>org.apache.commons</groupId>
+    		<artifactId>commons-lang3</artifactId>
+    		<version>[3.0,3.4)</version>
+		</dependency>
+	</dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+            	<extensions>true</extensions>
+    			<groupId>org.apache.felix</groupId>
+    			<artifactId>maven-bundle-plugin</artifactId>
+    			<version>3.0.1</version>
+			</plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/karaf/blob/f69e9b8f/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range-transitive/verify.bsh
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range-transitive/verify.bsh b/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range-transitive/verify.bsh
new file mode 100644
index 0000000..1400502
--- /dev/null
+++ b/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range-transitive/verify.bsh
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+import org.custommonkey.xmlunit.*;
+import java.io.*;
+import java.lang.*;
+
+Reader r = new FileReader(new File(basedir, "control.xml"));
+
+// load the features file pushed to the repository
+File generated = new File(basedir, "feature/target/feature/feature.xml" );
+if (generated.exists()) {
+    try {
+        XMLAssert.assertXMLEqual(r, new FileReader(generated));
+        return true;
+    } catch (Throwable ignored) { }
+}
+
+return false;

http://git-wip-us.apache.org/repos/asf/karaf/blob/f69e9b8f/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range/control.xml
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range/control.xml b/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range/control.xml
new file mode 100644
index 0000000..a29d8c8
--- /dev/null
+++ b/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range/control.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+  ~ 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 xmlns="http://karaf.apache.org/xmlns/features/v1.4.0" name="test-feature-use-version-range">
+    <feature name="test-feature-use-version-range" description="test-feature-use-version-range" version="1.0.0.SNAPSHOT">
+        <bundle>mvn:org.apache.commons/commons-lang3/[3.0,3.4)</bundle>
+    </feature>
+</features>
+
+

http://git-wip-us.apache.org/repos/asf/karaf/blob/f69e9b8f/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range/pom.xml
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range/pom.xml b/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range/pom.xml
new file mode 100644
index 0000000..2c60d55
--- /dev/null
+++ b/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range/pom.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <!--
+
+        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.
+    -->
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>test</groupId>
+    <artifactId>test-feature-use-version-range</artifactId>
+    <version>1.0-SNAPSHOT</version>
+    <packaging>feature</packaging>
+
+	<dependencies>
+		<dependency>
+    		<groupId>org.apache.commons</groupId>
+    		<artifactId>commons-lang3</artifactId>
+    		<version>[3.0,3.4)</version>
+		</dependency>
+	</dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.karaf.tooling</groupId>
+                <artifactId>karaf-maven-plugin</artifactId>
+                <version>@pom.version@</version>
+                <extensions>true</extensions>
+                <configuration>
+                	<useVersionRange>true</useVersionRange>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/karaf/blob/f69e9b8f/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range/verify.bsh
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range/verify.bsh b/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range/verify.bsh
new file mode 100644
index 0000000..6af1a7c
--- /dev/null
+++ b/tooling/karaf-maven-plugin/src/it/test-feature-use-version-range/verify.bsh
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+import org.custommonkey.xmlunit.*;
+import java.io.*;
+import java.lang.*;
+
+Reader r = new FileReader(new File(basedir, "control.xml"));
+
+// load the features file pushed to the repository
+File generated = new File(basedir, "target/feature/feature.xml" );
+if (generated.exists()) {
+    try {
+        XMLAssert.assertXMLEqual(r, new FileReader(generated));
+        return true;
+    } catch (Throwable ignored) { }
+}
+
+return false;

http://git-wip-us.apache.org/repos/asf/karaf/blob/f69e9b8f/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/GenerateDescriptorMojo.java
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/GenerateDescriptorMojo.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/GenerateDescriptorMojo.java
index a4c9c1c..9fcc4d5 100644
--- a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/GenerateDescriptorMojo.java
+++ b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/GenerateDescriptorMojo.java
@@ -17,6 +17,9 @@
  */
 package org.apache.karaf.tooling.features;
 
+import static java.lang.String.format;
+import static org.apache.karaf.deployer.kar.KarArtifactInstaller.FEATURE_CLASSIFIER;
+
 import java.io.BufferedInputStream;
 import java.io.BufferedWriter;
 import java.io.File;
@@ -32,6 +35,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.HashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
@@ -50,8 +54,10 @@ import org.apache.karaf.features.internal.model.JaxbUtil;
 import org.apache.karaf.features.internal.model.ObjectFactory;
 import org.apache.karaf.tooling.utils.DependencyHelper;
 import org.apache.karaf.tooling.utils.DependencyHelperFactory;
+import org.apache.karaf.tooling.utils.LocalDependency;
 import org.apache.karaf.tooling.utils.ManifestUtils;
 import org.apache.karaf.tooling.utils.MojoSupport;
+import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
 import org.apache.maven.artifact.resolver.ArtifactResolutionException;
 import org.apache.maven.plugin.MojoExecutionException;
@@ -63,6 +69,12 @@ import org.apache.maven.plugins.annotations.LifecyclePhase;
 import org.apache.maven.plugins.annotations.Mojo;
 import org.apache.maven.plugins.annotations.Parameter;
 import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.apache.maven.project.DefaultProjectBuildingRequest;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.ProjectBuilder;
+import org.apache.maven.project.ProjectBuildingException;
+import org.apache.maven.project.ProjectBuildingRequest;
+import org.apache.maven.repository.RepositorySystem;
 import org.apache.maven.shared.filtering.MavenFileFilter;
 import org.apache.maven.shared.filtering.MavenFilteringException;
 import org.apache.maven.shared.filtering.MavenResourcesExecution;
@@ -72,8 +84,6 @@ import org.codehaus.plexus.util.ReaderFactory;
 import org.codehaus.plexus.util.StringUtils;
 import org.xml.sax.SAXException;
 
-import static org.apache.karaf.deployer.kar.KarArtifactInstaller.FEATURE_CLASSIFIER;
-
 /**
  * Generates the features XML file starting with an optional source feature.xml and adding
  * project dependencies as bundles and feature/car dependencies.
@@ -221,6 +231,23 @@ public class GenerateDescriptorMojo extends MojoSupport {
      */
     @Parameter(defaultValue = "${project.artifactId}")
     private String primaryFeatureName;
+    
+    /**
+     * Flag indicating whether bundles should use the version range declared in the POM. If <code>false</code>,
+     * the actual version of the resolved artifacts will be used.
+     */
+    @Parameter(defaultValue = "false")
+    private boolean useVersionRange;
+    
+    /**
+     * Flag indicating whether the plugin should determine whether transitive dependencies are declared with
+     * a version range. If this flag is set to <code>true</code> and a transitive dependency has been found
+     * which had been declared with a version range, that version range will be used to build the appropriate
+     * bundle element instead of the newest version. This flag has only an effect when {@link #useVersionRange}
+     * is <code>true</code>
+     */
+    @Parameter(defaultValue = "false")
+    private boolean includeTransitiveVersionRanges;
 
     // *************************************************
     // READ-ONLY MAVEN PLUGIN PARAMETERS
@@ -232,15 +259,21 @@ public class GenerateDescriptorMojo extends MojoSupport {
      */
     @Component
     private PlexusContainer container;
+    
+    @Component
+    private RepositorySystem repoSystem;
 
     @Component
     protected MavenResourcesFiltering mavenResourcesFiltering;
 
     @Component
     protected MavenFileFilter mavenFileFilter;
+    
+	@Component
+	private ProjectBuilder mavenProjectBuilder;
 
     // dependencies we are interested in
-    protected Map<?, String> localDependencies;
+    protected Collection<LocalDependency> localDependencies;
 
     // log of what happened during search
     protected String treeListing;
@@ -250,6 +283,10 @@ public class GenerateDescriptorMojo extends MojoSupport {
 
     // maven log
     private Log log;
+    
+    // If useVersionRange is true, this map will be used to cache
+    // resolved MavenProjects
+    private final Map<Artifact, MavenProject> resolvedProjects = new HashMap<>();
 
     public void execute() throws MojoExecutionException, MojoFailureException {
         try {
@@ -277,6 +314,47 @@ public class GenerateDescriptorMojo extends MojoSupport {
         }
     }
 
+	private MavenProject resolveProject(final Object artifact) throws MojoExecutionException {
+		MavenProject resolvedProject = project;
+		if (includeTransitiveVersionRanges) {
+			resolvedProject = resolvedProjects.get(artifact);
+			if (resolvedProject == null) {
+				final ProjectBuildingRequest request = new DefaultProjectBuildingRequest();
+				request.setResolveDependencies(true);
+				request.setRemoteRepositories(project.getPluginArtifactRepositories());
+				request.setLocalRepository(localRepo);
+				request.setProfiles(new ArrayList<>(mavenSession.getRequest().getProfiles()));
+				request.setActiveProfileIds(new ArrayList<>(mavenSession.getRequest().getActiveProfiles()));
+				dependencyHelper.setRepositorySession(request);
+				final Artifact pomArtifact = repoSystem.createArtifact(dependencyHelper.getGroupId(artifact),
+						dependencyHelper.getArtifactId(artifact), dependencyHelper.getBaseVersion(artifact), "pom");
+				try {
+					resolvedProject = mavenProjectBuilder.build(pomArtifact, request).getProject();
+					resolvedProjects.put(pomArtifact, resolvedProject);
+				} catch (final ProjectBuildingException e) {
+					throw new MojoExecutionException(
+							format("Maven-project could not be built for artifact %", pomArtifact), e);
+				}
+			}
+		}
+		return resolvedProject;
+	}
+
+	private String getVersionOrRange(final Object parent, final Object artifact) throws MojoExecutionException {
+		String versionOrRange = dependencyHelper.getBaseVersion(artifact);
+		if (useVersionRange) {
+			for (final org.apache.maven.model.Dependency dependency : resolveProject(parent).getDependencies()) {
+
+				if (dependency.getGroupId().equals(dependencyHelper.getGroupId(artifact))
+						&& dependency.getArtifactId().equals(dependencyHelper.getArtifactId(artifact))) {
+					versionOrRange = dependency.getVersion();
+					break;
+				}
+			}
+		}
+		return versionOrRange;
+	}
+    
     /*
      * Write all project dependencies as feature
      */
@@ -323,15 +401,15 @@ public class GenerateDescriptorMojo extends MojoSupport {
         }
         if (includeProjectArtifact) {
             Bundle bundle = objectFactory.createBundle();
-            bundle.setLocation(this.dependencyHelper.artifactToMvn(project.getArtifact()));
+            bundle.setLocation(this.dependencyHelper.artifactToMvn(project.getArtifact(), project.getVersion()));
             if (startLevel != null) {
                 bundle.setStartLevel(startLevel);
             }
             feature.getBundle().add(bundle);
         }
         boolean needWrap = false;
-        for (Map.Entry<?, String> entry : localDependencies.entrySet()) {
-            Object artifact = entry.getKey();
+        for (final LocalDependency entry : localDependencies) {
+            Object artifact = entry.getArtifact();
 
             if (excludedArtifactIds.contains(this.dependencyHelper.getArtifactId(artifact))) {
                 continue;
@@ -348,7 +426,7 @@ public class GenerateDescriptorMojo extends MojoSupport {
                     features.getFeature().addAll(includedFeatures.getFeature());
                 }
             } else if (addBundlesToPrimaryFeature) {
-                String bundleName = this.dependencyHelper.artifactToMvn(artifact);
+                String bundleName = this.dependencyHelper.artifactToMvn(artifact, getVersionOrRange(entry.getParent(), artifact));
                 File bundleFile = this.dependencyHelper.resolve(artifact, getLog());
                 Manifest manifest = getManifest(bundleFile);
 
@@ -367,11 +445,11 @@ public class GenerateDescriptorMojo extends MojoSupport {
                 if (bundle == null) {
                     bundle = objectFactory.createBundle();
                     bundle.setLocation(bundleName);
-                    if (!"provided".equals(entry.getValue()) || !ignoreScopeProvided) {
+                    if (!"provided".equals(entry.getScope()) || !ignoreScopeProvided) {
                         feature.getBundle().add(bundle);
                     }
                 }
-                if ("runtime".equals(entry.getValue())) {
+                if ("runtime".equals(entry.getScope())) {
                     bundle.setDependency(true);
                 }
                 if (startLevel != null && bundle.getStartLevel() == 0) {

http://git-wip-us.apache.org/repos/asf/karaf/blob/f69e9b8f/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/utils/Dependency30Helper.java
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/utils/Dependency30Helper.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/utils/Dependency30Helper.java
index c06e0a5..8deeeb2 100644
--- a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/utils/Dependency30Helper.java
+++ b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/utils/Dependency30Helper.java
@@ -18,15 +18,31 @@
  */
 package org.apache.karaf.tooling.utils;
 
+import static java.lang.String.format;
+import static org.apache.commons.lang.reflect.MethodUtils.invokeMethod;
+import static org.apache.karaf.deployer.kar.KarArtifactInstaller.FEATURE_CLASSIFIER;
+
+import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
 import org.apache.maven.RepositoryUtils;
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.MojoFailureException;
 import org.apache.maven.plugin.logging.Log;
 import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.ProjectBuildingRequest;
 import org.sonatype.aether.RepositorySystem;
 import org.sonatype.aether.RepositorySystemSession;
 import org.sonatype.aether.artifact.Artifact;
-import org.sonatype.aether.collection.*;
+import org.sonatype.aether.collection.CollectRequest;
+import org.sonatype.aether.collection.CollectResult;
+import org.sonatype.aether.collection.DependencyCollectionContext;
+import org.sonatype.aether.collection.DependencyCollectionException;
+import org.sonatype.aether.collection.DependencyGraphTransformer;
+import org.sonatype.aether.collection.DependencySelector;
 import org.sonatype.aether.graph.Dependency;
 import org.sonatype.aether.graph.DependencyNode;
 import org.sonatype.aether.repository.RemoteRepository;
@@ -43,12 +59,6 @@ import org.sonatype.aether.util.graph.transformer.ConflictMarker;
 import org.sonatype.aether.util.graph.transformer.JavaDependencyContextRefiner;
 import org.sonatype.aether.util.graph.transformer.JavaEffectiveScopeCalculator;
 
-import java.io.File;
-import java.util.*;
-
-import static java.lang.String.*;
-import static org.apache.karaf.deployer.kar.KarArtifactInstaller.FEATURE_CLASSIFIER;
-
 /**
  * This is a dependency helper compliant with Maven 3.0 (using Aether Sonatype lib)
  */
@@ -70,7 +80,7 @@ public class Dependency30Helper implements DependencyHelper {
     private final List<RemoteRepository> projectRepositories;
 
     // dependencies we are interested in
-    protected Map<Artifact, String> localDependencies;
+    protected Set<LocalDependency> localDependencies;
     // log of what happened during search
     protected String treeListing;
 
@@ -79,9 +89,17 @@ public class Dependency30Helper implements DependencyHelper {
         this.repositorySystemSession = repositorySystemSession;
         this.repositorySystem = repositorySystem;
     }
+    
+	public void setRepositorySession(final ProjectBuildingRequest request) throws MojoExecutionException {
+		try {
+			invokeMethod(request, "setRepositorySession", repositorySystemSession);
+		} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
+			throw new MojoExecutionException("Cannot set repository session on project building request", e);
+		}
+	}
 
     @Override
-    public Map<Artifact, String> getLocalDependencies() {
+    public Set<LocalDependency> getLocalDependencies() {
         return this.localDependencies;
     }
 
@@ -190,39 +208,40 @@ public class Dependency30Helper implements DependencyHelper {
         }
 
         // all the dependencies needed, with provided dependencies removed
-        private final Map<Artifact, String> localDependencies = new LinkedHashMap<Artifact, String>();
+        private final Set<LocalDependency> localDependencies = new LinkedHashSet<>();
+
         // dependencies from ancestor, to be removed from localDependencies
-        private final Set<Artifact> dependencies = new LinkedHashSet<Artifact>();
+        private final Set<Artifact> dependencies = new LinkedHashSet<>();
 
         private final StringBuilder log = new StringBuilder();
 
         public void scan(DependencyNode rootNode, boolean useTransitiveDependencies) throws MojoExecutionException {
             for (DependencyNode child : rootNode.getChildren()) {
-                scan(child, Accept.ACCEPT, useTransitiveDependencies, false, "");
+                scan(rootNode, child, Accept.ACCEPT, useTransitiveDependencies, false, "");
             }
             if (useTransitiveDependencies) {
-                localDependencies.keySet().removeAll(dependencies);
+                localDependencies.removeAll(dependencies);
             }
         }
 
-        private void scan(DependencyNode dependencyNode, Accept parentAccept, boolean useTransitiveDependencies, boolean isFromFeature, String indent) throws MojoExecutionException {
+        private void scan(DependencyNode parentNode, DependencyNode dependencyNode, Accept parentAccept, boolean useTransitiveDependencies, boolean isFromFeature, String indent) throws MojoExecutionException {
             Accept accept = accept(dependencyNode, parentAccept);
             if (accept.isLocal()) {
                 if (isFromFeature) {
                     if (!isFeature(dependencyNode)) {
-                        log.append(indent).append("from feature: ").append(dependencyNode).append("\n");
+                        log.append(indent).append("from feature:").append(dependencyNode).append("\n");
                         dependencies.add(dependencyNode.getDependency().getArtifact());
                     } else {
-                        log.append(indent).append("is feature: ").append(dependencyNode).append("\n");
+                        log.append(indent).append("is feature:").append(dependencyNode).append("\n");
                     }
                 } else {
-                    log.append(indent).append("local: ").append(dependencyNode).append("\n");
-                    if (localDependencies.containsKey(dependencyNode.getDependency().getArtifact())) {
+                    log.append(indent).append("local:").append(dependencyNode).append("\n");
+                    if (localDependencies.contains(dependencyNode.getDependency().getArtifact())) {
                         log.append(indent).append("already in feature, returning:").append(dependencyNode).append("\n");
                         return;
                     }
                     // TODO resolve scope conflicts
-                    localDependencies.put(dependencyNode.getDependency().getArtifact(), dependencyNode.getDependency().getScope());
+                    localDependencies.add(new LocalDependency(dependencyNode.getDependency().getScope(), dependencyNode.getDependency().getArtifact(), parentNode.getDependency().getArtifact()));
                     if (isFeature(dependencyNode) || !useTransitiveDependencies) {
                         isFromFeature = true;
                     }
@@ -230,7 +249,7 @@ public class Dependency30Helper implements DependencyHelper {
                 if (useTransitiveDependencies && accept.isContinue()) {
                     List<DependencyNode> children = dependencyNode.getChildren();
                     for (DependencyNode child : children) {
-                        scan(child, accept, useTransitiveDependencies, isFromFeature, indent + " ");
+                        scan(dependencyNode, child, accept, useTransitiveDependencies, isFromFeature, indent + " ");
                     }
                 }
             }
@@ -265,6 +284,16 @@ public class Dependency30Helper implements DependencyHelper {
     public boolean isArtifactAFeature(Object artifact) {
         return Dependency30Helper.isFeature((Artifact) artifact);
     }
+    
+	@Override
+	public String getBaseVersion(Object artifact) {
+		return ((Artifact) artifact).getBaseVersion();
+	}
+
+	@Override
+	public String getGroupId(Object artifact) {
+		return ((Artifact) artifact).getGroupId();
+	}
 
     @Override
     public String getArtifactId(Object artifact) {
@@ -328,21 +357,21 @@ public class Dependency30Helper implements DependencyHelper {
     }
 
     @Override
-    public String artifactToMvn(org.apache.maven.artifact.Artifact artifact) {
-        return this.artifactToMvn(RepositoryUtils.toArtifact(artifact));
+    public String artifactToMvn(org.apache.maven.artifact.Artifact artifact, String versionOrRange) {
+        return this.artifactToMvn(RepositoryUtils.toArtifact(artifact), versionOrRange);
     }
 
     @Override
-    public String artifactToMvn(Object _artifact) {
+    public String artifactToMvn(Object _artifact, String versionOrRange) {
         Artifact artifact = (Artifact) _artifact;
         String bundleName;
         if (artifact.getExtension().equals("jar") && MavenUtil.isEmpty(artifact.getClassifier())) {
-            bundleName = String.format("mvn:%s/%s/%s", artifact.getGroupId(), artifact.getArtifactId(), artifact.getBaseVersion());
+            bundleName = String.format("mvn:%s/%s/%s", artifact.getGroupId(), artifact.getArtifactId(), versionOrRange);
         } else {
             if (MavenUtil.isEmpty(artifact.getClassifier())) {
-                bundleName = String.format("mvn:%s/%s/%s/%s", artifact.getGroupId(), artifact.getArtifactId(), artifact.getBaseVersion(), artifact.getExtension());
+                bundleName = String.format("mvn:%s/%s/%s/%s", artifact.getGroupId(), artifact.getArtifactId(), versionOrRange, artifact.getExtension());
             } else {
-                bundleName = String.format("mvn:%s/%s/%s/%s/%s", artifact.getGroupId(), artifact.getArtifactId(), artifact.getBaseVersion(), artifact.getExtension(), artifact.getClassifier());
+                bundleName = String.format("mvn:%s/%s/%s/%s/%s", artifact.getGroupId(), artifact.getArtifactId(), versionOrRange, artifact.getExtension(), artifact.getClassifier());
             }
         }
         return bundleName;
@@ -374,5 +403,4 @@ public class Dependency30Helper implements DependencyHelper {
         org.apache.maven.artifact.Artifact mavenArtifact = RepositoryUtils.toArtifact(artifact);
         return MavenUtil.layout.pathOf(mavenArtifact);
     }
-
 }

http://git-wip-us.apache.org/repos/asf/karaf/blob/f69e9b8f/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/utils/Dependency31Helper.java
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/utils/Dependency31Helper.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/utils/Dependency31Helper.java
index 215619e..89a1762 100644
--- a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/utils/Dependency31Helper.java
+++ b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/utils/Dependency31Helper.java
@@ -23,6 +23,7 @@ import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.MojoFailureException;
 import org.apache.maven.plugin.logging.Log;
 import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.ProjectBuildingRequest;
 import org.eclipse.aether.DefaultRepositorySystemSession;
 import org.eclipse.aether.RepositorySystem;
 import org.eclipse.aether.RepositorySystemSession;
@@ -41,10 +42,12 @@ import org.eclipse.aether.util.graph.selector.OptionalDependencySelector;
 import org.eclipse.aether.util.graph.transformer.*;
 
 import java.io.File;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.*;
 
 import static java.lang.String.*;
+import static org.apache.commons.lang.reflect.MethodUtils.invokeMethod;
 import static org.apache.karaf.deployer.kar.KarArtifactInstaller.FEATURE_CLASSIFIER;
 
 /**
@@ -72,7 +75,7 @@ public class Dependency31Helper implements DependencyHelper {
     private final List<RemoteRepository> projectRepositories;
 
     // dependencies we are interested in
-    protected Map<Artifact, String> localDependencies;
+    protected Set<LocalDependency> localDependencies;
     // log of what happened during search
     protected String treeListing;
 
@@ -82,9 +85,17 @@ public class Dependency31Helper implements DependencyHelper {
         this.repositorySystemSession = (RepositorySystemSession) session;
         this.repositorySystem = repositorySystem;
     }
+    
+	public void setRepositorySession(final ProjectBuildingRequest request) throws MojoExecutionException {
+		try {
+			invokeMethod(request, "setRepositorySession", repositorySystemSession);
+		} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
+			throw new MojoExecutionException("Cannot set repository session on project building request", e);
+		}
+	}
 
     @Override
-    public Map<?, String> getLocalDependencies() {
+    public Set<LocalDependency> getLocalDependencies() {
         return localDependencies;
     }
 
@@ -195,23 +206,23 @@ public class Dependency31Helper implements DependencyHelper {
         }
 
         // all the dependencies needed, with provided dependencies removed
-        private final Map<Artifact, String> localDependencies = new LinkedHashMap<Artifact, String>();
+        private final Set<LocalDependency> localDependencies = new LinkedHashSet<>();
 
         // dependencies from ancestor, to be removed from localDependencies
-        private final Set<Artifact> dependencies = new LinkedHashSet<Artifact>();
+        private final Set<Artifact> dependencies = new LinkedHashSet<>();
 
         private final StringBuilder log = new StringBuilder();
 
         public void scan(DependencyNode rootNode, boolean useTransitiveDependencies) throws MojoExecutionException {
             for (DependencyNode child : rootNode.getChildren()) {
-                scan(child, Accept.ACCEPT, useTransitiveDependencies, false, "");
+                scan(rootNode, child, Accept.ACCEPT, useTransitiveDependencies, false, "");
             }
             if (useTransitiveDependencies) {
-                localDependencies.keySet().removeAll(dependencies);
+                localDependencies.removeAll(dependencies);
             }
         }
 
-        private void scan(DependencyNode dependencyNode, Accept parentAccept, boolean useTransitiveDependencies, boolean isFromFeature, String indent) throws MojoExecutionException {
+        private void scan(DependencyNode parentNode, DependencyNode dependencyNode, Accept parentAccept, boolean useTransitiveDependencies, boolean isFromFeature, String indent) throws MojoExecutionException {
             Accept accept = accept(dependencyNode, parentAccept);
             if (accept.isLocal()) {
                 if (isFromFeature) {
@@ -223,12 +234,12 @@ public class Dependency31Helper implements DependencyHelper {
                     }
                 } else {
                     log.append(indent).append("local:").append(dependencyNode).append("\n");
-                    if (localDependencies.containsKey(dependencyNode.getDependency().getArtifact())) {
+                    if (localDependencies.contains(dependencyNode.getDependency().getArtifact())) {
                         log.append(indent).append("already in feature, returning:").append(dependencyNode).append("\n");
                         return;
                     }
                     // TODO resolve scope conflicts
-                    localDependencies.put(dependencyNode.getDependency().getArtifact(), dependencyNode.getDependency().getScope());
+                    localDependencies.add(new LocalDependency(dependencyNode.getDependency().getScope(), dependencyNode.getDependency().getArtifact(), parentNode.getDependency().getArtifact()));
                     if (isFeature(dependencyNode) || !useTransitiveDependencies) {
                         isFromFeature = true;
                     }
@@ -236,7 +247,7 @@ public class Dependency31Helper implements DependencyHelper {
                 if (useTransitiveDependencies && accept.isContinue()) {
                     List<DependencyNode> children = dependencyNode.getChildren();
                     for (DependencyNode child : children) {
-                        scan(child, accept, useTransitiveDependencies, isFromFeature, indent + " ");
+                        scan(dependencyNode, child, accept, useTransitiveDependencies, isFromFeature, indent + " ");
                     }
                 }
             }
@@ -272,6 +283,16 @@ public class Dependency31Helper implements DependencyHelper {
     public boolean isArtifactAFeature(Object artifact) {
         return Dependency31Helper.isFeature((Artifact) artifact);
     }
+    
+	@Override
+	public String getBaseVersion(Object artifact) {
+		return ((Artifact) artifact).getBaseVersion();
+	}
+
+	@Override
+	public String getGroupId(Object artifact) {
+		return ((Artifact) artifact).getGroupId();
+	}
 
     @Override
     public String getArtifactId(Object artifact) {
@@ -335,21 +356,21 @@ public class Dependency31Helper implements DependencyHelper {
     }
 
     @Override
-    public String artifactToMvn(org.apache.maven.artifact.Artifact artifact) throws MojoExecutionException {
-        return this.artifactToMvn(toArtifact(artifact));
+    public String artifactToMvn(org.apache.maven.artifact.Artifact artifact, String versionOrRange) throws MojoExecutionException {
+        return this.artifactToMvn(toArtifact(artifact), versionOrRange);
     }
 
     @Override
-    public String artifactToMvn(Object _artifact) {
+    public String artifactToMvn(Object _artifact, String versionOrRange) {
         Artifact artifact = (Artifact) _artifact;
         String bundleName;
         if (artifact.getExtension().equals("jar") && MavenUtil.isEmpty(artifact.getClassifier())) {
-            bundleName = String.format("mvn:%s/%s/%s", artifact.getGroupId(), artifact.getArtifactId(), artifact.getBaseVersion());
+            bundleName = String.format("mvn:%s/%s/%s", artifact.getGroupId(), artifact.getArtifactId(), versionOrRange);
         } else {
             if (MavenUtil.isEmpty(artifact.getClassifier())) {
-                bundleName = String.format("mvn:%s/%s/%s/%s", artifact.getGroupId(), artifact.getArtifactId(), artifact.getBaseVersion(), artifact.getExtension());
+                bundleName = String.format("mvn:%s/%s/%s/%s", artifact.getGroupId(), artifact.getArtifactId(), versionOrRange, artifact.getExtension());
             } else {
-                bundleName = String.format("mvn:%s/%s/%s/%s/%s", artifact.getGroupId(), artifact.getArtifactId(), artifact.getBaseVersion(), artifact.getExtension(), artifact.getClassifier());
+                bundleName = String.format("mvn:%s/%s/%s/%s/%s", artifact.getGroupId(), artifact.getArtifactId(), versionOrRange, artifact.getExtension(), artifact.getClassifier());
             }
         }
         return bundleName;

http://git-wip-us.apache.org/repos/asf/karaf/blob/f69e9b8f/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/utils/DependencyHelper.java
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/utils/DependencyHelper.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/utils/DependencyHelper.java
index e2e3bf7..62e5a68 100644
--- a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/utils/DependencyHelper.java
+++ b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/utils/DependencyHelper.java
@@ -19,13 +19,14 @@
 package org.apache.karaf.tooling.utils;
 
 import java.io.File;
-import java.util.Map;
+import java.util.Collection;
 
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.MojoFailureException;
 import org.apache.maven.plugin.logging.Log;
 import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.ProjectBuildingRequest;
 
 /**
  * <p>An interface for accessing available Aether subsystem (Sonatype for Maven 3.0.x or Eclipse for Maven 3.1.x)</p>
@@ -35,7 +36,7 @@ import org.apache.maven.project.MavenProject;
  */
 public interface DependencyHelper {
 
-    public abstract Map<?, String> getLocalDependencies();
+    public abstract Collection<LocalDependency> getLocalDependencies();
 
     public abstract String getTreeListing();
 
@@ -45,12 +46,18 @@ public interface DependencyHelper {
 
     public abstract String getArtifactId(Object artifact);
 
+	public abstract String getBaseVersion(Object artifact);
+
+	public abstract String getGroupId(Object artifact);
+    
     public abstract String getClassifier(Object artifact);
 
     public abstract File resolve(Object artifact, Log log);
 
     public abstract File resolveById(String id, Log log) throws MojoFailureException;
 
+    public abstract void setRepositorySession(ProjectBuildingRequest request) throws MojoExecutionException;
+    
     /**
      * Convert a Maven <code>Artifact</code> into a PAX URL mvn format.
      *
@@ -58,7 +65,7 @@ public interface DependencyHelper {
      * @return The corresponding PAX URL mvn format (mvn:groupId/artifactId/version/type/classifier)
      * @throws MojoExecutionException If the plugin execution fails.
      */
-    public String artifactToMvn(Artifact artifact) throws MojoExecutionException;
+    public String artifactToMvn(Artifact artifact, String versionOrRange) throws MojoExecutionException;
 
     /**
      * Convert an Aether (Sonatype or Eclipse) artifact into a PAX URL mvn format.
@@ -67,7 +74,7 @@ public interface DependencyHelper {
      * @return The corresponding PAX URL mvn format (mvn:groupId/artifactId/version/type/classifier).
      * @throws MojoExecutionException If the plugin execution fails.
      */
-    public String artifactToMvn(Object object) throws MojoExecutionException;
+    public String artifactToMvn(Object object, String versionOrRange) throws MojoExecutionException;
 
     public Artifact mvnToArtifact(String name) throws MojoExecutionException;
 
@@ -88,5 +95,4 @@ public interface DependencyHelper {
      * @throws MojoExecutionException If the plugin execution fails.
      */
     public String pathFromAether(String name) throws MojoExecutionException;
-
 }

http://git-wip-us.apache.org/repos/asf/karaf/blob/f69e9b8f/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/utils/LocalDependency.java
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/utils/LocalDependency.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/utils/LocalDependency.java
new file mode 100644
index 0000000..58c13c8
--- /dev/null
+++ b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/utils/LocalDependency.java
@@ -0,0 +1,35 @@
+package org.apache.karaf.tooling.utils;
+
+public class LocalDependency {
+	private String scope;
+	private Object artifact;
+	private Object parent;
+	
+	LocalDependency(final String scope, final Object artifact, Object parent) {
+		this.scope = scope;
+		this.artifact = artifact;
+		this.parent = parent;
+	}
+
+	public String getScope() {
+		return scope;
+	}
+
+	public Object getArtifact() {
+		return artifact;
+	}
+
+	public Object getParent() {
+		return parent;
+	}
+	
+	@Override
+	public int hashCode() {
+		return artifact.hashCode();
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		return artifact.equals(obj);
+	}
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/f69e9b8f/tooling/karaf-maven-plugin/src/test/java/org/apache/karaf/tooling/features/MavenUtilTest.java
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/test/java/org/apache/karaf/tooling/features/MavenUtilTest.java b/tooling/karaf-maven-plugin/src/test/java/org/apache/karaf/tooling/features/MavenUtilTest.java
index f66d047..0623566 100644
--- a/tooling/karaf-maven-plugin/src/test/java/org/apache/karaf/tooling/features/MavenUtilTest.java
+++ b/tooling/karaf-maven-plugin/src/test/java/org/apache/karaf/tooling/features/MavenUtilTest.java
@@ -83,17 +83,32 @@ public class MavenUtilTest {
     @Test
     public void testSonatypeArtifactToMvn() throws Exception {
         Dependency30Helper helper = new Dependency30Helper(null, null, null);
-        assertEquals("mvn:org.foo/org.foo.bar/1.0-SNAPSHOT", helper.artifactToMvn(new org.sonatype.aether.util.artifact.DefaultArtifact("org.foo:org.foo.bar:1.0-SNAPSHOT")));
-        assertEquals("mvn:org.foo/org.foo.bar/1.0-SNAPSHOT/kar", helper.artifactToMvn(new org.sonatype.aether.util.artifact.DefaultArtifact("org.foo:org.foo.bar:kar:1.0-SNAPSHOT")));
-        assertEquals("mvn:org.foo/org.foo.bar/1.0-SNAPSHOT/xml/features", helper.artifactToMvn(new org.sonatype.aether.util.artifact.DefaultArtifact("org.foo:org.foo.bar:xml:features:1.0-SNAPSHOT")));
+        assertEquals("mvn:org.foo/org.foo.bar/1.0-SNAPSHOT", helper.artifactToMvn(new org.sonatype.aether.util.artifact.DefaultArtifact("org.foo:org.foo.bar:1.0-SNAPSHOT"), "1.0-SNAPSHOT"));
+        assertEquals("mvn:org.foo/org.foo.bar/1.0-SNAPSHOT/kar", helper.artifactToMvn(new org.sonatype.aether.util.artifact.DefaultArtifact("org.foo:org.foo.bar:kar:1.0-SNAPSHOT"), "1.0-SNAPSHOT"));
+        assertEquals("mvn:org.foo/org.foo.bar/1.0-SNAPSHOT/xml/features", helper.artifactToMvn(new org.sonatype.aether.util.artifact.DefaultArtifact("org.foo:org.foo.bar:xml:features:1.0-SNAPSHOT"), "1.0-SNAPSHOT"));
     }
 
     @Test
     public void testEclipseArtifactToMvn() throws Exception {
         Dependency31Helper helper = new Dependency31Helper(null, null, null);
-        assertEquals("mvn:org.foo/org.foo.bar/1.0-SNAPSHOT", helper.artifactToMvn(new org.eclipse.aether.artifact.DefaultArtifact("org.foo:org.foo.bar:1.0-SNAPSHOT")));
-        assertEquals("mvn:org.foo/org.foo.bar/1.0-SNAPSHOT/kar", helper.artifactToMvn(new org.eclipse.aether.artifact.DefaultArtifact("org.foo:org.foo.bar:kar:1.0-SNAPSHOT")));
-        assertEquals("mvn:org.foo/org.foo.bar/1.0-SNAPSHOT/xml/features", helper.artifactToMvn(new org.eclipse.aether.artifact.DefaultArtifact("org.foo:org.foo.bar:xml:features:1.0-SNAPSHOT")));
+        assertEquals("mvn:org.foo/org.foo.bar/1.0-SNAPSHOT", helper.artifactToMvn(new org.eclipse.aether.artifact.DefaultArtifact("org.foo:org.foo.bar:1.0-SNAPSHOT"), "1.0-SNAPSHOT"));
+        assertEquals("mvn:org.foo/org.foo.bar/1.0-SNAPSHOT/kar", helper.artifactToMvn(new org.eclipse.aether.artifact.DefaultArtifact("org.foo:org.foo.bar:kar:1.0-SNAPSHOT"), "1.0-SNAPSHOT"));
+        assertEquals("mvn:org.foo/org.foo.bar/1.0-SNAPSHOT/xml/features", helper.artifactToMvn(new org.eclipse.aether.artifact.DefaultArtifact("org.foo:org.foo.bar:xml:features:1.0-SNAPSHOT"), "1.0-SNAPSHOT"));
     }
 
+    @Test
+    public void testSonatypeArtifactToMvnWithRange() throws Exception {
+        Dependency30Helper helper = new Dependency30Helper(null, null, null);
+        assertEquals("mvn:org.foo/org.foo.bar/[1.0,2.0)", helper.artifactToMvn(new org.sonatype.aether.util.artifact.DefaultArtifact("org.foo:org.foo.bar:1.0-SNAPSHOT"), "[1.0,2.0)"));
+        assertEquals("mvn:org.foo/org.foo.bar/[1.0,2.0)/kar", helper.artifactToMvn(new org.sonatype.aether.util.artifact.DefaultArtifact("org.foo:org.foo.bar:kar:1.0-SNAPSHOT"), "[1.0,2.0)"));
+        assertEquals("mvn:org.foo/org.foo.bar/[1.0,2.0)/xml/features", helper.artifactToMvn(new org.sonatype.aether.util.artifact.DefaultArtifact("org.foo:org.foo.bar:xml:features:1.0-SNAPSHOT"), "[1.0,2.0)"));
+    }
+
+    @Test
+    public void testEclipseArtifactToMvnWithRange() throws Exception {
+        Dependency31Helper helper = new Dependency31Helper(null, null, null);
+        assertEquals("mvn:org.foo/org.foo.bar/[1.0,2.0)", helper.artifactToMvn(new org.eclipse.aether.artifact.DefaultArtifact("org.foo:org.foo.bar:1.0-SNAPSHOT"), "[1.0,2.0)"));
+        assertEquals("mvn:org.foo/org.foo.bar/[1.0,2.0)/kar", helper.artifactToMvn(new org.eclipse.aether.artifact.DefaultArtifact("org.foo:org.foo.bar:kar:1.0-SNAPSHOT"), "[1.0,2.0)"));
+        assertEquals("mvn:org.foo/org.foo.bar/[1.0,2.0)/xml/features", helper.artifactToMvn(new org.eclipse.aether.artifact.DefaultArtifact("org.foo:org.foo.bar:xml:features:1.0-SNAPSHOT"), "[1.0,2.0)"));
+    }
 }


[2/2] karaf git commit: [KARAF-4571] This closes #200

Posted by jb...@apache.org.
[KARAF-4571] This closes #200


Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/13d88742
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/13d88742
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/13d88742

Branch: refs/heads/master
Commit: 13d88742471624d04df0e7cd5f1ad0e3c052c3a5
Parents: ce69d7d f69e9b8
Author: Jean-Baptiste Onofr� <jb...@apache.org>
Authored: Thu Jun 23 09:56:27 2016 +0200
Committer: Jean-Baptiste Onofr� <jb...@apache.org>
Committed: Thu Jun 23 09:56:27 2016 +0200

----------------------------------------------------------------------
 .../test-feature-use-base-version/control.xml   | 26 ++++++
 .../it/test-feature-use-base-version/pom.xml    | 48 ++++++++++
 .../it/test-feature-use-base-version/verify.bsh | 35 +++++++
 .../control.xml                                 | 28 ++++++
 .../feature/pom.xml                             | 52 +++++++++++
 .../pom.xml                                     | 33 +++++++
 .../transitive/pom.xml                          | 48 ++++++++++
 .../verify.bsh                                  | 35 +++++++
 .../test-feature-use-version-range/control.xml  | 27 ++++++
 .../it/test-feature-use-version-range/pom.xml   | 51 +++++++++++
 .../test-feature-use-version-range/verify.bsh   | 35 +++++++
 .../features/GenerateDescriptorMojo.java        | 96 ++++++++++++++++++--
 .../karaf/tooling/utils/Dependency30Helper.java | 82 +++++++++++------
 .../karaf/tooling/utils/Dependency31Helper.java | 53 +++++++----
 .../karaf/tooling/utils/DependencyHelper.java   | 16 +++-
 .../karaf/tooling/utils/LocalDependency.java    | 35 +++++++
 .../karaf/tooling/features/MavenUtilTest.java   | 27 ++++--
 17 files changed, 664 insertions(+), 63 deletions(-)
----------------------------------------------------------------------