diff --git a/maven-plugins/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/AssemblyMojo.java b/maven-plugins/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/AssemblyMojo.java index f72329259b..24c834b9ba 100755 --- a/maven-plugins/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/AssemblyMojo.java +++ b/maven-plugins/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/AssemblyMojo.java @@ -44,13 +44,13 @@ import org.codehaus.plexus.util.xml.pull.XmlPullParserException; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; +import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; -import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -64,7 +64,6 @@ import java.util.regex.Pattern; * @author Vincent Siveton * @version $Id$ * @goal assembly - * @description Assemble an application bundle or distribution from an assembly descriptor. * @requiresDependencyResolution test * @requiresDirectInvocation * @execute phase="package" @@ -73,7 +72,6 @@ import java.util.regex.Pattern; public class AssemblyMojo extends AbstractUnpackingMojo { - /** * Predefined Assembly Descriptor Id's. You can select bin, jar-with-dependencies, or src. * @@ -130,14 +128,57 @@ public class AssemblyMojo public void execute() throws MojoExecutionException, MojoFailureException { - doExecute(); + Assembly assembly = readAssembly(); + + // TODO: include dependencies marked for distribution under certain formats + // TODO: how, might we plug this into an installer, such as NSIS? + // TODO: allow file mode specifications? + + String fullName = finalName + "-" + assembly.getId(); + + for ( Iterator i = assembly.getFormats().iterator(); i.hasNext(); ) + { + String format = (String) i.next(); + + String filename = fullName + "." + format; + + File destFile; + try + { + // TODO: use component roles? Can we do that in a mojo? + Archiver archiver = createArchiver( format ); + + destFile = createArchive( archiver, assembly, filename ); + } + catch ( ArchiverException e ) + { + throw new MojoExecutionException( "Error creating assembly", e ); + } + catch ( IOException e ) + { + throw new MojoExecutionException( "Error creating assembly", e ); + } + + projectHelper.attachArtifact( project, format, format + "-assembly", destFile ); + } } - /** - * Create the binary distribution. - */ - private void doExecute() - throws MojoExecutionException, MojoFailureException + protected File createArchive( Archiver archiver, Assembly assembly, String filename ) + throws ArchiverException, IOException, MojoExecutionException + { + File destFile; + processDependencySets( archiver, assembly.getDependencySets(), assembly.isIncludeBaseDirectory() ); + processFileSets( archiver, assembly.getFileSets(), assembly.isIncludeBaseDirectory() ); + + destFile = new File( outputDirectory, filename ); + archiver.setDestFile( destFile ); + archiver.createArchive(); + + return destFile; + } + + protected Assembly readAssembly() + throws MojoFailureException, MojoExecutionException { Reader r; @@ -184,43 +225,7 @@ public class AssemblyMojo { IOUtil.close( r ); } - - // TODO: include dependencies marked for distribution under certain formats - // TODO: how, might we plug this into an installer, such as NSIS? - // TODO: allow file mode specifications? - - String fullName = finalName + "-" + assembly.getId(); - - for ( Iterator i = assembly.getFormats().iterator(); i.hasNext(); ) - { - String format = (String) i.next(); - - String filename = fullName + "." + format; - - File destFile = null; - try - { - // TODO: use component roles? Can we do that in a mojo? - Archiver archiver = createArchiver( format ); - - processDependencySets( archiver, assembly.getDependencySets(), assembly.isIncludeBaseDirectory() ); - processFileSets( archiver, assembly.getFileSets(), assembly.isIncludeBaseDirectory() ); - - destFile = new File( outputDirectory, filename ); - archiver.setDestFile( destFile ); - archiver.createArchive(); - } - catch ( ArchiverException e ) - { - throw new MojoExecutionException( "Error creating assembly", e ); - } - catch ( IOException e ) - { - throw new MojoExecutionException( "Error creating assembly", e ); - } - - projectHelper.attachArtifact( project, format, format + "-assembly", destFile ); - } + return assembly; } /** @@ -230,7 +235,7 @@ public class AssemblyMojo * @param dependencySets * @param includeBaseDirectory */ - private void processDependencySets( Archiver archiver, List dependencySets, boolean includeBaseDirectory ) + protected void processDependencySets( Archiver archiver, List dependencySets, boolean includeBaseDirectory ) throws ArchiverException, IOException, MojoExecutionException { for ( Iterator i = dependencySets.iterator(); i.hasNext(); ) @@ -310,7 +315,7 @@ public class AssemblyMojo * @param includeBaseDirecetory * @throws ArchiverException */ - private void processFileSets( Archiver archiver, List fileSets, boolean includeBaseDirecetory ) + protected void processFileSets( Archiver archiver, List fileSets, boolean includeBaseDirecetory ) throws ArchiverException { for ( Iterator i = fileSets.iterator(); i.hasNext(); ) diff --git a/maven-plugins/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/DirectoryMojo.java b/maven-plugins/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/DirectoryMojo.java new file mode 100644 index 0000000000..552b10a879 --- /dev/null +++ b/maven-plugins/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/DirectoryMojo.java @@ -0,0 +1,62 @@ +package org.apache.maven.plugin.assembly; + +/* + * 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.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.assembly.archiver.DirectoryArchiver; +import org.apache.maven.plugins.assembly.model.Assembly; +import org.codehaus.plexus.archiver.Archiver; +import org.codehaus.plexus.archiver.ArchiverException; + +import java.io.IOException; + +/** + * Assemble an application bundle or distribution. + * + * @goal directory + * @requiresDependencyResolution test + * @requiresDirectInvocation + * @execute phase="package" + */ +public class DirectoryMojo + extends AssemblyMojo +{ + public void execute() + throws MojoExecutionException, MojoFailureException + { + Assembly assembly = readAssembly(); + + String fullName = finalName + "-" + assembly.getId(); + + try + { + Archiver archiver = new DirectoryArchiver(); + + createArchive( archiver, assembly, fullName ); + } + catch ( ArchiverException e ) + { + throw new MojoExecutionException( "Error creating assembly", e ); + } + catch ( IOException e ) + { + throw new MojoExecutionException( "Error creating assembly", e ); + } + } + +} diff --git a/maven-plugins/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/archiver/DirectoryArchiver.java b/maven-plugins/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/archiver/DirectoryArchiver.java new file mode 100644 index 0000000000..b6cd656bfa --- /dev/null +++ b/maven-plugins/maven-assembly-plugin/src/main/java/org/apache/maven/plugin/assembly/archiver/DirectoryArchiver.java @@ -0,0 +1,186 @@ +package org.apache.maven.plugin.assembly.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.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Iterator; +import java.util.Map; + +import org.codehaus.plexus.archiver.AbstractArchiver; +import org.codehaus.plexus.archiver.ArchiveEntry; +import org.codehaus.plexus.archiver.ArchiverException; + +/** + * A plexus archiver implementation that stores the files to archive in a + * directory. + */ +public class DirectoryArchiver + extends AbstractArchiver +{ + + public void createArchive() + throws ArchiverException, IOException + { + //Most of this method was copied from org.codehaus.plexus.archiver.tar.TarArchiver + //and modified to store files in a directory, not a tar archive. + Map listFiles = getFiles(); + if ( listFiles == null || listFiles.size() == 0 ) + { + new ArchiverException( "You must set at least one file." ); + } + + File destDirectory = getDestFile(); + if ( destDirectory == null ) + { + new ArchiverException( "You must set the destination directory." ); + } + if ( destDirectory.exists() && !destDirectory.isDirectory() ) + { + new ArchiverException( destDirectory + " isn't a directory." ); + } + if ( destDirectory.exists() && !destDirectory.canWrite() ) + { + new ArchiverException( destDirectory + " is read-only." ); + } + + // Check if we don't add directory file in itself + for ( Iterator iter = getFiles().keySet().iterator(); iter.hasNext(); ) + { + String fileName = ( String ) iter.next(); + ArchiveEntry fileToAdd = ( ArchiveEntry ) getFiles().get( fileName ); + if ( destDirectory.equals( fileToAdd.getFile() ) ) + { + throw new ArchiverException( + "The destination directory cannot include itself."); + } + } + + getLogger().info( "Building assembly directory : " + destDirectory.getAbsolutePath() ); + + try + { + for ( Iterator iter = getFiles().keySet().iterator(); iter.hasNext(); ) + { + String fileName = ( String ) iter.next(); + ArchiveEntry f = ( ArchiveEntry ) getFiles().get( fileName ); + String destDir = destDirectory.getCanonicalPath(); + fileName = destDir + File.separator + fileName; + copyFile( f, fileName ); + } + } + catch ( IOException ioe ) + { + String message = "Problem copying files : " + ioe.getMessage(); + throw new ArchiverException( message, ioe ); + } + } + + /** + * Copies the specified file to the specified path, creating any ancestor directory + * structure as necessary. + * + * @param file The file to copy (IOException will be thrown if this does not exist) + * @param vPath The fully qualified path to copy the file to. + * @throws ArchiverException If there is a problem creating the directory structure + * @throws IOException If there is a problem copying the file + */ + protected void copyFile( ArchiveEntry entry, String vPath ) + throws ArchiverException, IOException + { + // don't add "" to the archive + if ( vPath.length() <= 0 ) + { + return; + } + + File inFile = entry.getFile(); + File outFile = new File( vPath ); + + if ( outFile.exists() && outFile.lastModified() >= inFile.lastModified() ) + { + //already up to date... + return; + } + + outFile.setLastModified( inFile.lastModified() ); + + if ( ! inFile.isDirectory() ) + { + if ( ! outFile.getParentFile().exists() ) + { + //create the parent directory... + if ( ! outFile.getParentFile().mkdirs() ) + { + //Failure, unable to create specified directory for some unknown reason. + throw new ArchiverException ("Unable to create directory or parent directory of " + + outFile ); + } + } + FileInputStream fIn = new FileInputStream( inFile ); + FileOutputStream fout = new FileOutputStream( outFile ); + try + { + byte[] buffer = new byte[ 8 * 1024 ]; + int count = 0; + do + { + fout.write( buffer, 0, count ); + count = fIn.read( buffer, 0, buffer.length ); + } + while ( count != -1 ); + } + finally + { + try + { + fIn.close(); + } + catch ( IOException ioe ) + { + fout.close(); + throw ioe; + } + fout.close(); + } + } + else + { //file is a directory + if ( outFile.exists() ) + { + if ( ! outFile.isDirectory() ) + { + //should we just delete the file and replace it with a directory? + //throw an exception, let the user delete the file manually. + throw new ArchiverException( + "Expected directory and found file at copy destination of " + + inFile + " to " + outFile ); + } + } + else if ( ! outFile.mkdirs() ) + { + //Failure, unable to create specified directory for some unknown reason. + throw new ArchiverException( + "Unable to create directory or parent directory of " + + outFile ); + } + + } + } +} \ No newline at end of file