git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@239335 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/sandbox/tbennett/maven-archiver/pom.xml b/sandbox/tbennett/maven-archiver/pom.xml
new file mode 100644
index 0000000..300d915
--- /dev/null
+++ b/sandbox/tbennett/maven-archiver/pom.xml
@@ -0,0 +1,29 @@
+<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>
+ <artifactId>maven</artifactId>
+ <groupId>org.apache.maven</groupId>
+ <version>2.0-alpha-3</version>
+ </parent>
+ <artifactId>maven-archiver</artifactId>
+ <name>Maven Archiver</name>
+ <version>2.0-alpha-3</version>
+ <dependencies>
+ <dependency>
+ <groupId>plexus</groupId>
+ <artifactId>plexus-archiver</artifactId>
+ <version>1.0-alpha-1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-artifact</artifactId>
+ <version>2.0-alpha-3</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-project</artifactId>
+ <version>2.0-alpha-3</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/sandbox/tbennett/maven-archiver/src/main/java/org/apache/maven/archiver/ManifestConfiguration.java b/sandbox/tbennett/maven-archiver/src/main/java/org/apache/maven/archiver/ManifestConfiguration.java
new file mode 100644
index 0000000..7ff960c
--- /dev/null
+++ b/sandbox/tbennett/maven-archiver/src/main/java/org/apache/maven/archiver/ManifestConfiguration.java
@@ -0,0 +1,78 @@
+package org.apache.maven.archiver;
+
+/*
+ * Copyright 2001-2005 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.
+ */
+
+/**
+ * Capture common manifest configuration.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ * @version $Id: ManifestConfiguration.java 209060 2005-07-04 11:59:42Z evenisse $
+ * @todo is this general enough to be in Plexus Archiver?
+ */
+public class ManifestConfiguration
+{
+ private String mainClass;
+
+ private String packageName;
+
+ /**
+ * @todo boolean instead
+ */
+ private String addClasspath;
+
+ /**
+ * @todo boolean instead
+ */
+ private String addExtensions;
+
+ /**
+ * This gets prefixed to all classpath entries.
+ */
+ private String classpathPrefix = "";
+
+ public String getMainClass()
+ {
+ return mainClass;
+ }
+
+ public boolean isAddClasspath()
+ {
+ return addClasspath != null ? Boolean.valueOf( addClasspath ).booleanValue() : false;
+ }
+
+ public boolean isAddExtensions()
+ {
+ return addExtensions != null ? Boolean.valueOf( addExtensions ).booleanValue() : false;
+ }
+
+ public String getPackageName()
+ {
+ return packageName;
+ }
+
+ public String getClasspathPrefix()
+ {
+ String cpp = classpathPrefix.replaceAll( "\\\\", "/" );
+
+ if ( cpp.length() != 0 && !cpp.endsWith("/") )
+ {
+ cpp += "/";
+ }
+
+ return cpp;
+ }
+}
diff --git a/sandbox/tbennett/maven-archiver/src/main/java/org/apache/maven/archiver/MavenArchiveConfiguration.java b/sandbox/tbennett/maven-archiver/src/main/java/org/apache/maven/archiver/MavenArchiveConfiguration.java
new file mode 100644
index 0000000..ec14472
--- /dev/null
+++ b/sandbox/tbennett/maven-archiver/src/main/java/org/apache/maven/archiver/MavenArchiveConfiguration.java
@@ -0,0 +1,101 @@
+package org.apache.maven.archiver;
+
+/*
+ * Copyright 2001-2005 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.
+ */
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Capture common archive configuration.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ * @version $Id: MavenArchiveConfiguration.java 225504 2005-07-27 12:48:52Z brett $
+ * @todo is this general enough to be in Plexus Archiver?
+ */
+public class MavenArchiveConfiguration
+{
+ private boolean compress = true;
+
+ private boolean index;
+
+ private File manifestFile;
+
+ private ManifestConfiguration manifest;
+
+ private Map manifestEntries = new HashMap();
+
+ public boolean isCompress()
+ {
+ return compress;
+ }
+
+ public boolean isIndex()
+ {
+ return index;
+ }
+
+ public File getManifestFile()
+ {
+ return manifestFile;
+ }
+
+ public ManifestConfiguration getManifest()
+ {
+ if ( manifest == null )
+ {
+ manifest = new ManifestConfiguration();
+ }
+ return manifest;
+ }
+
+ public void setCompress( boolean compress )
+ {
+ this.compress = compress;
+ }
+
+ public void setIndex( boolean index )
+ {
+ this.index = index;
+ }
+
+ public void setManifestFile( File manifestFile )
+ {
+ this.manifestFile = manifestFile;
+ }
+
+ public void setManifest( ManifestConfiguration manifest )
+ {
+ this.manifest = manifest;
+ }
+
+ public void addManifestEntry(Object key, Object value) {
+ manifestEntries.put(key, value);
+ }
+
+ public void addManifestEntries(Map map) {
+ manifestEntries.putAll(map);
+ }
+
+ public boolean isManifestEntriesEmpty() {
+ return manifestEntries.isEmpty();
+ }
+
+ public Map getManifestEntries() {
+ return manifestEntries;
+ }
+}
diff --git a/sandbox/tbennett/maven-archiver/src/main/java/org/apache/maven/archiver/MavenArchiver.java b/sandbox/tbennett/maven-archiver/src/main/java/org/apache/maven/archiver/MavenArchiver.java
new file mode 100644
index 0000000..16192e3
--- /dev/null
+++ b/sandbox/tbennett/maven-archiver/src/main/java/org/apache/maven/archiver/MavenArchiver.java
@@ -0,0 +1,317 @@
+package org.apache.maven.archiver;
+
+/*
+ * Copyright 2001-2005 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.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.DependencyResolutionRequiredException;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.archiver.ArchiverException;
+import org.codehaus.plexus.archiver.jar.JarArchiver;
+import org.codehaus.plexus.archiver.jar.Manifest;
+import org.codehaus.plexus.archiver.jar.ManifestException;
+import org.codehaus.plexus.util.IOUtil;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+/**
+ * @author <a href="evenisse@apache.org">Emmanuel Venisse</a>
+ * @version $Revision: 225504 $ $Date: 2005-07-27 07:48:52 -0500 (Wed, 27 Jul 2005) $
+ */
+public class MavenArchiver
+{
+ private JarArchiver archiver = new JarArchiver();
+
+ private File archiveFile;
+
+ /**
+ * Return a pre-configured manifest
+ *
+ * @todo Add user attributes list and user groups list
+ */
+ public Manifest getManifest( MavenProject project, ManifestConfiguration config )
+ throws ManifestException, DependencyResolutionRequiredException
+ {
+ // Added basic entries
+ Manifest m = new Manifest();
+ Manifest.Attribute buildAttr = new Manifest.Attribute( "Built-By", System.getProperty( "user.name" ) );
+ m.addConfiguredAttribute( buildAttr );
+ Manifest.Attribute createdAttr = new Manifest.Attribute( "Created-By", "Apache Maven" );
+ m.addConfiguredAttribute( createdAttr );
+
+ if ( config.getPackageName() != null )
+ {
+ Manifest.Attribute packageAttr = new Manifest.Attribute( "Package", config.getPackageName() );
+ m.addConfiguredAttribute( packageAttr );
+ }
+
+ Manifest.Attribute buildJdkAttr = new Manifest.Attribute( "Build-Jdk", System.getProperty( "java.version" ) );
+ m.addConfiguredAttribute( buildJdkAttr );
+
+ if ( config.isAddClasspath() )
+ {
+ StringBuffer classpath = new StringBuffer();
+ List artifacts = project.getRuntimeClasspathElements();
+ String classpathPrefix = config.getClasspathPrefix();
+
+ for ( Iterator iter = artifacts.iterator(); iter.hasNext(); )
+ {
+ File f = new File( (String) iter.next() );
+ if ( f.isFile() )
+ {
+ if ( classpath.length() > 0 )
+ {
+ classpath.append( " " );
+ }
+
+ classpath.append( classpathPrefix );
+ classpath.append( f.getName() );
+ }
+ }
+
+ if ( classpath.length() > 0 )
+ {
+ Manifest.Attribute classpathAttr = new Manifest.Attribute( "Class-Path", classpath.toString() );
+ m.addConfiguredAttribute( classpathAttr );
+ }
+ }
+
+ // Added supplementary entries
+ Manifest.Attribute extensionNameAttr = new Manifest.Attribute( "Extension-Name", project.getArtifactId() );
+ m.addConfiguredAttribute( extensionNameAttr );
+
+ if ( project.getDescription() != null )
+ {
+ Manifest.Attribute specificationTitleAttr = new Manifest.Attribute( "Specification-Title",
+ project.getDescription() );
+ m.addConfiguredAttribute( specificationTitleAttr );
+ }
+
+ if ( project.getOrganization() != null )
+ {
+ Manifest.Attribute specificationVendor = new Manifest.Attribute( "Specification-Vendor",
+ project.getOrganization().getName() );
+ m.addConfiguredAttribute( specificationVendor );
+ Manifest.Attribute implementationVendorAttr = new Manifest.Attribute( "Implementation-Vendor",
+ project.getOrganization().getName() );
+ m.addConfiguredAttribute( implementationVendorAttr );
+ }
+
+ Manifest.Attribute implementationTitleAttr = new Manifest.Attribute( "Implementation-Title",
+ project.getArtifactId() );
+ m.addConfiguredAttribute( implementationTitleAttr );
+ Manifest.Attribute implementationVersionAttr = new Manifest.Attribute( "Implementation-Version",
+ project.getVersion() );
+ m.addConfiguredAttribute( implementationVersionAttr );
+
+ String mainClass = config.getMainClass();
+ if ( mainClass != null && !"".equals( mainClass ) )
+ {
+ Manifest.Attribute mainClassAttr = new Manifest.Attribute( "Main-Class", mainClass );
+ m.addConfiguredAttribute( mainClassAttr );
+ }
+
+ // Added extensions
+ if ( config.isAddExtensions() )
+ {
+ StringBuffer extensionsList = new StringBuffer();
+ Set artifacts = project.getArtifacts();
+
+ for ( Iterator iter = artifacts.iterator(); iter.hasNext(); )
+ {
+ Artifact artifact = (Artifact) iter.next();
+ // TODO: type of ejb should be added too?
+ if ( "jar".equals( artifact.getType() ) )
+ {
+ if ( extensionsList.length() > 0 )
+ {
+ extensionsList.append( " " );
+ }
+ extensionsList.append( artifact.getArtifactId() );
+ }
+ }
+
+ if ( extensionsList.length() > 0 )
+ {
+ Manifest.Attribute extensionsListAttr = new Manifest.Attribute( "Extension-List",
+ extensionsList.toString() );
+ m.addConfiguredAttribute( extensionsListAttr );
+ }
+
+ for ( Iterator iter = artifacts.iterator(); iter.hasNext(); )
+ {
+ Artifact artifact = (Artifact) iter.next();
+ if ( "jar".equals( artifact.getType() ) )
+ {
+ Manifest.Attribute archExtNameAttr = new Manifest.Attribute(
+ artifact.getArtifactId() + "-Extension-Name", artifact.getArtifactId() );
+ m.addConfiguredAttribute( archExtNameAttr );
+ String name = artifact.getArtifactId() + "-Implementation-Version";
+ Manifest.Attribute archImplVersionAttr = new Manifest.Attribute( name, artifact.getVersion() );
+ m.addConfiguredAttribute( archImplVersionAttr );
+
+ if ( artifact.getRepository() != null )
+ {
+ // TODO: is this correct
+ name = artifact.getArtifactId() + "-Implementation-URL";
+ String url = artifact.getRepository().getUrl() + "/" + artifact.toString();
+ Manifest.Attribute archImplUrlAttr = new Manifest.Attribute( name, url );
+ m.addConfiguredAttribute( archImplUrlAttr );
+ }
+ }
+ }
+ }
+
+ return m;
+ }
+
+ public JarArchiver getArchiver()
+ {
+ return archiver;
+ }
+
+ public void setArchiver( JarArchiver archiver )
+ {
+ this.archiver = archiver;
+ }
+
+ public void setOutputFile( File outputFile )
+ {
+ archiveFile = outputFile;
+ }
+
+ public void createArchive( MavenProject project, MavenArchiveConfiguration archiveConfiguration )
+ throws ArchiverException, ManifestException, IOException, DependencyResolutionRequiredException
+ {
+ // ----------------------------------------------------------------------
+ // We want to add the metadata for the project to the JAR in two forms:
+ //
+ // The first form is that of the POM itself. Applications that wish to
+ // access the POM for an artifact using maven tools they can.
+ //
+ // The second form is that of a properties file containing the basic
+ // top-level POM elements so that applications that wish to access
+ // POM information without the use of maven tools can do so.
+ // ----------------------------------------------------------------------
+
+ String groupId = project.getGroupId();
+
+ String artifactId = project.getArtifactId();
+
+ File exportReadyPom = writeExportReadyPom( project );
+
+ archiver.addFile( exportReadyPom, "META-INF/maven/" + groupId + "/" + artifactId + "/pom.xml" );
+
+ // ----------------------------------------------------------------------
+ // Create pom.properties file
+ // ----------------------------------------------------------------------
+
+ Properties p = new Properties();
+
+ p.setProperty( "groupId", project.getGroupId() );
+
+ p.setProperty( "artifactId", project.getArtifactId() );
+
+ p.setProperty( "version", project.getVersion() );
+
+ File pomPropertiesFile = new File( project.getFile().getParentFile(), "pom.properties" );
+
+ OutputStream os = new FileOutputStream( pomPropertiesFile );
+
+ p.store( os, "Generated by Maven" );
+
+ os.close(); // stream is flushed but not closed by Properties.store()
+
+ archiver.addFile( pomPropertiesFile, "META-INF/maven/" + groupId + "/" + artifactId + "/pom.properties" );
+
+ // ----------------------------------------------------------------------
+ // Create the manifest
+ // ----------------------------------------------------------------------
+
+ File manifestFile = archiveConfiguration.getManifestFile();
+
+ if ( manifestFile != null )
+ {
+ archiver.setManifest( manifestFile );
+ }
+
+ Manifest manifest = getManifest( project, archiveConfiguration.getManifest() );
+
+ // any custom manifest entries in the archive configuration manifest?
+ if (!archiveConfiguration.isManifestEntriesEmpty()) {
+ Map entries = archiveConfiguration.getManifestEntries();
+ Set keys = entries.keySet();
+ for (Iterator iter = keys.iterator(); iter.hasNext(); ) {
+ String key = (String) iter.next();
+ String value = (String) entries.get(key);
+ Manifest.Attribute attr = new Manifest.Attribute(key, value);
+ manifest.addConfiguredAttribute(attr);
+ }
+ }
+
+ // Configure the jar
+ archiver.addConfiguredManifest( manifest );
+
+ archiver.setCompress( archiveConfiguration.isCompress() );
+
+ archiver.setIndex( archiveConfiguration.isIndex() );
+
+ archiver.setDestFile( archiveFile );
+
+ // create archive
+ archiver.createArchive();
+
+ // Cleanup
+
+ pomPropertiesFile.delete();
+ }
+
+ private File writeExportReadyPom( MavenProject project )
+ throws IOException
+ {
+ String buildDirectory = project.getBuild().getDirectory();
+
+ File buildDirectoryFile = new File( buildDirectory );
+
+ buildDirectoryFile.mkdirs();
+
+ File fullPom = new File( buildDirectoryFile, "exported-pom.xml" );
+
+ FileWriter fWriter = null;
+
+ try
+ {
+ fWriter = new FileWriter( fullPom );
+
+ project.writeModel( fWriter );
+ }
+ finally
+ {
+ IOUtil.close( fWriter );
+ }
+
+ return fullPom;
+ }
+}