You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 09:15:25 UTC

[sling-maven-sling-plugin] 01/48: Import initial Sling source

This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag maven-sling-plugin-2.0.2-incubator
in repository https://gitbox.apache.org/repos/asf/sling-maven-sling-plugin.git

commit 14afbbdbd507a3055535f941c050144a015e3755
Author: Felix Meschberger <fm...@apache.org>
AuthorDate: Mon Sep 10 08:50:41 2007 +0000

    Import initial Sling source
    
    git-svn-id: https://svn.apache.org/repos/asf/incubator/sling/trunk/maven-sling-plugin@574179 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                            |  85 +++++
 .../sling/maven/assembly/AssemblyPlugin.java       | 352 +++++++++++++++++++++
 .../sling/maven/bundlesupport/BundleCopyMojo.java  | 130 ++++++++
 .../maven/bundlesupport/BundleDeployMojo.java      | 264 ++++++++++++++++
 .../sling/maven/bundlesupport/BundleListMojo.java  | 305 ++++++++++++++++++
 .../java/org/apache/sling/maven/war/WarMojo.java   | 276 ++++++++++++++++
 src/main/resources/META-INF/LICENSE                | 202 ++++++++++++
 src/main/resources/META-INF/NOTICE                 |   8 +
 src/main/resources/META-INF/plexus/components.xml  |  56 ++++
 9 files changed, 1678 insertions(+)

diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..de46380
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+    Copyright 2007 The Apache Software Foundation.
+    
+    Licensed 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.
+-->
+<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/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>sling</artifactId>
+        <version>1-incubator-SNAPSHOT</version>
+        <relativePath>../parent/pom.xml</relativePath>
+    </parent>
+
+    <groupId>org.apache.sling</groupId>
+    <artifactId>maven-sling-plugin</artifactId>
+    <version>2.0.0-incubator-SNAPSHOT</version>
+    <packaging>maven-plugin</packaging>
+
+    <name>Sling - Maven Plugin for Supporting Bundle Development</name>
+    <description>
+        Maven Plugin supporting various Sling Development Tasks
+    </description>
+
+    <scm>
+        <url>
+            http://svn.day.com/repos/sling/trunk/maven-sling-plugin
+        </url>
+        <connection>scm:svn:${scm.url}</connection>
+        <developerConnection>scm:svn:${scm.url}</developerConnection>
+    </scm>
+
+    <reporting>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-plugin-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </reporting>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>osgi_R4_core</artifactId>
+            <version>1.0</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>commons-httpclient</groupId>
+            <artifactId>commons-httpclient</artifactId>
+            <version>3.0.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>1.3.2</version>
+            <scope>compile</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-plugin-api</artifactId>
+            <version>2.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-archiver</artifactId>
+            <version>2.0</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/src/main/java/org/apache/sling/maven/assembly/AssemblyPlugin.java b/src/main/java/org/apache/sling/maven/assembly/AssemblyPlugin.java
new file mode 100644
index 0000000..6368b2c
--- /dev/null
+++ b/src/main/java/org/apache/sling/maven/assembly/AssemblyPlugin.java
@@ -0,0 +1,352 @@
+/*
+ * Copyright 2007 The Apache Software Foundation.
+ * 
+ * Licensed 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.sling.maven.assembly;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.maven.archiver.MavenArchiveConfiguration;
+import org.apache.maven.archiver.MavenArchiver;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.model.License;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.archiver.ArchiverException;
+import org.codehaus.plexus.archiver.jar.JarArchiver;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+
+/**
+ * The <code>AssemblyPlugin</code> TODO
+ *
+ * @goal assembly
+ * @phase package
+ * @requiresDependencyResolution compile
+ * @description build a Sling Assembly jar
+ */
+public class AssemblyPlugin extends AbstractMojo {
+
+    /**
+     * The name of the bundle manifest header providing the specification(s) of
+     * the bundle(s) to be installed along with this Assembly Bundle (value is
+     * "Assembly-Bundles").
+     */
+    public static final String ASSEMBLY_BUNDLES = "Assembly-Bundles";
+
+    /**
+     * The name of the bundle manifest header providing the source of the
+     * bundles to be installed (value is "Assembly-BundleRepository").
+     */
+    public static final String ASSEMBLY_BUNDLEREPOSITORY = "Assembly-BundleRepository";
+
+    /**
+     * The location in the Assembly Bundle of embedded bundles to install (value
+     * is "OSGI-INF/bundles/").
+     */
+    public static final String EMBEDDED_BUNDLE_LOCATION = "OSGI-INF/bundles/";
+
+    /**
+     * @parameter expression="${project.build.directory}"
+     * @required
+     * @readonly
+     */
+    private File outputDirectory;
+
+    /**
+     * Name of the generated JAR.
+     *
+     * @parameter expression="${project.build.finalName}"
+     * @required
+     */
+    private String finalName;
+
+    /**
+     * The Maven project.
+     *
+     * @parameter expression="${project}"
+     * @required
+     * @readonly
+     */
+    private MavenProject project;
+
+    /**
+     * The default start level for bundles not listed in the <code>startLevels</code>
+     * property. Default if missing or undefined is <code>30</code>. Valid values
+     * are integers in the range [1 .. Integer.MAX_VALUE].
+     *
+     * @parameter expression="${sling.assemblies.startlevel.default}"
+     */
+    private String defaultStartLevel;
+
+    /**
+     * Startlevel mappings for included artifacts. Indexed by
+     * groupId.artifactId, value is numeric startlevel [1 .. Integer.MAX_VALUE]
+     *
+     * @parameter
+     */
+    private Map startLevels = new HashMap();
+
+    /**
+     * Version mapping for included artifacts. Indexed
+     * by groupId.artifactId, value is a policy string, either "strict" (default)
+     * or "latest".
+     *
+     * @parameter
+     */
+    private Map versionPolicies = new HashMap();
+
+    /**
+     * An optional comma-separated list of URLs of OSGi Bundle Repositories -
+     * e.g. http://repohost.day.com/repository.xml - to use for the installation
+     * of the bundles.
+     *
+     * @parameter
+     */
+    private String repositories;
+
+    /**
+     * Whether the bundles are embedded in the created JAR file or not. Default
+     * is to not embed the bundles.
+     *
+     * @parameter expression="${sling.assemblies.embedded}"
+     */
+    private boolean embedded;
+
+    /**
+     * @parameter
+     */
+    private MavenArchiveConfiguration archive = new MavenArchiveConfiguration();
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.apache.maven.plugin.Mojo#execute()
+     */
+    public void execute() throws MojoExecutionException {
+        try {
+            String bsn = this.project.getGroupId() + "." + this.project.getArtifactId();
+            String version = this.project.getVersion();
+            Pattern P_VERSION = Pattern.compile("([0-9]+(\\.[0-9])*)-(.*)");
+            Matcher m = P_VERSION.matcher(version);
+            if (m.matches()) {
+                version = m.group(1) + "." + m.group(3);
+            }
+
+            this.getLog().info("Building Assembly " + bsn + " " + version);
+
+            File jarFile = new File(this.outputDirectory, this.finalName + ".jar");
+
+            // create the initial Manifest first
+            this.header(Constants.BUNDLE_MANIFESTVERSION, "2");
+            this.header(Constants.BUNDLE_SYMBOLICNAME, bsn);
+            this.header(Constants.BUNDLE_VERSION, version);
+            this.header(Constants.BUNDLE_DESCRIPTION, this.project.getDescription());
+            this.header("Bundle-License", this.printLicenses(this.project.getLicenses()));
+            this.header(Constants.BUNDLE_NAME, this.project.getName());
+
+            if (this.project.getOrganization() != null) {
+                this.header(Constants.BUNDLE_VENDOR,
+                    this.project.getOrganization().getName());
+                if (this.project.getOrganization().getUrl() != null) {
+                    this.header(Constants.BUNDLE_DOCURL,
+                        this.project.getOrganization().getUrl());
+                }
+            }
+
+            // next extract the bundle dependencies and create the Assembly
+            // headers
+            JarArchiver jar = new JarArchiver();
+            this.getBundles(jar);
+
+            // finally we are going to write this whole stuff
+            MavenArchiver archiver = new MavenArchiver();
+            archiver.setArchiver(jar);
+            archiver.setOutputFile(jarFile);
+
+            archiver.createArchive(this.project, this.archive);
+
+            // set the newly generated file as the primary artifact
+            this.project.getArtifact().setFile(jarFile);
+        } catch (MojoExecutionException e) {
+            throw e;
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new MojoExecutionException("Unknown error occurred", e);
+        }
+    }
+
+    private StringBuffer printLicenses(List licenses) {
+        if (licenses == null || licenses.size() == 0) return null;
+        StringBuffer sb = new StringBuffer();
+        String del = "";
+        for (Iterator i = licenses.iterator(); i.hasNext();) {
+            License l = (License) i.next();
+            String url = l.getUrl();
+            sb.append(del);
+            sb.append(url);
+            del = ", ";
+        }
+        return sb;
+    }
+
+    private void getBundles(JarArchiver jar) throws MojoExecutionException,
+            ArchiverException {
+        // set the assembly headers
+        if (this.repositories != null && this.repositories.length() > 0) {
+            this.getLog().debug("Adding Bundle Repositories [" + this.repositories + "]");
+            this.archive.addManifestEntry(ASSEMBLY_BUNDLEREPOSITORY, this.repositories);
+        }
+
+        // check default start level
+        if (this.defaultStartLevel == null || this.defaultStartLevel.length() == 0) {
+            this.defaultStartLevel = "30";
+        }
+
+        StringBuffer bundleList = new StringBuffer();
+
+        Map resolved = this.project.getArtifactMap();
+        Set artifacts = this.project.getDependencyArtifacts();
+        for (Iterator it = artifacts.iterator(); it.hasNext();) {
+            Artifact declared = (Artifact) it.next();
+            this.getLog().debug("Checking artifact " + declared);
+            if (Artifact.SCOPE_COMPILE.equals(declared.getScope())
+                    || Artifact.SCOPE_PROVIDED.equals(declared.getScope())
+                    || Artifact.SCOPE_RUNTIME.equals(declared.getScope())) {
+                this.getLog().debug("Resolving artifact " + declared);
+                Artifact artifact = (Artifact) resolved.get(ArtifactUtils.versionlessKey(declared));
+                if (artifact != null) {
+                    this.getLog().debug("Getting manifest from artifact " + artifact);
+                    Manifest m = this.getManifest(artifact);
+                    if (m != null
+                        && m.getMainAttributes().getValue(
+                            Constants.BUNDLE_SYMBOLICNAME) != null) {
+
+                        String name = m.getMainAttributes().getValue(
+                            Constants.BUNDLE_SYMBOLICNAME);
+                        String version = m.getMainAttributes().getValue(
+                            Constants.BUNDLE_VERSION);
+
+                        if (bundleList.length() > 0) bundleList.append(",");
+
+                        bundleList.append(name);
+                        if (version != null) {
+                            final Version v = new Version(version);
+                            final String nextVersion = v.getMajor() + "." + v.getMinor() + "." + (v.getMicro() + 1);
+                            bundleList.append(";version=\"");
+
+                            // ensure no SNAPSHOT in qualifier
+                            if (artifact.isSnapshot()) {
+                                version = v.getMajor() + "." + v.getMinor()
+                                    + "." + v.getMicro();
+                            } else {
+
+                                if (v.getQualifier() != null
+                                    && v.getQualifier().indexOf("SNAPSHOT") >= 0) {
+                                    version = v.getMajor() + "." + v.getMinor()
+                                        + "." + v.getMicro();
+                                }
+                            }
+                            // if the policy is strict, we exactly want the specified version
+                            final String policy = (String)this.versionPolicies.get(artifact.getGroupId() + "." + artifact.getArtifactId());
+                            if ( policy == null || policy.trim().length() == 0 || policy.trim().equalsIgnoreCase("strict") ) {
+                                bundleList.append("[").append(version).append(",").append(nextVersion).append(")");
+                            } else {
+                                bundleList.append(version);
+                            }
+
+                            bundleList.append('"');
+                        }
+
+                        String startLevel = (String) this.startLevels.get(artifact.getGroupId()
+                            + "." + artifact.getArtifactId());
+                        if (startLevel == null) {
+                            startLevel = this.defaultStartLevel;
+                        }
+                        if (startLevel != null) {
+                            bundleList.append(";startlevel=").append(startLevel);
+                        }
+
+                        if (this.embedded) {
+                            String path = EMBEDDED_BUNDLE_LOCATION
+                                + artifact.getGroupId() + "."
+                                + artifact.getArtifactId() + "-"
+                                + artifact.getVersion() + "."
+                                + artifact.getArtifactHandler().getExtension();
+                            jar.addFile(artifact.getFile(), path);
+                            bundleList.append(";entry=");
+                            bundleList.append('"').append(path).append('"');
+                            this.getLog().debug("Embedding Bundle Artifact " + artifact + " as [" + path + "]");
+                        } else {
+                            this.getLog().debug("Referring to Bundle Artifact " + artifact);
+                        }
+
+                        // TODO: get linked somehow ...
+                    } else {
+                        this.getLog().warn("Ignoring " + artifact + ": Missing Manifest");
+                    }
+                } else {
+                    this.getLog().warn("Ignoring " + declared + ": Not resolved");
+                }
+            } else {
+                this.getLog().warn("Ignoring " + declared + ": Wrong scope");
+            }
+        }
+
+        this.getLog().debug("Adding Bundles:" + bundleList);
+        this.archive.addManifestEntry(ASSEMBLY_BUNDLES, bundleList.toString());
+    }
+
+    private void header(String key, Object value) {
+        if (this.archive.getManifestEntries().containsKey(key) || value == null) {
+            return;
+        }
+
+        if (value instanceof Collection && ((Collection) value).isEmpty()) {
+            return;
+        }
+
+        this.archive.addManifestEntry(key, value.toString());
+    }
+
+    private Manifest getManifest(Artifact artifact) throws MojoExecutionException {
+        JarFile file = null;
+        try {
+            file = new JarFile(artifact.getFile());
+            return file.getManifest();
+        } catch (IOException ioe) {
+            throw new MojoExecutionException("Unable to read manifest from artifact " + artifact, ioe);
+        } finally {
+            if (file != null) {
+                try {
+                    file.close();
+                } catch (IOException ignore) {
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/maven/bundlesupport/BundleCopyMojo.java b/src/main/java/org/apache/sling/maven/bundlesupport/BundleCopyMojo.java
new file mode 100644
index 0000000..67b87fb
--- /dev/null
+++ b/src/main/java/org/apache/sling/maven/bundlesupport/BundleCopyMojo.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2007 The Apache Software Foundation.
+ * 
+ * Licensed 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.sling.maven.bundlesupport;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.plugin.AbstractMojo;
+
+/**
+ * Copies artifacts with scope <code>bundle</code> to the web archive at a
+ * configurable location - <code>WEB-INF/resources/bundles</code> by default.
+ * The main intent of this bundle is to include OSGi bundles with a Web
+ * Application for installation on first startup.
+ *
+ * @goal copy
+ * @phase process-resources
+ * @description Copy "provided" artifacts to the web bundle as a resource
+ * @requiresDependencyResolution bundle
+ */
+public class BundleCopyMojo extends AbstractMojo {
+
+    /**
+     * The directory to which the artifacts are copied.
+     *
+     * @parameter expression="${project.build.directory}/${project.build.finalName}/WEB-INF/resources/bundles"
+     * @required
+     */
+    private String bundleDestination;
+
+    /**
+     * Project dependencies of which the ones with scope <code>bundle</code>
+     * are selected to be included in the final artifact.
+     *
+     * @parameter expression="${project.artifacts}"
+     * @required
+     * @readonly
+     */
+    private Set dependencies;
+
+    /**
+     * Execute this Mojo
+     */
+    public void execute() {
+        File bundleDestFile = new File(this.bundleDestination);
+        bundleDestFile.mkdirs();
+
+        Iterator artifacts = this.dependencies.iterator();
+        while (artifacts.hasNext()) {
+            Artifact artifact = (Artifact) artifacts.next();
+            if (!"bundle".equals(artifact.getScope())) {
+                this.getLog().debug(
+                    "Ignoring non-bundle artifact " + artifact.getArtifactId());
+                continue;
+            }
+
+            // fix scope to not include the artifact in the final bundle
+            artifact.setScope(Artifact.SCOPE_PROVIDED);
+
+            // copy file
+            File source = artifact.getFile();
+            String destName = this.getArtifactFileName(artifact);
+            File dest = new File(bundleDestFile, destName);
+            try {
+                this.copyFile(source, dest);
+                this.getLog().info(
+                    "Copied Bundle " + source.getName() + " to " + dest);
+            } catch (IOException ioe) {
+                this.getLog().error(
+                    "Failed to copy Bundle " + source.getName() + " to " + dest,
+                    ioe);
+            }
+        }
+    }
+
+    private String getArtifactFileName(Artifact artifact) {
+        if (artifact.getClassifier() != null) {
+            return artifact.getArtifactId() + "-" + artifact.getVersion() + "-"
+                + artifact.getClassifier() + "." + artifact.getType();
+        }
+        return artifact.getArtifactId() + "-" + artifact.getVersion() + "."
+            + artifact.getType();
+    }
+
+    private void copyFile(File source, File dest) throws IOException {
+        FileInputStream ins = null;
+        FileOutputStream out = null;
+        try {
+            ins = new FileInputStream(source);
+            out = new FileOutputStream(dest);
+
+            byte[] buf = new byte[8192];
+            int rd = 0;
+            while ((rd = ins.read(buf)) >= 0) {
+                out.write(buf, 0, rd);
+            }
+        } finally {
+            if (ins != null) {
+                try {
+                    ins.close();
+                } catch (IOException ignore) {
+                }
+            }
+            if (out != null) {
+                try {
+                    out.close();
+                } catch (IOException ignore) {
+                }
+            }
+        }
+    }
+}
diff --git a/src/main/java/org/apache/sling/maven/bundlesupport/BundleDeployMojo.java b/src/main/java/org/apache/sling/maven/bundlesupport/BundleDeployMojo.java
new file mode 100644
index 0000000..2263b8b
--- /dev/null
+++ b/src/main/java/org/apache/sling/maven/bundlesupport/BundleDeployMojo.java
@@ -0,0 +1,264 @@
+/*
+ * Copyright 2007 The Apache Software Foundation.
+ * 
+ * Licensed 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.sling.maven.bundlesupport;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarInputStream;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+import java.util.zip.Deflater;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpStatus;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.multipart.FilePart;
+import org.apache.commons.httpclient.methods.multipart.FilePartSource;
+import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
+import org.apache.commons.httpclient.methods.multipart.Part;
+import org.apache.commons.httpclient.methods.multipart.StringPart;
+import org.apache.commons.io.IOUtils;
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.project.MavenProject;
+
+/**
+ * Deploy a JAR representing an OSGi Bundle.
+ *
+ * @goal deploy
+ * @phase deploy
+ * @description deploy an OSGi bundle jar to the Day OBR
+ */
+public class BundleDeployMojo extends AbstractMojo {
+
+	/**
+     * The directory for the generated JAR.
+     *
+     * @parameter expression="${project.build.directory}"
+     * @required
+     */
+    private String buildDirectory;
+
+    /**
+     * The name of the generated JAR file.
+     *
+     * @parameter alias="jarName" expression="${project.build.finalName}.jar"
+     * @required
+     */
+    private String jarName;
+
+    /**
+     * The URL of the OBR.
+     *
+     * @parameter expression="${obr}" default-value="http://obr.dev.day.com"
+     * @required
+     */
+    private String obr;
+
+    /**
+     * The Maven project.
+     *
+     * @parameter expression="${project}"
+     * @required
+     * @readonly
+     */
+    private MavenProject project;
+
+	/**
+	 * Execute this Mojo
+	 */
+	public void execute() throws MojoExecutionException {
+        // only upload if packaging as an osgi-bundle
+        File jarFile = new File(this.buildDirectory, this.jarName);
+        if (!this.isBundle(jarFile)) {
+            this.getLog().info(jarFile + " is not an OSGi Bundle, not uploading");
+            return;
+        }
+
+        // if this is a snapshot, replace "SNAPSHOT" with the date generated
+        // by the maven deploy plugin
+        if ( this.project.getVersion().indexOf("SNAPSHOT") > 0 ) {
+            // create new version string by replacing all '-' with '.'
+            String newVersion = this.project.getArtifact().getVersion();
+            int firstPos = newVersion.indexOf('-') + 1;
+            int pos = 0;
+            while (pos != -1) {
+                pos = newVersion.indexOf('-');
+                if ( pos != -1 ) {
+                    newVersion = newVersion.substring(0, pos ) + '.' + newVersion.substring(pos+1);
+                }
+            }
+            // now remove all dots after the third one
+            pos = newVersion.indexOf('.', firstPos);
+            while ( pos != -1 ) {
+                newVersion = newVersion.substring(0, pos) + newVersion.substring(pos+1);
+                pos = newVersion.indexOf('.', pos+1);
+            }
+            jarFile = this.changeVersion(jarFile, newVersion);
+        } else {
+            // if this is a final release append "final"
+            try {
+                final ArtifactVersion v = this.project.getArtifact().getSelectedVersion();
+                if ( v.getBuildNumber() == 0 && v.getQualifier() == null ) {
+                    final String newVersion = this.project.getArtifact().getVersion() + ".FINAL";
+                    jarFile = this.changeVersion(jarFile, newVersion);
+                }
+            } catch (OverConstrainedVersionException ocve) {
+                // we ignore this and don't append "final"!
+            }
+        }
+        this.post(this.obr, jarFile);
+	}
+
+	private void post(String targetURL, File file) {
+        this.getLog().info("Uploading " + file + " to " + targetURL);
+
+        PostMethod filePost = new PostMethod(targetURL);
+
+        try {
+            Part[] parts = { new FilePart(file.getName(), new FilePartSource(file.getName(), file)),
+                new StringPart("_noredir_", "_noredir_") };
+            filePost.setRequestEntity(new MultipartRequestEntity(parts,
+                filePost.getParams()));
+            HttpClient client = new HttpClient();
+            client.getHttpConnectionManager().getParams().setConnectionTimeout(
+                5000);
+            int status = client.executeMethod(filePost);
+            if (status == HttpStatus.SC_OK) {
+                InputStream res = filePost.getResponseBodyAsStream();
+                String response = "";
+                if (res != null) {
+                    response = IOUtils.toString(res,
+                        filePost.getResponseCharSet());
+                }
+                this.getLog().info("Upload complete: " + response);
+            } else {
+                this.getLog().error(
+                    "Upload failed, cause: " + HttpStatus.getStatusText(status));
+            }
+        } catch (Exception ex) {
+            this.getLog().error(ex.getClass().getName() + " " + ex.getMessage());
+            ex.printStackTrace();
+        } finally {
+            filePost.releaseConnection();
+        }
+    }
+
+    private boolean isBundle(File jarFile) {
+        if (!jarFile.exists()) {
+            this.getLog().debug("isBundle: " + jarFile + " does not exist");
+            return false;
+        }
+
+        JarFile jaf = null;
+        try {
+            jaf = new JarFile(jarFile);
+            Manifest manif = jaf.getManifest();
+            if (manif == null) {
+                this.getLog().debug("isBundle: Missing manifest in " + jarFile);
+                return false;
+            }
+
+            String symbName =
+                manif.getMainAttributes().getValue("Bundle-SymbolicName");
+            if (symbName == null) {
+                this.getLog().debug("isBundle: No Bundle-SymbolicName in " + jarFile);
+                return false;
+            }
+
+            this.getLog().info("isBundle: " + jarFile + " contains Bundle " + symbName);
+            return true;
+        } catch (IOException ioe) {
+            // TODO
+        } finally {
+            if (jaf != null) {
+                try {
+                    jaf.close();
+                } catch (IOException ignore) {
+                    // don't care
+                }
+            }
+        }
+
+        // fall back to not being a bundle
+        return false;
+    }
+
+    /**
+     * Change the version in jar
+     * @param newVersion
+     * @param file
+     * @return
+     * @throws MojoExecutionException
+     */
+    protected File changeVersion(File file, String newVersion)
+    throws MojoExecutionException {
+        String fileName = file.getName();
+        int pos = fileName.indexOf(this.project.getVersion());
+        fileName = fileName.substring(0, pos) + newVersion + fileName.substring(pos + this.project.getVersion().length());
+
+        JarInputStream jis = null;
+        JarOutputStream jos;
+        OutputStream out = null;
+        try {
+            // now create a temporary file and update the version
+            final JarFile sourceJar = new JarFile(file);
+            final Manifest manifest = sourceJar.getManifest();
+            manifest.getMainAttributes().putValue("Bundle-Version", newVersion);
+
+            jis = new JarInputStream(new FileInputStream(file));
+            final File destJar = new File(file.getParentFile(), fileName);
+            out = new FileOutputStream(destJar);
+            jos = new JarOutputStream(out, manifest);
+
+            jos.setMethod(JarOutputStream.DEFLATED);
+            jos.setLevel(Deflater.BEST_COMPRESSION);
+
+            JarEntry entryIn = jis.getNextJarEntry();
+            while (entryIn != null) {
+                JarEntry entryOut = new JarEntry(entryIn.getName());
+                entryOut.setTime(entryIn.getTime());
+                entryOut.setComment(entryIn.getComment());
+                jos.putNextEntry(entryOut);
+                if (!entryIn.isDirectory()) {
+                    IOUtils.copy(jis, jos);
+                }
+                jos.closeEntry();
+                jis.closeEntry();
+                entryIn = jis.getNextJarEntry();
+            }
+
+            // close the JAR file now to force writing
+            jos.close();
+            return destJar;
+        } catch (IOException ioe) {
+            throw new MojoExecutionException("Unable to update version in jar file.", ioe);
+        } finally {
+            IOUtils.closeQuietly(jis);
+            IOUtils.closeQuietly(out);
+        }
+
+
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/maven/bundlesupport/BundleListMojo.java b/src/main/java/org/apache/sling/maven/bundlesupport/BundleListMojo.java
new file mode 100644
index 0000000..5e90853
--- /dev/null
+++ b/src/main/java/org/apache/sling/maven/bundlesupport/BundleListMojo.java
@@ -0,0 +1,305 @@
+/*
+ * Copyright 2007 The Apache Software Foundation.
+ * 
+ * Licensed 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.sling.maven.bundlesupport;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+
+/**
+ * Lists artifacts scoped as "bundleinstall" in a properties file at a
+ * configurable location - WEB-INF/autoinstall.properties by default. The
+ * properties file contains three entries for each bundle thus added: The bundle
+ * symbolic name, the bundle version and the start level to assign the bundle
+ * after installation.
+ * <p>
+ * Bundles are listed in the file sorted by bundle startlevel, symblic name and
+ * version. Bundle start levels may be declared using the
+ * <code>defaultStartLevel</code> and <code>startLevels</code> properties.
+ *
+ * @goal list
+ * @phase process-resources
+ * @description List bundles to be installed/updated from an OBR on startup
+ * @requiresDependencyResolution bundleinstall
+ */
+public class BundleListMojo extends AbstractMojo {
+
+    /**
+     * The prefix to the properties defining the bundle to be installed. This
+     * property cannot be modified.
+     *
+     * @parameter expression="install."
+     * @required
+     * @readonly
+     */
+    private String prefix;
+
+    /**
+     * The file in which the bundle name and versions are listed.
+     *
+     * @parameter expression="${project.build.directory}/${project.build.finalName}/WEB-INF/autoinstall/${project.groupId}.${project.artifactId}.properties"
+     * @required
+     */
+    private String bundleInstallProperties;
+
+    /**
+     * The default start level for installed bundles. May be overwritten by
+     * specific per-artifact settings
+     *
+     * @parameter expression="10"
+     * @required
+     */
+    private String defaultStartLevel;
+
+    /**
+     * Specific startlevels for artifacts. Indexed by the artifact's groupId
+     * plus artifactId, value is the specific startlevel.
+     * <p>
+     * Sample configuration:
+     *
+     * <pre>
+     *      &lt;startLevels&gt;
+     *            &lt;groupId.artifactId&gt;30&lt;/groupId.artifactId&gt;
+     *            &lt;org.apache.osgi.day-osgi-webmanager&gt;5&lt;/org.apache.osgi.day-osgi-webmanager&gt;
+     *      &lt;/startLevels&gt;
+     * </pre>
+     *
+     * @parameter
+     */
+    private Map startLevels = new HashMap();
+
+    /**
+     * Dependencies which are installed
+     *
+     * @parameter expression="${project.artifacts}"
+     * @readonly
+     */
+    private Set dependencies;
+
+    /**
+     * Execute this Mojo
+     *
+     * @throws MojoExecutionException
+     */
+    public void execute() {
+
+        SortedMap byStartLevel = new TreeMap();
+        Iterator artifacts = this.dependencies.iterator();
+        while (artifacts.hasNext()) {
+            Artifact artifact = (Artifact) artifacts.next();
+            String artifactScope = artifact.getScope();
+            if (artifactScope == null
+                || !artifactScope.startsWith("bundleinstall")) {
+                this.getLog().debug(
+                    "Ignoring non-bundle artifact " + artifact.getArtifactId());
+                continue;
+            }
+
+            // fix scope to not include the artifact in the final bundle
+            artifact.setScope(Artifact.SCOPE_PROVIDED);
+
+            // copy file
+            BundleSpec bs = this.getBundleSpec(artifact, artifactScope);
+            if (bs != null) {
+                Integer sl = new Integer(bs.startLevel);
+                SortedSet slSet = (SortedSet) byStartLevel.get(sl);
+                if (slSet == null) {
+                    slSet = new TreeSet();
+                    byStartLevel.put(sl, slSet);
+                }
+                slSet.add(bs);
+                this.getLog().debug(
+                    "Added Bundle " + bs.symbolicName + "/" + bs.version);
+            }
+        }
+
+        // do not write anynothing if there is nothing to write !
+        if (byStartLevel.isEmpty()) {
+            this.getLog().info("No Bundles added this time, nothing more to do");
+            return;
+        }
+
+        // convert map of sets into properties
+        int id = 0;
+        Properties props = new Properties();
+        for (Iterator mi = byStartLevel.values().iterator(); mi.hasNext();) {
+            SortedSet slSet = (SortedSet) mi.next();
+            for (Iterator bi = slSet.iterator(); bi.hasNext();) {
+                BundleSpec bs = (BundleSpec) bi.next();
+                props.setProperty(this.prefix + id + ".symbolic-name",
+                    bs.symbolicName);
+                props.setProperty(this.prefix + id + ".version", bs.version);
+                props.setProperty(this.prefix + id + ".startlevel", String.valueOf(bs.startLevel));
+                id++;
+
+                this.getLog().debug(id + "  ==>  " + bs.symbolicName);
+            }
+        }
+
+        // write the properties file
+        File bundleInstallPropertiesFile = new File(this.bundleInstallProperties);
+        bundleInstallPropertiesFile.getParentFile().mkdirs();
+        OutputStream out = null;
+        try {
+            out = new FileOutputStream(bundleInstallPropertiesFile);
+            props.store(
+                out,
+                "Bundles to install from OBR on startup, automatically generated, do not modify");
+        } catch (IOException ioe) {
+            this.getLog().error(
+                "Cannot store auto install properties "
+                    + bundleInstallPropertiesFile, ioe);
+        } finally {
+            if (out != null) {
+                try {
+                    out.close();
+                } catch (IOException ignore) {
+                    // ignore
+                }
+            }
+        }
+    }
+
+    private BundleSpec getBundleSpec(Artifact artifact, String declaredScope) {
+        File bundleFile = artifact.getFile();
+        if (!bundleFile.exists()) {
+            this.getLog().debug(
+                "setBundleProperties: " + bundleFile + " does not exist");
+            return null;
+        }
+
+        JarFile jaf = null;
+        try {
+            jaf = new JarFile(bundleFile);
+            Manifest manif = jaf.getManifest();
+            if (manif == null) {
+                this.getLog().debug(
+                    "setBundleProperties: Missing manifest in " + bundleFile);
+                return null;
+            }
+
+            String symbName = manif.getMainAttributes().getValue(
+                "Bundle-SymbolicName");
+            if (symbName == null) {
+                this.getLog().debug(
+                    "setBundleProperties: No Bundle-SymbolicName in "
+                        + bundleFile);
+                return null;
+            }
+            this.getLog().debug(
+                "setBundleProperties: " + bundleFile + " contains Bundle "
+                    + symbName);
+
+            String version = manif.getMainAttributes().getValue(
+                "Bundle-Version");
+            if (version == null) {
+                // default version if missing
+                version = "0.0.0";
+            } else if (version.endsWith(".SNAPSHOT")) {
+                // cutoff .SNAPSHOT qualifier
+                version = version.substring(0, version.length()
+                    - ".SNAPSHOT".length());
+            }
+
+            BundleSpec bs = new BundleSpec();
+            bs.symbolicName = symbName;
+            bs.version = version;
+            bs.startLevel = this.getStartLevel(artifact);
+            return bs;
+        } catch (IOException ioe) {
+            this.getLog().warn(
+                "setBundleProperties: Problem list bundle " + bundleFile, ioe);
+        } finally {
+            if (jaf != null) {
+                try {
+                    jaf.close();
+                } catch (IOException ignore) {
+                    // don't care
+                }
+            }
+        }
+
+        // fall back to not being a bundle
+        return null;
+    }
+
+    private int getStartLevel(Artifact artifact) {
+        String startLevel = null;
+        if (this.startLevels != null) {
+            String id = artifact.getGroupId() + "." + artifact.getArtifactId();
+            startLevel = (String) this.startLevels.get(id);
+        }
+
+        // fallback to default start level if none explicitly set
+        if (startLevel == null) {
+            startLevel = this.defaultStartLevel;
+        }
+
+        // convert to int - fall back to -1 if wrong type
+        try {
+            return Integer.parseInt(startLevel);
+        } catch (NumberFormatException nfe) {
+            return -1;
+        }
+    }
+
+    private static class BundleSpec implements Comparable {
+        String symbolicName;
+
+        String version;
+
+        int startLevel;
+
+        public int compareTo(Object obj) {
+            BundleSpec other = (BundleSpec) obj;
+
+            // order by start level
+            if (this.startLevel < other.startLevel) {
+                return -1;
+            } else if (this.startLevel > other.startLevel) {
+                return 1;
+            }
+
+            // order by symbolic version if symbolic names are equal
+            if (this.symbolicName.equals(other.symbolicName)) {
+                if (this.version.equals(other.version)) {
+                    return 0;
+                }
+
+                return this.version.compareTo(other.version);
+            }
+
+            // order by symbolic name
+            return this.symbolicName.compareTo(other.symbolicName);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/maven/war/WarMojo.java b/src/main/java/org/apache/sling/maven/war/WarMojo.java
new file mode 100644
index 0000000..a564a8e
--- /dev/null
+++ b/src/main/java/org/apache/sling/maven/war/WarMojo.java
@@ -0,0 +1,276 @@
+/*
+ * Copyright 2007 The Apache Software Foundation.
+ * 
+ * Licensed 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.sling.maven.war;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.artifact.versioning.ArtifactVersion;
+import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.project.MavenProject;
+import org.osgi.framework.Constants;
+
+/**
+ * This bundle generates the WEB-INF/sling_install.properties containing
+ * the referenced assemblies.
+ *
+ * @goal install-properties
+ * @phase process-resources
+ * @requiresDependencyResolution compile
+ * @description build the sling_install.properties
+ *
+ */
+public class WarMojo extends org.apache.maven.plugin.AbstractMojo {
+
+    /**
+     * @parameter expression="${project.build.directory}"
+     * @required
+     * @readonly
+     */
+    private File outputDirectory;
+
+    /**
+     * Name of the generated JAR.
+     *
+     * @parameter expression="${project.build.finalName}"
+     * @required
+     */
+    private String finalName;
+
+    /**
+     * The Maven project.
+     *
+     * @parameter expression="${project}"
+     * @required
+     * @readonly
+     */
+    private MavenProject project;
+
+    /**
+     * The default start level for bundles not listed in the <code>startLevels</code>
+     * property. Default if missing or undefined is <code>30</code>. Valid values
+     * are integers in the range [1 .. Integer.MAX_VALUE].
+     *
+     * @parameter expression="${sling.assemblies.startlevel.default}"
+     */
+    private String defaultStartLevel;
+
+    /**
+     * Startlevel mappings for included artifacts. Indexed by
+     * groupId.artifactId, value is numeric startlevel [1 .. Integer.MAX_VALUE]
+     *
+     * @parameter
+     */
+    private Map startLevels = new HashMap();
+
+    /**
+     * Version mapping for included artifacts. Indexed
+     * by groupId.artifactId, value is a policy string, either "strict" (default)
+     * or "latest".
+     *
+     * @parameter
+     */
+    private Map versionPolicies = new HashMap();
+
+    /**
+     * @see org.apache.maven.plugin.AbstractMojo#execute()
+     */
+    public void execute() throws MojoExecutionException, MojoFailureException {
+        this.getLog().debug("Executing sling war mojo");
+        // check default start level
+        if (this.defaultStartLevel == null || this.defaultStartLevel.length() == 0) {
+            this.defaultStartLevel = "30";
+        }
+
+        final List assemblies = new ArrayList();
+
+        final Map resolved = this.project.getArtifactMap();
+        final Set artifacts = this.project.getDependencyArtifacts();
+        final Iterator it = artifacts.iterator();
+        while ( it.hasNext() ) {
+            final Artifact declared = (Artifact) it.next();
+            this.getLog().debug("Checking artifact " + declared);
+            if (Artifact.SCOPE_COMPILE.equals(declared.getScope())
+                || Artifact.SCOPE_PROVIDED.equals(declared.getScope())
+                || Artifact.SCOPE_RUNTIME.equals(declared.getScope())) {
+                this.getLog().debug("Resolving artifact " + declared);
+                Artifact artifact = (Artifact) resolved.get(ArtifactUtils.versionlessKey(declared));
+                if (artifact != null) {
+                    this.getLog().debug("Getting manifest from artifact " + artifact);
+                    try {
+                        Manifest m = this.getManifest(artifact);
+                        if (m != null ) {
+                            final String category = m.getMainAttributes().getValue(Constants.BUNDLE_CATEGORY);
+                            this.getLog().debug("Category of artifact " + artifact + " is " + category);
+                            if ( category != null && category.equals("assembly") ) {
+                                final String name = m.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME);
+                                this.getLog().debug("Found assembly: " + artifact.getArtifactId() + " with name " + name);
+                                final String identifier = artifact.getGroupId() + "." + artifact.getArtifactId();
+                                final String startLevel = (String) this.startLevels.get(identifier);
+                                final String policy = (String) this.versionPolicies.get(identifier);
+                                assemblies.add(new AssemblyInfo(name, declared, (startLevel != null ? startLevel : this.defaultStartLevel), policy));
+                            }
+                        } else {
+                            this.getLog().debug("Unable to get manifest from artifact " + artifact);
+                        }
+                    } catch (IOException ioe) {
+                        throw new MojoExecutionException("Unable to get manifest from artifact " + artifact, ioe);
+                    }
+                } else {
+                    this.getLog().debug("Unable to resolve artifact " + declared);
+                }
+            } else {
+                this.getLog().debug("Artifact " + declared + " has not scope compile, provided or runtime, but: " + declared.getScope());
+            }
+        }
+        final File f = new File(this.outputDirectory, this.finalName + File.separator + "WEB-INF" + File.separator + "sling_install.properties");
+        if ( assemblies.size() > 0 ) {
+            // create the directory if necessary
+            f.getParentFile().mkdirs();
+            // let's sort the assemblies based on the start level
+            Collections.sort(assemblies, new AssemblyInfoComparator());
+            String previousLevel = null;
+            FileWriter fw = null;
+            try {
+                fw = new FileWriter(f);
+                fw.write("# Generated installation properties for assemblies\n");
+                final Iterator i = assemblies.iterator();
+                while ( i.hasNext() ) {
+                    final AssemblyInfo info = (AssemblyInfo)i.next();
+                    // first entry or new level?
+                    if ( previousLevel == null || !previousLevel.equals(info.level) ) {
+                        if ( previousLevel != null ) {
+                            fw.write('\n');
+                        }
+                        fw.write("sling.install.");
+                        fw.write(info.level);
+                        fw.write(" = ");
+                    } else {
+                        // append entry
+                        fw.write(',');
+                    }
+                    fw.write(info.name);
+                    fw.write(':');
+                    fw.write(info.version);
+                    previousLevel = info.level;
+                }
+                if ( previousLevel != null ) {
+                    fw.write('\n');
+                }
+            } catch (IOException e) {
+                throw new MojoExecutionException("Unable to generate " + f, e);
+            } finally {
+                if ( fw != null ) {
+                    try {
+                        fw.close();
+                    } catch (IOException ignore) {
+                        // ignore this
+                    }
+                }
+            }
+        } else {
+            // if we don't reference any assembly delete a possible
+            // properties file from an earlier build
+            if ( f.exists() ) {
+                f.delete();
+            }
+        }
+    }
+
+    protected Manifest getManifest(Artifact artifact) throws IOException {
+        JarFile file = null;
+        try {
+            file = new JarFile(artifact.getFile());
+            return file.getManifest();
+        } finally {
+            if (file != null) {
+                try {
+                    file.close();
+                } catch (IOException ignore) {
+                }
+            }
+        }
+    }
+
+    protected static final class AssemblyInfoComparator implements Comparator {
+
+        public int compare(Object arg0, Object arg1) {
+            // we know that we sort just assembly infos, so no need to check this!
+            final AssemblyInfo info1 = (AssemblyInfo)arg0;
+            final AssemblyInfo info2 = (AssemblyInfo)arg1;
+            return info1.level.compareTo(info2.level);
+        }
+
+    }
+
+    protected static final class AssemblyInfo {
+
+        public final String name;
+        public final String version;
+        public final String level;
+
+        public AssemblyInfo(String n, Artifact artifact, String l, String policy) {
+            this.name = n;
+            ArtifactVersion av;
+            String v = null;
+            String nextVersion = null;
+            try {
+                av = artifact.getSelectedVersion();
+                final StringBuffer buffer = new StringBuffer();
+                buffer.append(av.getMajorVersion());
+                buffer.append('.');
+                buffer.append(av.getMinorVersion());
+                buffer.append('.');
+                nextVersion = buffer.toString() + (av.getIncrementalVersion() + 1);
+                buffer.append(av.getIncrementalVersion());
+                // we don't append build number and qualifier to always get the latest version
+
+                //if ( av.getBuildNumber() != 0 ) {
+                //    buffer.append('.');
+                //    buffer.append(av.getBuildNumber());
+                //}
+                //if ( av.getQualifier() != null ) {
+                //    buffer.append('.');
+                //    buffer.append(av.getQualifier());
+                //}
+                v = buffer.toString();
+            } catch (OverConstrainedVersionException e) {
+                v = artifact.getVersion();
+            }
+            if ( policy == null || policy.trim().length() == 0 || policy.trim().equalsIgnoreCase("strict") && nextVersion != null ) {
+                this.version = "\"[" + v + "," + nextVersion + ")\"";
+            } else {
+                this.version = v;
+            }
+            this.level = l;
+        }
+    }
+}
diff --git a/src/main/resources/META-INF/LICENSE b/src/main/resources/META-INF/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/src/main/resources/META-INF/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/src/main/resources/META-INF/NOTICE b/src/main/resources/META-INF/NOTICE
new file mode 100644
index 0000000..4894d83
--- /dev/null
+++ b/src/main/resources/META-INF/NOTICE
@@ -0,0 +1,8 @@
+Apache Sling
+Copyright 2007 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+Based on source code originally developed by
+Day Software (http://www.day.com/).
diff --git a/src/main/resources/META-INF/plexus/components.xml b/src/main/resources/META-INF/plexus/components.xml
new file mode 100644
index 0000000..92b3a52
--- /dev/null
+++ b/src/main/resources/META-INF/plexus/components.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+    Copyright 2007 The Apache Software Foundation.
+    
+    Licensed 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.
+-->
+<component-set>
+  <components>
+    <component>
+      <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
+      <role-hint>assembly</role-hint>
+      <implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
+      <configuration>
+        <lifecycles>
+          <lifecycle>
+            <id>default</id>
+            <!-- START SNIPPET: bundle-lifecycle -->
+            <phases>
+              <process-resources>org.apache.maven.plugins:maven-resources-plugin:resources</process-resources>
+              <compile>org.apache.maven.plugins:maven-compiler-plugin:compile</compile>
+              <process-test-resources>org.apache.maven.plugins:maven-resources-plugin:testResources</process-test-resources>
+              <test-compile>org.apache.maven.plugins:maven-compiler-plugin:testCompile</test-compile>
+              <test>org.apache.maven.plugins:maven-surefire-plugin:test</test>
+              <package>org.apache.sling:maven-sling-plugin:assembly</package>
+              <install>org.apache.maven.plugins:maven-install-plugin:install</install>
+              <deploy>org.apache.maven.plugins:maven-deploy-plugin:deploy</deploy>
+            </phases>
+            <!-- END SNIPPET: bundle-lifecycle -->
+          </lifecycle>
+        </lifecycles>
+      </configuration>
+    </component>
+    <component>
+      <role>org.apache.maven.artifact.handler.ArtifactHandler</role>
+      <role-hint>assembly</role-hint>
+      <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
+      <configuration>
+        <type>assembly</type>
+        <includesDependencies>true</includesDependencies>
+        <language>java</language>
+        <extension>jar</extension>
+        <addedToClasspath>true</addedToClasspath>
+      </configuration>
+    </component>
+  </components>
+</component-set>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.