You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gn...@apache.org on 2015/04/17 11:34:57 UTC

[5/5] karaf git commit: [KARAF-3671] Clean up karaf-maven-plugin goals

[KARAF-3671] Clean up karaf-maven-plugin goals


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

Branch: refs/heads/master
Commit: 056239dca87c6a6586d4ecce10badc181d635f7f
Parents: 437186b
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Fri Apr 17 11:34:07 2015 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Fri Apr 17 11:34:37 2015 +0200

----------------------------------------------------------------------
 assemblies/apache-karaf-minimal/pom.xml         |   4 +-
 assemblies/apache-karaf/pom.xml                 |   4 +-
 assemblies/features/enterprise/pom.xml          |   2 +-
 assemblies/features/framework/pom.xml           |   2 +-
 assemblies/features/spring/pom.xml              |   2 +-
 assemblies/features/standard/pom.xml            |   2 +-
 assemblies/features/static/pom.xml              |   2 +-
 demos/deployer/kar/pom.xml                      |   2 +-
 demos/profiles/dynamic/pom.xml                  |   4 +-
 demos/profiles/static/pom.xml                   |   4 +-
 manual/src/main/asciidoc/users-guide/kar.adoc   |  15 +-
 .../developers-guide/custom-distribution.conf   |   2 +-
 .../karaf-maven-plugin-features-create-kar.conf |   4 +-
 ...af-maven-plugin-instance-create-archive.conf |   6 +-
 .../developers-guide/karaf-maven-plugin.conf    |   6 +-
 manual/src/main/webapp/users-guide/kar.conf     |  15 +-
 .../src/it/test-kar-classifier/pom.xml          |   4 +-
 .../src/it/test-kar-multiple-kars/pom.xml       |   8 +-
 .../src/it/test-kar-with-pom-packaging/pom.xml  |   4 +-
 .../org/apache/karaf/tooling/ArchiveMojo.java   | 226 ++++++
 .../org/apache/karaf/tooling/AssemblyMojo.java  | 321 ++++++++
 .../java/org/apache/karaf/tooling/KarMojo.java  | 398 +++++++++
 .../org/apache/karaf/tooling/VerifyMojo.java    | 805 +++++++++++++++++++
 .../tooling/features/AbstractFeatureMojo.java   |   2 +-
 .../tooling/features/AddToRepositoryMojo.java   |  11 +-
 .../karaf/tooling/features/CreateKarMojo.java   | 398 ---------
 .../karaf/tooling/features/InstallKarsMojo.java | 305 -------
 .../features/ValidateDescriptorMojo.java        | 665 ---------------
 .../features/VerifyFeatureResolutionMojo.java   | 805 -------------------
 .../tooling/instances/CreateArchiveMojo.java    | 226 ------
 .../karaf/tooling/url/BlueprintURLHandler.java  |  91 ---
 .../CustomBundleURLStreamHandlerFactory.java    | 106 ---
 .../karaf/tooling/url/FeatureURLHandler.java    |  92 ---
 .../karaf/tooling/url/SpringURLHandler.java     |  91 ---
 .../apache/karaf/tooling/url/WarURLHandler.java |  57 --
 .../tooling/utils/InternalMavenResolver.java    |  69 --
 .../resources/META-INF/plexus/components.xml    |   6 +-
 .../karaf-maven-plugin/src/site/apt/usage.apt   |   2 +-
 38 files changed, 1798 insertions(+), 2970 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/056239dc/assemblies/apache-karaf-minimal/pom.xml
----------------------------------------------------------------------
diff --git a/assemblies/apache-karaf-minimal/pom.xml b/assemblies/apache-karaf-minimal/pom.xml
index a05bcf9..a1b5074 100644
--- a/assemblies/apache-karaf-minimal/pom.xml
+++ b/assemblies/apache-karaf-minimal/pom.xml
@@ -100,13 +100,13 @@
                         <id>process-resources</id>
                         <phase>process-resources</phase>
                         <goals>
-                            <goal>install-kars</goal>
+                            <goal>assembly</goal>
                         </goals>
                     </execution>
                     <execution>
                         <id>package</id>
                         <goals>
-                            <goal>instance-create-archive</goal>
+                            <goal>archive</goal>
                         </goals>
                     </execution>
                 </executions>

http://git-wip-us.apache.org/repos/asf/karaf/blob/056239dc/assemblies/apache-karaf/pom.xml
----------------------------------------------------------------------
diff --git a/assemblies/apache-karaf/pom.xml b/assemblies/apache-karaf/pom.xml
index 3e3f109..0c90e0a 100644
--- a/assemblies/apache-karaf/pom.xml
+++ b/assemblies/apache-karaf/pom.xml
@@ -145,13 +145,13 @@
                         <id>install-kar</id>
                         <phase>compile</phase>
                         <goals>
-                            <goal>install-kars</goal>
+                            <goal>assembly</goal>
                         </goals>
                     </execution>
                     <execution>
                         <id>package</id>
                         <goals>
-                            <goal>instance-create-archive</goal>
+                            <goal>archive</goal>
                         </goals>
                     </execution>
                 </executions>

http://git-wip-us.apache.org/repos/asf/karaf/blob/056239dc/assemblies/features/enterprise/pom.xml
----------------------------------------------------------------------
diff --git a/assemblies/features/enterprise/pom.xml b/assemblies/features/enterprise/pom.xml
index 16b1fec..e16fc29 100644
--- a/assemblies/features/enterprise/pom.xml
+++ b/assemblies/features/enterprise/pom.xml
@@ -219,7 +219,7 @@
                         <id>verify</id>
                         <phase>process-resources</phase>
                         <goals>
-                            <goal>verify-features</goal>
+                            <goal>verify</goal>
                         </goals>
                         <configuration>
                             <descriptors>

http://git-wip-us.apache.org/repos/asf/karaf/blob/056239dc/assemblies/features/framework/pom.xml
----------------------------------------------------------------------
diff --git a/assemblies/features/framework/pom.xml b/assemblies/features/framework/pom.xml
index 6c32293..fbec7c9 100644
--- a/assemblies/features/framework/pom.xml
+++ b/assemblies/features/framework/pom.xml
@@ -282,7 +282,7 @@
                     <execution>
                         <id>package</id>
                         <goals>
-                            <goal>features-create-kar</goal>
+                            <goal>kar</goal>
                         </goals>
                     </execution>
                 </executions>

http://git-wip-us.apache.org/repos/asf/karaf/blob/056239dc/assemblies/features/spring/pom.xml
----------------------------------------------------------------------
diff --git a/assemblies/features/spring/pom.xml b/assemblies/features/spring/pom.xml
index d6adfe0..7d7f877 100644
--- a/assemblies/features/spring/pom.xml
+++ b/assemblies/features/spring/pom.xml
@@ -338,7 +338,7 @@
                         <id>verify</id>
                         <phase>process-resources</phase>
                         <goals>
-                            <goal>verify-features</goal>
+                            <goal>verify</goal>
                         </goals>
                         <configuration>
                             <descriptors>

http://git-wip-us.apache.org/repos/asf/karaf/blob/056239dc/assemblies/features/standard/pom.xml
----------------------------------------------------------------------
diff --git a/assemblies/features/standard/pom.xml b/assemblies/features/standard/pom.xml
index 564caca..9882490 100644
--- a/assemblies/features/standard/pom.xml
+++ b/assemblies/features/standard/pom.xml
@@ -454,7 +454,7 @@
                         <id>verify</id>
                         <phase>process-resources</phase>
                         <goals>
-                            <goal>verify-features</goal>
+                            <goal>verify</goal>
                         </goals>
                         <configuration>
                             <descriptors>

http://git-wip-us.apache.org/repos/asf/karaf/blob/056239dc/assemblies/features/static/pom.xml
----------------------------------------------------------------------
diff --git a/assemblies/features/static/pom.xml b/assemblies/features/static/pom.xml
index 34ea37a..34147c5 100644
--- a/assemblies/features/static/pom.xml
+++ b/assemblies/features/static/pom.xml
@@ -168,7 +168,7 @@
                     <execution>
                         <id>package</id>
                         <goals>
-                            <goal>features-create-kar</goal>
+                            <goal>kar</goal>
                         </goals>
                     </execution>
                 </executions>

http://git-wip-us.apache.org/repos/asf/karaf/blob/056239dc/demos/deployer/kar/pom.xml
----------------------------------------------------------------------
diff --git a/demos/deployer/kar/pom.xml b/demos/deployer/kar/pom.xml
index 52f1e67..5903c01 100644
--- a/demos/deployer/kar/pom.xml
+++ b/demos/deployer/kar/pom.xml
@@ -51,7 +51,7 @@
                     <execution>
                         <id>package</id>
                         <goals>
-                            <goal>features-create-kar</goal>
+                            <goal>kar</goal>
                         </goals>
                         <configuration>
                             <featuresFile>${project.basedir}/src/main/resources/features.xml</featuresFile>

http://git-wip-us.apache.org/repos/asf/karaf/blob/056239dc/demos/profiles/dynamic/pom.xml
----------------------------------------------------------------------
diff --git a/demos/profiles/dynamic/pom.xml b/demos/profiles/dynamic/pom.xml
index 6db6a5d..b13e2b2 100644
--- a/demos/profiles/dynamic/pom.xml
+++ b/demos/profiles/dynamic/pom.xml
@@ -95,13 +95,13 @@
                         <id>process-resources</id>
                         <phase>process-resources</phase>
                         <goals>
-                            <goal>install-kars</goal>
+                            <goal>assembly</goal>
                         </goals>
                     </execution>
                     <execution>
                         <id>package</id>
                         <goals>
-                            <goal>instance-create-archive</goal>
+                            <goal>archive</goal>
                         </goals>
                     </execution>
                 </executions>

http://git-wip-us.apache.org/repos/asf/karaf/blob/056239dc/demos/profiles/static/pom.xml
----------------------------------------------------------------------
diff --git a/demos/profiles/static/pom.xml b/demos/profiles/static/pom.xml
index 8db3ef1..556694e 100644
--- a/demos/profiles/static/pom.xml
+++ b/demos/profiles/static/pom.xml
@@ -109,13 +109,13 @@
                         <id>process-resources</id>
                         <phase>process-resources</phase>
                         <goals>
-                            <goal>install-kars</goal>
+                            <goal>assembly</goal>
                         </goals>
                     </execution>
                     <execution>
                         <id>package</id>
                         <goals>
-                            <goal>instance-create-archive</goal>
+                            <goal>archive</goal>
                         </goals>
                     </execution>
                 </executions>

http://git-wip-us.apache.org/repos/asf/karaf/blob/056239dc/manual/src/main/asciidoc/users-guide/kar.adoc
----------------------------------------------------------------------
diff --git a/manual/src/main/asciidoc/users-guide/kar.adoc b/manual/src/main/asciidoc/users-guide/kar.adoc
index c5d2f47..a56cfe0 100644
--- a/manual/src/main/asciidoc/users-guide/kar.adoc
+++ b/manual/src/main/asciidoc/users-guide/kar.adoc
@@ -101,20 +101,13 @@ You can create KAR files using Apache Maven, or directly in the Apache Karaf con
 
 Apache Karaf provides a Maven plugin: `karaf-maven-plugin`.
 
-The Apache Karaf Maven plugin provides the `features-create-kar` goal.
+The Apache Karaf Maven plugin provides the `kar` goal.
 
-The `features-create-kar` goal does:
+The `kar` goal does:
 1. Reads all features specified in the features XML.
 2. For each feature described in the features XML, the goal resolves the bundles described in the feature.
 3. The goal finally packages the features XML, and the resolved bundles in a zip file.
 
-You can also use the Karaf maven plugin. The features maven plugin provides an features-create-kar goal.
-
-The features-create-kar goal:
-1. Reads all features specified in the features descriptor.
-2. For each feature, it resolves the bundles defined in the feature.
-3. All bundles are packaged into the kar archive.
-
 For instance, the following Maven POM create `my-kar.kar`
 
 For instance, you can use the following POM to create a kar:
@@ -138,9 +131,9 @@ For instance, you can use the following POM to create a kar:
                 <version>3.0.0</version>
                 <executions>
                     <execution>
-                        <id>features-create-kar</id>
+                        <id>kar</id>
                         <goals>
-                            <goal>features-create-kar</goal>
+                            <goal>kar</goal>
                         </goals>
                         <configuration>
                             <featuresFile>src/main/resources/features.xml</featuresFile>

http://git-wip-us.apache.org/repos/asf/karaf/blob/056239dc/manual/src/main/webapp/developers-guide/custom-distribution.conf
----------------------------------------------------------------------
diff --git a/manual/src/main/webapp/developers-guide/custom-distribution.conf b/manual/src/main/webapp/developers-guide/custom-distribution.conf
index d3f3e62..ad45a2d 100644
--- a/manual/src/main/webapp/developers-guide/custom-distribution.conf
+++ b/manual/src/main/webapp/developers-guide/custom-distribution.conf
@@ -109,7 +109,7 @@ This is the minimal assembly pom changed to use the packaging and annotated
                     </execution>
                 </executions>
             </plugin>
-            <!-- karaf-maven-plugin will call both install-kar and instance-create-archive goals -->
+            <!-- karaf-maven-plugin will call both assembly and archive goals -->
             <plugin>
                 <groupId>org.apache.karaf.tooling</groupId>
                 <artifactId>karaf-maven-plugin</artifactId>

http://git-wip-us.apache.org/repos/asf/karaf/blob/056239dc/manual/src/main/webapp/developers-guide/karaf-maven-plugin-features-create-kar.conf
----------------------------------------------------------------------
diff --git a/manual/src/main/webapp/developers-guide/karaf-maven-plugin-features-create-kar.conf b/manual/src/main/webapp/developers-guide/karaf-maven-plugin-features-create-kar.conf
index 018f35e..1e8fe45 100644
--- a/manual/src/main/webapp/developers-guide/karaf-maven-plugin-features-create-kar.conf
+++ b/manual/src/main/webapp/developers-guide/karaf-maven-plugin-features-create-kar.conf
@@ -1,8 +1,8 @@
-h2. Goal {{karaf:features-create-kar}}
+h2. Goal {{karaf:kar}}
 
 Except in unusual circumstances, use the <packaging>kar</packaging> to run this goal.
 
-The {{karaf:features-create-kar}} goal assembles a KAR archive from a features XML descriptor file, normally generated in the same project with the {{karaf:features-generate-descriptor}} mojo.
+The {{karaf:kar}} goal assembles a KAR archive from a features XML descriptor file, normally generated in the same project with the {{karaf:features-generate-descriptor}} mojo.
 
 h2. kar layout
 

http://git-wip-us.apache.org/repos/asf/karaf/blob/056239dc/manual/src/main/webapp/developers-guide/karaf-maven-plugin-instance-create-archive.conf
----------------------------------------------------------------------
diff --git a/manual/src/main/webapp/developers-guide/karaf-maven-plugin-instance-create-archive.conf b/manual/src/main/webapp/developers-guide/karaf-maven-plugin-instance-create-archive.conf
index 23790d6..4b3a8a3 100644
--- a/manual/src/main/webapp/developers-guide/karaf-maven-plugin-instance-create-archive.conf
+++ b/manual/src/main/webapp/developers-guide/karaf-maven-plugin-instance-create-archive.conf
@@ -1,8 +1,8 @@
-h2. Goal {{karaf:instance-create-archive}}
+h2. Goal {{karaf:archive}}
 
 Normally this is run as part of the karaf-assembly packaging.
 
-The {{karaf:instance-create-archive}} goal packages a Karaf instance archive from a given assembled instance.
+The {{karaf:archive}} goal packages a Karaf instance archive from a given assembled instance.
 
 Both tar.gz and zip formats are generated in the destination folder.
 
@@ -21,7 +21,7 @@ The example below create archives for the given Karaf instance:
               <id>generate</id>
               <phase>package</phase>
               <goals>
-                <goal>instance-create-archive</goal>
+                <goal>archive</goal>
               </goals>
               <configuration>
                 <destDir>${project.build.directory}</destDir>

http://git-wip-us.apache.org/repos/asf/karaf/blob/056239dc/manual/src/main/webapp/developers-guide/karaf-maven-plugin.conf
----------------------------------------------------------------------
diff --git a/manual/src/main/webapp/developers-guide/karaf-maven-plugin.conf b/manual/src/main/webapp/developers-guide/karaf-maven-plugin.conf
index a7c5d70..c00516b 100644
--- a/manual/src/main/webapp/developers-guide/karaf-maven-plugin.conf
+++ b/manual/src/main/webapp/developers-guide/karaf-maven-plugin.conf
@@ -56,7 +56,7 @@ The {{karaf-maven-plugin}} provides several goals to help you create and validat
 || Goal || Description ||
 | {{[karaf:features-generate-descriptor|karaf-maven-plugin-features-generate-descriptor]}} | Generates a features XML descriptor for a set of bundles.  Used in feature and kar packagings. |
 | {{[karaf:features-validate-descriptor|karaf-maven-plugin-features-validate-descriptor]}} | Validate a features XML descriptor by checking if all the required imports can be matched to exports |
-| {{[karaf:features-create-kar|karaf-maven-plugin-features-create-kar]}} | Assemble a KAR archive from a features XML descriptor. Used in kar packaging.|
+| {{[karaf:kar|karaf-maven-plugin-features-create-kar]}} | Assemble a KAR archive from a features XML descriptor. Used in kar packaging.|
 
 
 h2. Instances and distributions goals
@@ -65,6 +65,6 @@ Normally you should use the karaf-assembly packaging instead of this individual
 The {{karaf-maven-plugin}} helps you to build custom Karaf distributions or archives existing Karaf instances:
 
 || Goal || Description ||
-| {{karaf:install-kars}} | Assemble a server from Maven feature-repo and kar dependencies. Used in karaf-assembly packaging.  See {{[karaf-assembly|custom-distribution]}}. |
-| {{[karaf:instance-create-archive|karaf-maven-plugin-instance-create-archive]}} | Package a server archive from an assembled server. . Used in karaf-assembly packaging.  See also {{[karaf-assembly|custom-distribution]}}.|
+| {{karaf:assembly}} | Assemble a server from Maven feature-repo and kar dependencies. Used in karaf-assembly packaging.  See {{[karaf-assembly|custom-distribution]}}. |
+| {{[karaf:archive|karaf-maven-plugin-instance-create-archive]}} | Package a server archive from an assembled server. . Used in karaf-assembly packaging.  See also {{[karaf-assembly|custom-distribution]}}.|
 | {{[karaf:features-add-to-repository|karaf-maven-plugin-features-add-to-repository]}} | (old style manual assemblies) Copies all the bundles required for a given set of features into a directory \\ (e.g. for creating your own Karaf-based distribution) |

http://git-wip-us.apache.org/repos/asf/karaf/blob/056239dc/manual/src/main/webapp/users-guide/kar.conf
----------------------------------------------------------------------
diff --git a/manual/src/main/webapp/users-guide/kar.conf b/manual/src/main/webapp/users-guide/kar.conf
index 57c06a3..7690373 100644
--- a/manual/src/main/webapp/users-guide/kar.conf
+++ b/manual/src/main/webapp/users-guide/kar.conf
@@ -87,20 +87,13 @@ h2. Maven
 
 Apache Karaf provides a Maven plugin: {{karaf-maven-plugin}}.
 
-The Apache Karaf Maven plugin provides the {{features-create-kar}} goal.
+The Apache Karaf Maven plugin provides the {{kar}} goal.
 
-The {{features-create-kar}} goal does:
+The {{kar}} goal does:
 1. Reads all features specified in the features XML.
 2. For each feature described in the features XML, the goal resolves the bundles described in the feature.
 3. The goal finally packages the features XML, and the resolved bundles in a zip file.
 
-You can also use the Karaf maven plugin. The features maven plugin provides an features-create-kar goal.
-
-The features-create-kar goal:
-1. Reads all features specified in the features descriptor.
-2. For each feature, it resolves the bundles defined in the feature.
-3. All bundles are packaged into the kar archive.
-
 For instance, the following Maven POM create {{my-kar.kar}}
 
 For instance, you can use the following POM to create a kar:
@@ -124,9 +117,9 @@ For instance, you can use the following POM to create a kar:
                 <version>3.0.0</version>
                 <executions>
                     <execution>
-                        <id>features-create-kar</id>
+                        <id>kar</id>
                         <goals>
-                            <goal>features-create-kar</goal>
+                            <goal>kar</goal>
                         </goals>
                         <configuration>
                             <featuresFile>src/main/resources/features.xml</featuresFile>

http://git-wip-us.apache.org/repos/asf/karaf/blob/056239dc/tooling/karaf-maven-plugin/src/it/test-kar-classifier/pom.xml
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/it/test-kar-classifier/pom.xml b/tooling/karaf-maven-plugin/src/it/test-kar-classifier/pom.xml
index 62c979d..cea616c 100644
--- a/tooling/karaf-maven-plugin/src/it/test-kar-classifier/pom.xml
+++ b/tooling/karaf-maven-plugin/src/it/test-kar-classifier/pom.xml
@@ -40,9 +40,9 @@
                         </goals>
                     </execution>
                     <execution>
-                        <id>features-create-kar</id>
+                        <id>kar</id>
                         <goals>
-                            <goal>features-create-kar</goal>
+                            <goal>kar</goal>
                         </goals>
                         <configuration>
                             <classifier>classy</classifier>

http://git-wip-us.apache.org/repos/asf/karaf/blob/056239dc/tooling/karaf-maven-plugin/src/it/test-kar-multiple-kars/pom.xml
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/it/test-kar-multiple-kars/pom.xml b/tooling/karaf-maven-plugin/src/it/test-kar-multiple-kars/pom.xml
index 3fde485..58626d5 100644
--- a/tooling/karaf-maven-plugin/src/it/test-kar-multiple-kars/pom.xml
+++ b/tooling/karaf-maven-plugin/src/it/test-kar-multiple-kars/pom.xml
@@ -55,9 +55,9 @@
                     </execution>
 
                     <execution>
-                        <id>features-create-kar1</id>
+                        <id>kar1</id>
                         <goals>
-                            <goal>features-create-kar</goal>
+                            <goal>kar</goal>
                         </goals>
                         <configuration>
                             <classifier>kar1</classifier>
@@ -65,9 +65,9 @@
                         </configuration>
                     </execution>
                     <execution>
-                        <id>features-create-kar2</id>
+                        <id>kar2</id>
                         <goals>
-                            <goal>features-create-kar</goal>
+                            <goal>kar</goal>
                         </goals>
                         <configuration>
                             <classifier>kar2</classifier>

http://git-wip-us.apache.org/repos/asf/karaf/blob/056239dc/tooling/karaf-maven-plugin/src/it/test-kar-with-pom-packaging/pom.xml
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/it/test-kar-with-pom-packaging/pom.xml b/tooling/karaf-maven-plugin/src/it/test-kar-with-pom-packaging/pom.xml
index e165180..b7832d7 100644
--- a/tooling/karaf-maven-plugin/src/it/test-kar-with-pom-packaging/pom.xml
+++ b/tooling/karaf-maven-plugin/src/it/test-kar-with-pom-packaging/pom.xml
@@ -41,9 +41,9 @@
                         </goals>
                     </execution>
                     <execution>
-                        <id>features-create-kar</id>
+                        <id>kar</id>
                         <goals>
-                            <goal>features-create-kar</goal>
+                            <goal>kar</goal>
                         </goals>
                     </execution>
                 </executions>

http://git-wip-us.apache.org/repos/asf/karaf/blob/056239dc/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/ArchiveMojo.java
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/ArchiveMojo.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/ArchiveMojo.java
new file mode 100644
index 0000000..2c24698
--- /dev/null
+++ b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/ArchiveMojo.java
@@ -0,0 +1,226 @@
+/*
+ * 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.
+ */
+package org.apache.karaf.tooling;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
+import org.apache.commons.compress.archivers.tar.TarConstants;
+import org.apache.commons.compress.archivers.zip.UnixStat;
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
+import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
+import org.apache.karaf.tooling.utils.MojoSupport;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+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;
+
+/**
+ * Package a server archive from an assembled server
+ */
+@Mojo(name = "archive", defaultPhase = LifecyclePhase.PACKAGE, requiresDependencyResolution = ResolutionScope.RUNTIME)
+public class ArchiveMojo extends MojoSupport {
+
+    /**
+     * The target directory of the project.
+     */
+    @Parameter(defaultValue="${project.build.directory}")
+    private File destDir;
+
+    /**
+     * The location of the server repository.
+     */
+    @Parameter(defaultValue="${project.build.directory}/assembly")
+    private File targetServerDirectory;
+
+    /**
+     * The target file to set as the project's artifact.
+     */
+    @Parameter(defaultValue="${project.artifactId}-${project.version}")
+    private File targetFile;
+
+    /**
+     * pack a assembly as a tar.gz archive
+     */
+    @Parameter
+    private boolean archiveTarGz = true;
+
+    /**
+     * pack a assembly as a zip archive
+     */
+    @Parameter
+    private boolean archiveZip = true;
+
+    /**
+     * use symbolic links in tar.gz or zip archives
+     *
+     * Symbolic links are not very well supported by windows Platform.
+     * At least, is does not work on WinXP + NTFS, so do not include them
+     * for now. So the default is false.
+     */
+    @Parameter
+    private boolean useSymLinks = false;
+
+    public void execute() throws MojoExecutionException, MojoFailureException {
+        getLog().debug("Setting artifact file: " + targetFile);
+        org.apache.maven.artifact.Artifact artifact = project.getArtifact();
+        artifact.setFile(targetFile);
+        try {
+            //now pack up the server.
+            if(archiveTarGz){
+                archive("tar.gz");
+            }
+            if(archiveZip) {
+                archive("zip");
+            }
+        } catch (Exception e) {
+            throw new MojoExecutionException("Could not archive plugin", e);
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+	private void archive(String type) throws IOException {
+        Artifact artifact1 = factory.createArtifactWithClassifier(project.getArtifact().getGroupId(), project.getArtifact().getArtifactId(), project.getArtifact().getVersion(), type, "bin");
+        File target1 = archive(targetServerDirectory, destDir, artifact1);
+        projectHelper.attachArtifact( project, artifact1.getType(), null, target1 );
+    }
+
+    public File archive(File source, File dest, Artifact artifact) throws //ArchiverException,
+            IOException {
+        String serverName = null;
+        if (targetFile != null && project.getPackaging().equals("karaf-assembly")) {
+            serverName = targetFile.getName();
+        } else {
+           serverName = artifact.getArtifactId() + "-" + artifact.getVersion();
+        }
+        dest = new File(dest, serverName + "." + artifact.getType());
+
+        if ("tar.gz".equals(artifact.getType())) {
+            try (
+                    OutputStream fOut = Files.newOutputStream(dest.toPath());
+                    OutputStream bOut = new BufferedOutputStream(fOut);
+                    OutputStream gzOut = new GzipCompressorOutputStream(bOut);
+                    TarArchiveOutputStream tOut = new TarArchiveOutputStream(gzOut);
+                    DirectoryStream<Path> children = Files.newDirectoryStream(source.toPath())
+
+            ) {
+                tOut.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);
+                tOut.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_POSIX);
+                for (Path child : children) {
+                    addFileToTarGz(tOut, child, serverName + "/");
+                }
+            }
+        } else if ("zip".equals(artifact.getType())) {
+            try (
+                    OutputStream fOut = Files.newOutputStream(dest.toPath());
+                    OutputStream bOut = new BufferedOutputStream(fOut);
+                    ZipArchiveOutputStream tOut = new ZipArchiveOutputStream(bOut);
+                    DirectoryStream<Path> children = Files.newDirectoryStream(source.toPath())
+
+            ) {
+                for (Path child : children) {
+                    addFileToZip(tOut, child, serverName + "/");
+                }
+            }
+        } else {
+            throw new IllegalArgumentException("Unknown target type: " + artifact.getType());
+        }
+
+        return dest;
+    }
+
+    private void addFileToTarGz(TarArchiveOutputStream tOut, Path f, String base) throws IOException {
+        if (Files.isDirectory(f)) {
+            String entryName = base + f.getFileName().toString() + "/";
+            TarArchiveEntry tarEntry = new TarArchiveEntry(entryName);
+            tOut.putArchiveEntry(tarEntry);
+            tOut.closeArchiveEntry();
+            try (DirectoryStream<Path> children = Files.newDirectoryStream(f)) {
+                for (Path child : children) {
+                    addFileToTarGz(tOut, child, entryName);
+                }
+            }
+        } else if (useSymLinks && Files.isSymbolicLink(f)) {
+            String entryName = base + f.getFileName().toString();
+            TarArchiveEntry tarEntry = new TarArchiveEntry(entryName, TarConstants.LF_SYMLINK);
+            tarEntry.setLinkName(Files.readSymbolicLink(f).toString());
+            tOut.putArchiveEntry(tarEntry);
+            tOut.closeArchiveEntry();
+        }  else {
+            String entryName = base + f.getFileName().toString();
+            TarArchiveEntry tarEntry = new TarArchiveEntry(entryName);
+            tarEntry.setSize(Files.size(f));
+            if (entryName.contains("/bin/")) {
+                tarEntry.setMode(0755);
+                if (entryName.endsWith(".bat")) {
+                    return;
+                }
+            }
+            tOut.putArchiveEntry(tarEntry);
+            Files.copy(f, tOut);
+            tOut.closeArchiveEntry();
+        }
+    }
+
+    private void addFileToZip(ZipArchiveOutputStream tOut, Path f, String base) throws IOException {
+        if (Files.isDirectory(f)) {
+            String entryName = base + f.getFileName().toString() + "/";
+            ZipArchiveEntry zipEntry = new ZipArchiveEntry(entryName);
+            tOut.putArchiveEntry(zipEntry);
+            tOut.closeArchiveEntry();
+            try (DirectoryStream<Path> children = Files.newDirectoryStream(f)) {
+                for (Path child : children) {
+                    addFileToZip(tOut, child, entryName);
+                }
+            }
+        } else if (useSymLinks && Files.isSymbolicLink(f)) {
+            String entryName = base + f.getFileName().toString();
+            ZipArchiveEntry zipEntry = new ZipArchiveEntry(entryName);
+            zipEntry.setUnixMode(UnixStat.LINK_FLAG | UnixStat.DEFAULT_FILE_PERM);
+            tOut.putArchiveEntry(zipEntry);
+            tOut.write(Files.readSymbolicLink(f).toString().getBytes());
+            tOut.closeArchiveEntry();
+        }  else {
+            String entryName = base + f.getFileName().toString();
+            ZipArchiveEntry zipEntry = new ZipArchiveEntry(entryName);
+            zipEntry.setSize(Files.size(f));
+            if (entryName.contains("/bin/")) {
+                if (!entryName.endsWith(".bat")) {
+                    return;
+                }
+                zipEntry.setUnixMode(0755);
+            }
+            tOut.putArchiveEntry(zipEntry);
+            Files.copy(f, tOut);
+            tOut.closeArchiveEntry();
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/056239dc/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/AssemblyMojo.java
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/AssemblyMojo.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/AssemblyMojo.java
new file mode 100644
index 0000000..121fdf9
--- /dev/null
+++ b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/AssemblyMojo.java
@@ -0,0 +1,321 @@
+/*
+ * 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.
+ */
+package org.apache.karaf.tooling;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.karaf.profile.assembly.Builder;
+import org.apache.karaf.tooling.utils.IoUtils;
+import org.apache.karaf.tooling.utils.MavenUtil;
+import org.apache.karaf.tooling.utils.MojoSupport;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+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;
+
+/**
+ * Installs kar dependencies into a server-under-construction in target/assembly
+ */
+@Mojo(name = "assembly", defaultPhase = LifecyclePhase.PROCESS_RESOURCES, requiresDependencyResolution = ResolutionScope.RUNTIME)
+public class AssemblyMojo extends MojoSupport {
+
+    /**
+     * Base directory used to copy the resources during the build (working directory).
+     */
+    @Parameter(defaultValue = "${project.build.directory}/assembly")
+    protected File workDirectory;
+
+    /**
+     * Features configuration file (etc/org.apache.karaf.features.cfg).
+     */
+    @Parameter(defaultValue = "${project.build.directory}/assembly/etc/org.apache.karaf.features.cfg")
+    protected File featuresCfgFile;
+
+    /**
+     * startup.properties file.
+     */
+    @Parameter(defaultValue = "${project.build.directory}/assembly/etc/startup.properties")
+    protected File startupPropertiesFile;
+
+    /**
+     * Directory used during build to construction the Karaf system repository.
+     */
+    @Parameter(defaultValue="${project.build.directory}/assembly/system")
+    protected File systemDirectory;
+
+    /**
+     * default start level for bundles in features that don't specify it.
+     */
+    @Parameter
+    protected int defaultStartLevel = 30;
+
+    @Parameter
+    private List<String> startupRepositories;
+    @Parameter
+    private List<String> bootRepositories;
+    @Parameter
+    private List<String> installedRepositories;
+
+    /**
+     * List of features from runtime-scope features xml and kars to be installed into system and listed in startup.properties.
+     */
+    @Parameter
+    private List<String> startupFeatures;
+
+    /**
+     * List of features from runtime-scope features xml and kars to be installed into system repo and listed in features service boot features.
+     */
+    @Parameter
+    private List<String> bootFeatures;
+
+    /**
+     * List of features from runtime-scope features xml and kars to be installed into system repo and not mentioned elsewhere.
+     */
+    @Parameter
+    private List<String> installedFeatures;
+
+    @Parameter
+    private List<String> blacklistedFeatures;
+
+    @Parameter
+    private List<String> startupBundles;
+    @Parameter
+    private List<String> bootBundles;
+    @Parameter
+    private List<String> installedBundles;
+    @Parameter
+    private List<String> blacklistedBundles;
+    
+    @Parameter
+    private String profilesUri;
+
+    @Parameter
+    private List<String> bootProfiles;
+
+    @Parameter
+    private List<String> startupProfiles;
+
+    @Parameter
+    private List<String> installedProfiles;
+
+    @Parameter
+    private List<String> blacklistedProfiles;
+
+    @Parameter
+    private Builder.BlacklistPolicy blacklistPolicy;
+
+    /**
+     * Ignore the dependency attribute (dependency="[true|false]") on bundle
+     */
+    @Parameter(defaultValue = "false")
+    protected boolean ignoreDependencyFlag;
+
+    /**
+     * Additional feature repositories
+     */
+    @Parameter
+    protected List<String> featureRepositories;
+
+    @Parameter
+    protected List<String> libraries;
+
+    /**
+     * Use reference: style urls in startup.properties
+     */
+    @Parameter(defaultValue = "false")
+    protected boolean useReferenceUrls;
+
+    @Parameter
+    protected boolean installAllFeaturesByDefault = true;
+
+    @Parameter
+    protected Builder.KarafVersion karafVersion = Builder.KarafVersion.v4x;
+
+    @Override
+    public void execute() throws MojoExecutionException, MojoFailureException {
+        try {
+            doExecute();
+        }
+        catch (MojoExecutionException | MojoFailureException e) {
+            throw e;
+        }
+        catch (Exception e) {
+            throw new MojoExecutionException("Unable to build assembly", e);
+        }
+    }
+
+    protected void doExecute() throws Exception {
+        startupRepositories = nonNullList(startupRepositories);
+        bootRepositories = nonNullList(bootRepositories);
+        installedRepositories = nonNullList(installedRepositories);
+        startupBundles = nonNullList(startupBundles);
+        bootBundles = nonNullList(bootBundles);
+        installedBundles = nonNullList(installedBundles);
+        blacklistedBundles = nonNullList(blacklistedBundles);
+        startupFeatures = nonNullList(startupFeatures);
+        bootFeatures = nonNullList(bootFeatures);
+        installedFeatures = nonNullList(installedFeatures);
+        blacklistedFeatures = nonNullList(blacklistedFeatures);
+        startupProfiles = nonNullList(startupProfiles);
+        bootProfiles = nonNullList(bootProfiles);
+        installedProfiles = nonNullList(installedProfiles);
+        blacklistedProfiles = nonNullList(blacklistedProfiles);
+
+        if (!startupProfiles.isEmpty() || !bootProfiles.isEmpty() || !installedProfiles.isEmpty()) {
+            if (profilesUri == null) {
+                throw new IllegalArgumentException("profilesDirectory must be specified");
+            }
+        }
+
+        if (featureRepositories != null && !featureRepositories.isEmpty()) {
+            getLog().warn("Use of featureRepositories is deprecated, use startupRepositories, bootRepositories or installedRepositories instead");
+            startupRepositories.addAll(featureRepositories);
+            bootRepositories.addAll(featureRepositories);
+            installedRepositories.addAll(featureRepositories);
+        }
+
+        Builder builder = Builder.newInstance();
+
+        // Set up blacklisted items
+        builder.blacklistBundles(blacklistedBundles);
+        builder.blacklistFeatures(blacklistedFeatures);
+        builder.blacklistProfiles(blacklistedProfiles);
+        builder.blacklistPolicy(blacklistPolicy);
+
+        // creating system directory
+        getLog().info("Creating work directory");
+        builder.homeDirectory(workDirectory.toPath());
+        IoUtils.deleteRecursive(workDirectory);
+        workDirectory.mkdirs();
+
+        List<String> startupKars = new ArrayList<>();
+        List<String> bootKars = new ArrayList<>();
+        List<String> installedKars = new ArrayList<>();
+
+        // Loading kars and features repositories
+        getLog().info("Loading kar and features repositories dependencies");
+        for (Artifact artifact : project.getDependencyArtifacts()) {
+            Builder.Stage stage;
+            switch (artifact.getScope()) {
+            case "compile":
+                stage = Builder.Stage.Startup;
+                break;
+            case "runtime":
+                stage = Builder.Stage.Boot;
+                break;
+            case "provided":
+                stage = Builder.Stage.Installed;
+                break;
+            default:
+                continue;
+            }
+            if ("kar".equals(artifact.getType())) {
+                String uri = artifactToMvn(artifact);
+                switch (stage) {
+                case Startup:   startupKars.add(uri); break;
+                case Boot:      bootKars.add(uri); break;
+                case Installed: installedKars.add(uri); break;
+                }
+            } else if ("features".equals(artifact.getClassifier())) {
+                String uri = artifactToMvn(artifact);
+                switch (stage) {
+                case Startup:   startupRepositories.add(uri); break;
+                case Boot:      bootRepositories.add(uri); break;
+                case Installed: installedRepositories.add(uri); break;
+                }
+            } else if ("jar".equals(artifact.getType()) || "bundle".equals(artifact.getType())) {
+                String uri = artifactToMvn(artifact);
+                switch (stage) {
+                case Startup:   startupBundles.add(uri); break;
+                case Boot:      bootBundles.add(uri); break;
+                case Installed: installedBundles.add(uri); break;
+                }
+            }
+        }
+
+        builder.karafVersion(karafVersion)
+               .useReferenceUrls(useReferenceUrls)
+               .defaultAddAll(installAllFeaturesByDefault)
+               .ignoreDependencyFlag(ignoreDependencyFlag);
+        if (profilesUri != null) {
+            builder.profilesUris(profilesUri);
+        }
+        if (libraries != null) {
+            builder.libraries(libraries.toArray(new String[libraries.size()]));
+        }
+        // Startup
+        builder.defaultStage(Builder.Stage.Startup)
+               .kars(toArray(startupKars))
+               .repositories(startupFeatures.isEmpty() && startupProfiles.isEmpty() && installAllFeaturesByDefault, toArray(startupRepositories))
+               .features(toArray(startupFeatures))
+               .bundles(toArray(startupBundles))
+               .profiles(toArray(startupProfiles));
+        // Boot
+        builder.defaultStage(Builder.Stage.Boot)
+                .kars(toArray(bootKars))
+                .repositories(bootFeatures.isEmpty() && bootProfiles.isEmpty() && installAllFeaturesByDefault, toArray(bootRepositories))
+                .features(toArray(bootFeatures))
+                .bundles(toArray(bootBundles))
+                .profiles(toArray(bootProfiles));
+        // Installed
+        builder.defaultStage(Builder.Stage.Installed)
+                .kars(toArray(installedKars))
+                .repositories(installedFeatures.isEmpty() && installedProfiles.isEmpty() && installAllFeaturesByDefault, toArray(installedRepositories))
+                .features(toArray(installedFeatures))
+                .bundles(toArray(installedBundles))
+                .profiles(toArray(installedProfiles));
+
+        builder.generateAssembly();
+    }
+
+    private String artifactToMvn(Artifact artifact) throws MojoExecutionException {
+        String uri;
+
+        String groupId = artifact.getGroupId();
+        String artifactId = artifact.getArtifactId();
+        String version = artifact.getBaseVersion();
+        String type = artifact.getArtifactHandler().getExtension();
+        String classifier = artifact.getClassifier();
+
+        if (MavenUtil.isEmpty(classifier)) {
+            if ("jar".equals(type)) {
+                uri = String.format("mvn:%s/%s/%s", groupId, artifactId, version);
+            } else {
+                uri = String.format("mvn:%s/%s/%s/%s", groupId, artifactId, version, type);
+            }
+        } else {
+            uri = String.format("mvn:%s/%s/%s/%s/%s", groupId, artifactId, version, type, classifier);
+        }
+        return uri;
+    }
+
+    private String[] toArray(List<String> strings) {
+        return strings.toArray(new String[strings.size()]);
+    }
+
+    private List<String> nonNullList(List<String> list) {
+        return list == null ? new ArrayList<String>() : list;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/056239dc/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/KarMojo.java
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/KarMojo.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/KarMojo.java
new file mode 100644
index 0000000..6b3f9a9
--- /dev/null
+++ b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/KarMojo.java
@@ -0,0 +1,398 @@
+/*
+ * 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.
+ */
+package org.apache.karaf.tooling;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.karaf.deployer.kar.KarArtifactInstaller;
+import org.apache.karaf.features.BundleInfo;
+import org.apache.karaf.features.ConfigFileInfo;
+import org.apache.karaf.features.internal.model.Feature;
+import org.apache.karaf.features.internal.model.Features;
+import org.apache.karaf.features.internal.model.JaxbUtil;
+import org.apache.karaf.tooling.utils.MavenUtil;
+import org.apache.karaf.tooling.utils.MojoSupport;
+import org.apache.maven.archiver.MavenArchiveConfiguration;
+import org.apache.maven.archiver.MavenArchiver;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
+import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
+import org.apache.maven.artifact.repository.metadata.Metadata;
+import org.apache.maven.artifact.repository.metadata.Snapshot;
+import org.apache.maven.artifact.repository.metadata.SnapshotVersion;
+import org.apache.maven.artifact.repository.metadata.Versioning;
+import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Writer;
+import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.Component;
+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.codehaus.plexus.archiver.Archiver;
+import org.codehaus.plexus.archiver.jar.JarArchiver;
+
+/**
+ * Assemble a kar archive from a features.xml file
+ */
+@Mojo(name = "kar", defaultPhase = LifecyclePhase.PACKAGE, requiresDependencyResolution = ResolutionScope.RUNTIME)
+public class KarMojo extends MojoSupport {
+
+    /**
+     * The maven archive configuration to use.
+     * <p/>
+     * See <a href="http://maven.apache.org/ref/current/maven-archiver/apidocs/org/apache/maven/archiver/MavenArchiveConfiguration.html">the Javadocs for MavenArchiveConfiguration</a>.
+     */
+    @Parameter
+    private MavenArchiveConfiguration archive = new MavenArchiveConfiguration();
+
+    /**
+     * The Jar archiver.
+     */
+    @Component(role = Archiver.class, hint="jar")
+    private JarArchiver jarArchiver = null;
+
+    /**
+     * Directory containing the generated archive.
+     */
+    @Parameter(defaultValue = "${project.build.directory}")
+    private File outputDirectory = null;
+
+    /**
+     * Name of the generated archive.
+     */
+    @Parameter(defaultValue = "${project.build.finalName}")
+    private String finalName = null;
+
+    /**
+     * Ignore the dependency flag on the bundles in the features XML
+     */
+    @Parameter(defaultValue = "false")
+    private boolean ignoreDependencyFlag;
+
+    /**
+     * Classifier to add to the artifact generated. If given, the artifact will be attached.
+     * If it's not given, it will merely be written to the output directory according to the finalName.
+     */
+    @Parameter
+    protected String classifier;
+
+    /**
+     * Location of resources directory for additional content to include in the kar.
+     * Note that it includes everything under classes so as to include maven-remote-resources
+     */
+    @Parameter(defaultValue = "${project.build.directory}/classes")
+    private File resourcesDir;
+
+
+    /**
+     * The features file to use as instructions
+     */
+    @Parameter(defaultValue = "${project.build.directory}/feature/feature.xml")
+    private String featuresFile;
+
+
+    /**
+     * The wrapper repository in the kar.
+     */
+    @Parameter(defaultValue = "${repositoryPath}")
+    private String repositoryPath = "repository/";
+
+    private static final Pattern mvnPattern = Pattern.compile("mvn:([^/ ]+)/([^/ ]+)/([^/ ]*)(/([^/ ]+)(/([^/ ]+))?)?");
+
+
+    //
+    // Mojo
+    //
+
+    public void execute() throws MojoExecutionException, MojoFailureException {
+        File featuresFileResolved = resolveFile(featuresFile);
+        String groupId = project.getGroupId();
+        String artifactId = project.getArtifactId();
+        String version = project.getVersion();
+
+        if (isMavenUrl(featuresFile)) {
+            Artifact artifactTemp = resourceToArtifact(featuresFile, false);
+            if (artifactTemp.getGroupId() != null)
+                groupId = artifactTemp.getGroupId();
+            if (artifactTemp.getArtifactHandler() != null)
+                artifactId = artifactTemp.getArtifactId();
+            if (artifactTemp.getVersion() != null)
+                version = artifactTemp.getVersion();
+        }
+
+        List<Artifact> resources = readResources(featuresFileResolved);
+
+        // Build the archive
+        File archive = createArchive(resources, featuresFileResolved, groupId, artifactId, version);
+
+        // if no classifier is specified and packaging is not kar, display a warning
+        // and attach artifact
+        if (classifier == null && !this.getProject().getPackaging().equals("kar")) {
+            this.getLog().warn("Your project should use the \"kar\" packaging or configure a \"classifier\" for kar attachment");
+            projectHelper.attachArtifact(getProject(), "kar", null, archive);
+            return;
+        }
+
+        // Attach the generated archive for install/deploy
+        if (classifier != null) {
+            projectHelper.attachArtifact(getProject(), "kar", classifier, archive);
+        } else {
+            getProject().getArtifact().setFile(archive);
+        }
+    }
+
+    private File resolveFile(String file) {
+        File fileResolved = null;
+
+        if (isMavenUrl(file)) {
+            fileResolved = new File(fromMaven(file));
+            try {
+                Artifact artifactTemp = resourceToArtifact(file, false);
+                if (!fileResolved.exists()) {
+                    try {
+                        artifactResolver.resolve(artifactTemp, remoteRepos, localRepo);
+                        fileResolved = artifactTemp.getFile();
+                    } catch (ArtifactResolutionException e) {
+                        getLog().error("Artifact was not resolved", e);
+                    } catch (ArtifactNotFoundException e) {
+                        getLog().error("Artifact was not found", e);
+                    }
+                }
+            } catch (MojoExecutionException e) {
+                getLog().error(e);
+            }
+        } else {
+            fileResolved = new File(file);
+        }
+
+        return fileResolved;
+    }
+
+    /**
+     * Read bundles and configuration files in the features file.
+     *
+     * @return
+     * @throws MojoExecutionException
+     */
+    private List<Artifact> readResources(File featuresFile) throws MojoExecutionException {
+        List<Artifact> resources = new ArrayList<Artifact>();
+        try {
+            Features features = JaxbUtil.unmarshal(featuresFile.toURI().toASCIIString(), false);
+            for (Feature feature : features.getFeature()) {
+                for (BundleInfo bundle : feature.getBundles()) {
+                    if (ignoreDependencyFlag || (!ignoreDependencyFlag && !bundle.isDependency())) {
+                        resources.add(resourceToArtifact(bundle.getLocation(), false));
+                    }
+                }
+                for (ConfigFileInfo configFile : feature.getConfigurationFiles()) {
+                    resources.add(resourceToArtifact(configFile.getLocation(), false));
+                }
+            }
+            return resources;
+        } catch (MojoExecutionException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new MojoExecutionException("Could not interpret features.xml", e);
+        }
+    }
+
+    /**
+     * Generates the configuration archive.
+     *
+     * @param bundles
+     */
+    @SuppressWarnings("deprecation")
+	private File createArchive(List<Artifact> bundles, File featuresFile, String groupId, String artifactId, String version) throws MojoExecutionException {
+        ArtifactRepositoryLayout layout = new DefaultRepositoryLayout();
+        File archiveFile = getArchiveFile(outputDirectory, finalName, classifier);
+
+        MavenArchiver archiver = new MavenArchiver();
+        archiver.setArchiver(jarArchiver);
+        archiver.setOutputFile(archiveFile);
+
+        try {
+            //TODO should .kar be a bundle?
+//            archive.addManifestEntry(Constants.BUNDLE_NAME, project.getName());
+//            archive.addManifestEntry(Constants.BUNDLE_VENDOR, project.getOrganization().getName());
+//            ArtifactVersion version = project.getArtifact().getSelectedVersion();
+//            String versionString = "" + version.getMajorVersion() + "." + version.getMinorVersion() + "." + version.getIncrementalVersion();
+//            if (version.getQualifier() != null) {
+//                versionString += "." + version.getQualifier();
+//            }
+//            archive.addManifestEntry(Constants.BUNDLE_VERSION, versionString);
+//            archive.addManifestEntry(Constants.BUNDLE_MANIFESTVERSION, "2");
+//            archive.addManifestEntry(Constants.BUNDLE_DESCRIPTION, project.getDescription());
+//            // NB, no constant for this one
+//            archive.addManifestEntry("Bundle-License", ((License) project.getLicenses().get(0)).getUrl());
+//            archive.addManifestEntry(Constants.BUNDLE_DOCURL, project.getUrl());
+//            //TODO this might need some help
+//            archive.addManifestEntry(Constants.BUNDLE_SYMBOLICNAME, project.getArtifactId());
+
+            //include the feature.xml
+			Artifact featureArtifact = factory.createArtifactWithClassifier(groupId, artifactId, version, "xml", KarArtifactInstaller.FEATURE_CLASSIFIER);
+            jarArchiver.addFile(featuresFile, repositoryPath + layout.pathOf(featureArtifact));
+
+            if (featureArtifact.isSnapshot()) {
+                // the artifact is a snapshot, create the maven-metadata-local.xml
+                getLog().debug("Feature artifact is a SNAPSHOT, handling the maven-metadata-local.xml");
+                File metadataTarget = new File(featuresFile.getParentFile(), "maven-metadata-local.xml");
+                getLog().debug("Looking for " + metadataTarget.getAbsolutePath());
+                if (!metadataTarget.exists()) {
+                    // the maven-metadata-local.xml doesn't exist, create it
+                    getLog().debug(metadataTarget.getAbsolutePath() + " doesn't exist, create it");
+                    Metadata metadata = new Metadata();
+                    metadata.setGroupId(featureArtifact.getGroupId());
+                    metadata.setArtifactId(featureArtifact.getArtifactId());
+                    metadata.setVersion(featureArtifact.getVersion());
+                    metadata.setModelVersion("1.1.0");
+
+                    Versioning versioning = new Versioning();
+                    versioning.setLastUpdatedTimestamp(new Date(System.currentTimeMillis()));
+                    Snapshot snapshot = new Snapshot();
+                    snapshot.setLocalCopy(true);
+                    versioning.setSnapshot(snapshot);
+                    SnapshotVersion snapshotVersion = new SnapshotVersion();
+                    snapshotVersion.setClassifier(featureArtifact.getClassifier());
+                    snapshotVersion.setVersion(featureArtifact.getVersion());
+                    snapshotVersion.setExtension(featureArtifact.getType());
+                    snapshotVersion.setUpdated(versioning.getLastUpdated());
+                    versioning.addSnapshotVersion(snapshotVersion);
+
+                    metadata.setVersioning(versioning);
+
+                    MetadataXpp3Writer metadataWriter = new MetadataXpp3Writer();
+                    try {
+                        Writer writer = new FileWriter(metadataTarget);
+                        metadataWriter.write(writer, metadata);
+                    } catch (Exception e) {
+                        getLog().warn("Could not create maven-metadata-local.xml", e);
+                        getLog().warn("It means that this SNAPSHOT could be overwritten by an older one present on remote repositories");
+                    }
+                }
+                getLog().debug("Adding file " + metadataTarget.getAbsolutePath() + " in the jar path " + repositoryPath + layout.pathOf(featureArtifact).substring(0, layout.pathOf(featureArtifact).lastIndexOf('/')) + "/maven-metadata-local.xml");
+                jarArchiver.addFile(metadataTarget, repositoryPath + layout.pathOf(featureArtifact).substring(0, layout.pathOf(featureArtifact).lastIndexOf('/')) + "/maven-metadata-local.xml");
+            }
+
+            for (Artifact artifact : bundles) {
+                artifactResolver.resolve(artifact, remoteRepos, localRepo);
+                File localFile = artifact.getFile();
+
+                if (artifact.isSnapshot()) {
+                    // the artifact is a snapshot, create the maven-metadata-local.xml
+                    File metadataTarget = new File(localFile.getParentFile(), "maven-metadata-local.xml");
+                    if (!metadataTarget.exists()) {
+                        // the maven-metadata-local.xml doesn't exist, create it
+                        try {
+                            MavenUtil.generateMavenMetadata(artifact, metadataTarget);
+                        } catch (Exception e) {
+                            getLog().warn("Could not create maven-metadata-local.xml", e);
+                            getLog().warn("It means that this SNAPSHOT could be overwritten by an older one present on remote repositories");
+                        }
+                    }
+                    jarArchiver.addFile(metadataTarget, repositoryPath + layout.pathOf(artifact).substring(0, layout.pathOf(artifact).lastIndexOf('/')) + "/maven-metadata-local.xml");
+                }
+
+                //TODO this may not be reasonable, but... resolved snapshot artifacts have timestamped versions
+                //which do not work in startup.properties.
+                artifact.setVersion(artifact.getBaseVersion());
+                String targetFileName = repositoryPath + layout.pathOf(artifact);
+                jarArchiver.addFile(localFile, targetFileName);
+            }
+
+            if (resourcesDir.isDirectory()) {
+                archiver.getArchiver().addDirectory(resourcesDir);
+            }
+            archiver.createArchive(project, archive);
+
+            return archiveFile;
+        } catch (Exception e) {
+            throw new MojoExecutionException("Failed to create archive", e);
+        }
+    }
+
+    protected static boolean isMavenUrl(String name) {
+        Matcher m = mvnPattern.matcher(name);
+        return m.matches();
+    }
+
+    /**
+     * Return a path for an artifact:
+     * - if the input is already a path (doesn't contain ':'), the same path is returned.
+     * - if the input is a Maven URL, the input is converted to a default repository location path, type and classifier
+     *   are optional.
+     *
+     * @param name artifact data
+     * @return path as supplied or a default Maven repository path
+     */
+    private static String fromMaven(String name) {
+        Matcher m = mvnPattern.matcher(name);
+        if (!m.matches()) {
+            return name;
+        }
+
+        StringBuilder b = new StringBuilder();
+        b.append(m.group(1));
+        for (int i = 0; i < b.length(); i++) {
+            if (b.charAt(i) == '.') {
+                b.setCharAt(i, '/');
+            }
+        }
+        b.append("/"); // groupId
+        String artifactId = m.group(2);
+        String version = m.group(3);
+        String extension = m.group(5);
+        String classifier = m.group(7);
+        b.append(artifactId).append("/"); // artifactId
+        b.append(version).append("/"); // version
+        b.append(artifactId).append("-").append(version);
+        if (present(classifier)) {
+            b.append("-").append(classifier);
+        }
+        if (present(classifier)) {
+            b.append(".").append(extension);
+        } else {
+            b.append(".jar");
+        }
+        return b.toString();
+    }
+
+    private static boolean present(String part) {
+        return part != null && !part.isEmpty();
+    }
+
+    protected static File getArchiveFile(final File basedir, final String finalName, String classifier) {
+        if (classifier == null) {
+            classifier = "";
+        } else if (classifier.trim().length() > 0 && !classifier.startsWith("-")) {
+            classifier = "-" + classifier;
+        }
+
+        return new File(basedir, finalName + classifier + ".kar");
+    }
+
+
+}