You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by sn...@apache.org on 2007/07/18 07:34:02 UTC

svn commit: r557155 - in /maven/plugins/branches/MWAR-97-2/src: main/java/org/apache/maven/plugin/war/ main/java/org/apache/maven/plugin/war/overlay/ main/java/org/apache/maven/plugin/war/packaging/ test/java/org/apache/maven/plugin/war/ test/java/org/...

Author: snicoll
Date: Tue Jul 17 22:34:01 2007
New Revision: 557155

URL: http://svn.apache.org/viewvc?view=rev&rev=557155
Log:
- New implementation is fully wired in the mojo. Temporary commit with still the old code to make sure that we have no regression.
- Still a few tests to fix

Modified:
    maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/AbstractWarMojo.java
    maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/overlay/InvalidOverlayConfigurationException.java
    maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/overlay/OverlayManager.java
    maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/AbstractWarPackagingTask.java
    maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/ArtifactsPackagingTask.java
    maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/ClassesPackagingTask.java
    maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/OverlayPackagingTask.java
    maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/WarPackagingContext.java
    maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/WarPackagingTask.java
    maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/WarProjectPackagingTask.java
    maven/plugins/branches/MWAR-97-2/src/test/java/org/apache/maven/plugin/war/WarExplodedMojoTest.java
    maven/plugins/branches/MWAR-97-2/src/test/java/org/apache/maven/plugin/war/stub/IncludeExcludeWarArtifactStub.java
    maven/plugins/branches/MWAR-97-2/src/test/java/org/apache/maven/plugin/war/stub/WarArtifactStub.java
    maven/plugins/branches/MWAR-97-2/src/test/java/org/apache/maven/plugin/war/stub/WarOverlayStub.java

Modified: maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/AbstractWarMojo.java
URL: http://svn.apache.org/viewvc/maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/AbstractWarMojo.java?view=diff&rev=557155&r1=557154&r2=557155
==============================================================================
--- maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/AbstractWarMojo.java (original)
+++ maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/AbstractWarMojo.java Tue Jul 17 22:34:01 2007
@@ -27,7 +27,14 @@
 import org.apache.maven.plugin.AbstractMojo;
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.plugin.war.overlay.OverlayManager;
+import org.apache.maven.plugin.war.packaging.OverlayPackagingTask;
+import org.apache.maven.plugin.war.packaging.WarPackagingContext;
+import org.apache.maven.plugin.war.packaging.WarPackagingTask;
+import org.apache.maven.plugin.war.packaging.WarProjectPackagingTask;
 import org.apache.maven.plugin.war.util.MappingUtils;
+import org.apache.maven.plugin.war.util.PathSet;
 import org.apache.maven.project.MavenProject;
 import org.codehaus.plexus.archiver.ArchiverException;
 import org.codehaus.plexus.archiver.UnArchiver;
@@ -535,6 +542,69 @@
         }
     }
 
+
+    /**
+     * Builds the webapp for the specified project with the new packaging task
+     * thingy
+     * <p/>
+     * Classes, libraries and tld files are copied to
+     * the <tt>webappDirectory</tt> during this phase.
+     * <p/>
+     * TODO: this is a temporary branch code! rename and clean the mess here when we're done.
+     *
+     * @param project         the maven project
+     * @param webappDirectory the target directory
+     * @throws MojoExecutionException if an error occured while packaging the webapp
+     * @throws MojoFailureException   if an unexpected error occured while packaging the webapp
+     */
+    public void buildWebapp( MavenProject project, File webappDirectory )
+        throws MojoExecutionException, MojoFailureException, IOException
+    {
+
+        final long startTime = System.currentTimeMillis();
+        getLog().info( "Assembling webapp[" + project.getArtifactId() + "] in [" + webappDirectory + "]" );
+
+        final List packagingTasks = getPackagingTasks();
+        final Iterator it = packagingTasks.iterator();
+        while ( it.hasNext() )
+        {
+            WarPackagingTask warPackagingTask = (WarPackagingTask) it.next();
+            warPackagingTask.performPackaging( new DefaultWarPackagingContext( webappDirectory ) );
+        }
+        getLog().info( "Webapp assembled in[" + ( System.currentTimeMillis() - startTime ) + " msecs]" );
+    }
+
+
+    /**
+     * Returns a <tt>List</tt> of the {@link org.apache.maven.plugin.war.packaging.WarPackagingTask}
+     * instances to invoke to perform the packaging.
+     *
+     * @return the list of packaging tasks
+     * @throws MojoExecutionException if the packaging tasks could not be built
+     */
+    private List getPackagingTasks()
+        throws MojoExecutionException
+    {
+        final List packagingTasks = new ArrayList();
+        OverlayManager overlayManager = new OverlayManager( overlays, project );
+        final List resolvedOverlays = overlayManager.getOverlays();
+        final Iterator it = resolvedOverlays.iterator();
+        while ( it.hasNext() )
+        {
+            Overlay overlay = (Overlay) it.next();
+            if ( overlay.isCurrentProject() )
+            {
+                packagingTasks.add( new WarProjectPackagingTask( webResources, webXml, containerConfigXML ) );
+            }
+            else
+            {
+                packagingTasks.add( new OverlayPackagingTask( overlay ) );
+            }
+        }
+        return packagingTasks;
+    }
+
+
     /**
      * Builds the webapp for the specified project.
      * <p/>
@@ -545,7 +615,7 @@
      * @param webappDirectory
      * @throws java.io.IOException if an error occured while building the webapp
      */
-    public void buildWebapp( MavenProject project, File webappDirectory )
+    public void buildWebapp2( MavenProject project, File webappDirectory )
         throws MojoExecutionException, IOException, MojoFailureException
     {
         getLog().info( "Assembling webapp " + project.getArtifactId() + " in " + webappDirectory );
@@ -556,6 +626,7 @@
         File metainfDir = new File( webappDirectory, META_INF );
         metainfDir.mkdirs();
 
+        // DONE
         List webResources = this.webResources != null ? Arrays.asList( this.webResources ) : null;
         if ( webResources != null && webResources.size() > 0 )
         {
@@ -571,8 +642,10 @@
             }
         }
 
+        //DONE
         copyResources( warSourceDirectory, webappDirectory );
 
+        // TODO
         if ( webXml != null && StringUtils.isNotEmpty( webXml.getName() ) )
         {
             if ( !webXml.exists() )
@@ -584,6 +657,7 @@
             copyFileIfModified( webXml, new File( webinfDir, "/web.xml" ) );
         }
 
+        //TODO
         if ( containerConfigXML != null && StringUtils.isNotEmpty( containerConfigXML.getName() ) )
         {
             metainfDir = new File( webappDirectory, META_INF );
@@ -599,6 +673,7 @@
 
         File webappClassesDirectory = new File( webappDirectory, WEB_INF + "/classes" );
 
+        //DONE
         if ( classesDirectory.exists() && !classesDirectory.equals( webappClassesDirectory ) )
         {
             if ( archiveClasses )
@@ -611,6 +686,7 @@
             }
         }
 
+        //DONE
         Set artifacts = project.getArtifacts();
 
         List duplicates = findDuplicates( artifacts );
@@ -1107,4 +1183,103 @@
 
     }
 
+    // War packaging implementation
+
+    private class DefaultWarPackagingContext
+        implements WarPackagingContext
+    {
+
+        private final PathSet pathSet = new PathSet();
+
+        private final File webappDirectory;
+
+
+        public DefaultWarPackagingContext( File webappDirectory )
+        {
+            this.webappDirectory = webappDirectory;
+        }
+
+
+        public MavenProject getProject()
+        {
+            return project;
+        }
+
+        public File getWebappDirectory()
+        {
+            return webappDirectory;
+        }
+
+        public File getClassesDirectory()
+        {
+            return classesDirectory;
+        }
+
+        public Log getLog()
+        {
+            return AbstractWarMojo.this.getLog();
+        }
+
+        public String getOutputFileNameMapping()
+        {
+            return outputFileNameMapping;
+        }
+
+        public File getWebappSourceDirectory()
+        {
+            return warSourceDirectory;
+        }
+
+        public String[] getWebappSourceIncludes()
+        {
+            return getIncludes();
+        }
+
+        public String[] getWebappSourceExcludes()
+        {
+            return getExcludes();
+        }
+
+        public boolean archiveClasses()
+        {
+            return archiveClasses;
+        }
+
+        public File getOverlaysWorkDirectory()
+        {
+            return workDirectory;
+        }
+
+        public ArchiverManager getArchiverManager()
+        {
+            return archiverManager;
+        }
+
+        public MavenArchiveConfiguration getArchive()
+        {
+            return archive;
+        }
+
+        public JarArchiver getJarArchiver()
+        {
+            return jarArchiver;
+        }
+
+        public PathSet getProtectedFiles()
+        {
+            return pathSet;
+        }
+
+        public List getFilters()
+        {
+            return filters;
+        }
+
+        public Map getFilterProperties()
+            throws MojoExecutionException
+        {
+            //TODO refactor this
+            return getBuildFilterProperties();
+        }
+    }
 }

Modified: maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/overlay/InvalidOverlayConfigurationException.java
URL: http://svn.apache.org/viewvc/maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/overlay/InvalidOverlayConfigurationException.java?view=diff&rev=557155&r1=557154&r2=557155
==============================================================================
--- maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/overlay/InvalidOverlayConfigurationException.java (original)
+++ maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/overlay/InvalidOverlayConfigurationException.java Tue Jul 17 22:34:01 2007
@@ -1,5 +1,7 @@
 package org.apache.maven.plugin.war.overlay;
 
+import org.apache.maven.plugin.MojoExecutionException;
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -25,11 +27,8 @@
  * @author Stephane Nicoll
  */
 public class InvalidOverlayConfigurationException
-    extends Exception
+    extends MojoExecutionException
 {
-    public InvalidOverlayConfigurationException()
-    {
-    }
 
     public InvalidOverlayConfigurationException( String string )
     {
@@ -39,10 +38,5 @@
     public InvalidOverlayConfigurationException( String string, Throwable throwable )
     {
         super( string, throwable );
-    }
-
-    public InvalidOverlayConfigurationException( Throwable throwable )
-    {
-        super( throwable );
     }
 }

Modified: maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/overlay/OverlayManager.java
URL: http://svn.apache.org/viewvc/maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/overlay/OverlayManager.java?view=diff&rev=557155&r1=557154&r2=557155
==============================================================================
--- maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/overlay/OverlayManager.java (original)
+++ maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/overlay/OverlayManager.java Tue Jul 17 22:34:01 2007
@@ -49,8 +49,9 @@
      * manager so a new list is created based on the overlays.
      *
      * @param overlays the overlays
-     * @param project the maven project
-     * @throws InvalidOverlayConfigurationException if the config is invalid
+     * @param project  the maven project
+     * @throws InvalidOverlayConfigurationException
+     *          if the config is invalid
      */
     public OverlayManager( List overlays, MavenProject project )
         throws InvalidOverlayConfigurationException

Modified: maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/AbstractWarPackagingTask.java
URL: http://svn.apache.org/viewvc/maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/AbstractWarPackagingTask.java?view=diff&rev=557155&r1=557154&r2=557155
==============================================================================
--- maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/AbstractWarPackagingTask.java (original)
+++ maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/AbstractWarPackagingTask.java Tue Jul 17 22:34:01 2007
@@ -50,34 +50,74 @@
 {
     public static final String[] DEFAULT_INCLUDES = {"**/**"};
 
-    public static final String CLASSES_PATH = "WEB-INF/classes";
+    public static final String WEB_INF_PATH = "WEB-INF";
 
-    public static final String LIB_PATH = "WEB-INF/lib";
+    public static final String META_INF_PATH = "META-INF";
+
+    public static final String CLASSES_PATH = "WEB-INF/classes/";
+
+    public static final String LIB_PATH = "WEB-INF/lib/";
 
     /**
-     * Copies the files if possible.
+     * Copies the files if possible with an optional target prefix.
      * <p/>
      * Copy uses a first-win strategy: files that have already been copied by previous
      * tasks are ignored. This method makes sure to update the list of protected files
      * which gives the list of files that have already been copied.
+     * <p/>
+     * If the structure of the source directory is not the same as the root of the
+     * webapp, use the <tt>targetPrefix</tt> parameter to specify in which particular
+     * directory the files should be copied. Use <tt>null</tt> to copy the files with
+     * the same structure
      *
      * @param context        the context to use
      * @param sourceBaseDir  the base directory from which the <tt>sourceFilesSet</tt> will be copied
      * @param sourceFilesSet the files to be copied
+     * @param targetPrefix   the prefix to add to the target file name
      * @throws IOException if an error occured while copying the files
      */
-    protected void copyFiles( WarPackagingContext context, File sourceBaseDir, PathSet sourceFilesSet )
+    protected void copyFiles( WarPackagingContext context, File sourceBaseDir, PathSet sourceFilesSet,
+                              String targetPrefix )
         throws IOException
     {
         for ( Iterator iter = sourceFilesSet.iterator(); iter.hasNext(); )
         {
             final String fileToCopyName = (String) iter.next();
             final File sourceFile = new File( sourceBaseDir, fileToCopyName );
-            copyFile( context, sourceFile, fileToCopyName );
+
+            String destinationFileName;
+            if ( targetPrefix == null )
+            {
+                destinationFileName = fileToCopyName;
+            }
+            else
+            {
+                destinationFileName = targetPrefix + fileToCopyName;
+            }
+
+            copyFile( context, sourceFile, destinationFileName );
         }
     }
 
     /**
+     * Copies the files if possible as is.
+     * <p/>
+     * Copy uses a first-win strategy: files that have already been copied by previous
+     * tasks are ignored. This method makes sure to update the list of protected files
+     * which gives the list of files that have already been copied.
+     *
+     * @param context        the context to use
+     * @param sourceBaseDir  the base directory from which the <tt>sourceFilesSet</tt> will be copied
+     * @param sourceFilesSet the files to be copied
+     * @throws IOException if an error occured while copying the files
+     */
+    protected void copyFiles( WarPackagingContext context, File sourceBaseDir, PathSet sourceFilesSet )
+        throws IOException
+    {
+        copyFiles( context, sourceBaseDir, sourceFilesSet, null );
+    }
+
+    /**
      * Copy the specified file if the target location has not yet already been used.
      * <p/>
      * The <tt>targetFileName</tt> is the relative path according to the root of
@@ -94,18 +134,17 @@
     {
         if ( !context.getProtectedFiles().contains( targetFilename ) )
         {
-            File targetFile = new File( context.getWebAppDirectory(), targetFilename );
+            File targetFile = new File( context.getWebappDirectory(), targetFilename );
             copyFile( file, targetFile );
 
             // Add the file to the protected list
             context.getProtectedFiles().add( targetFilename );
-            context.getLogger().debug( " + " + targetFilename + " has been copied." );
+            context.getLog().debug( " + " + targetFilename + " has been copied." );
             return true;
         }
         else
         {
-            context.getLogger().debug(
-                " - " + targetFilename + " wasn't copied because it has already been packaged." );
+            context.getLog().debug( " - " + targetFilename + " wasn't copied because it has already been packaged." );
             return false;
         }
     }
@@ -130,7 +169,7 @@
 
         if ( !context.getProtectedFiles().contains( targetFilename ) )
         {
-            final File targetFile = new File( context.getWebAppDirectory(), targetFilename );
+            final File targetFile = new File( context.getWebappDirectory(), targetFilename );
             // buffer so it isn't reading a byte at a time!
             Reader fileReader = null;
             Writer fileWriter = null;
@@ -158,13 +197,12 @@
             }
             // Add the file to the protected list
             context.getProtectedFiles().add( targetFilename );
-            context.getLogger().debug( " + " + targetFilename + " has been copied." );
+            context.getLog().debug( " + " + targetFilename + " has been copied." );
             return true;
         }
         else
         {
-            context.getLogger().debug(
-                " - " + targetFilename + " wasn't copied because it has already been packaged." );
+            context.getLog().debug( " - " + targetFilename + " wasn't copied because it has already been packaged." );
             return false;
         }
     }
@@ -203,7 +241,7 @@
         }
         catch ( NoSuchArchiverException e )
         {
-            context.getLogger().warn( "Skip unpacking dependency file[" + file.getAbsolutePath() +
+            context.getLog().warn( "Skip unpacking dependency file[" + file.getAbsolutePath() +
                 " with unknown extension[" + archiveExt + "]" );
         }
     }
@@ -227,6 +265,35 @@
         FileUtils.copyFile( source.getCanonicalFile(), destination );
         // preserve timestamp
         destination.setLastModified( source.lastModified() );
+    }
+
+
+    /**
+     * Copy file from source to destination only if source timestamp is later than the destination timestamp.
+     * The directories up to <code>destination</code> will be created if they don't already exist.
+     * <code>destination</code> will be overwritten if it already exists.
+     *
+     * @param source      An existing non-directory <code>File</code> to copy bytes from.
+     * @param destination A non-directory <code>File</code> to write bytes to (possibly
+     *                    overwriting).
+     * @throws IOException                   if <code>source</code> does not exist, <code>destination</code> cannot be
+     *                                       written to, or an IO error occurs during copying.
+     * @throws java.io.FileNotFoundException if <code>destination</code> is a directory
+     *                                       <p/>
+     *                                       TO DO: Remove this method when Maven moves to plexus-util version 1.4
+     *                                       TODO: WARNING this needs to be refactored once the protected list system is up to date
+     */
+    protected void copyFileIfModified( File source, File destination )
+        throws IOException
+    {
+        // TO DO: Remove this method and use the method in WarFileUtils when Maven 2 changes
+        // to plexus-util 1.2.
+        if ( destination.lastModified() < source.lastModified() )
+        {
+            FileUtils.copyFile( source.getCanonicalFile(), destination );
+            // preserve timestamp
+            destination.setLastModified( source.lastModified() );
+        }
     }
 
     /**

Modified: maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/ArtifactsPackagingTask.java
URL: http://svn.apache.org/viewvc/maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/ArtifactsPackagingTask.java?view=diff&rev=557155&r1=557154&r2=557155
==============================================================================
--- maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/ArtifactsPackagingTask.java (original)
+++ maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/ArtifactsPackagingTask.java Tue Jul 17 22:34:01 2007
@@ -19,9 +19,9 @@
     extends AbstractWarPackagingTask
 {
 
-    public static final String TLD_PATH = "WEB-INF/tld";
+    public static final String TLD_PATH = "WEB-INF/tld/";
 
-    public static final String SERVICES_PATH = "WEB-INF/services";
+    public static final String SERVICES_PATH = "WEB-INF/services/";
 
     private final Set artifacts;
 
@@ -44,13 +44,13 @@
             Artifact artifact = (Artifact) iter.next();
             String targetFileName = getArtifactFinalName( context, artifact );
 
-            context.getLogger().debug( "Processing: " + targetFileName );
+            context.getLog().debug( "Processing: " + targetFileName );
 
             if ( duplicates.contains( targetFileName ) )
             {
-                context.getLogger().debug( "Duplicate found: " + targetFileName );
+                context.getLog().debug( "Duplicate found: " + targetFileName );
                 targetFileName = artifact.getGroupId() + "-" + targetFileName;
-                context.getLogger().debug( "Renamed to: " + targetFileName );
+                context.getLog().debug( "Renamed to: " + targetFileName );
             }
 
             if ( !artifact.isOptional() && filter.include( artifact ) )
@@ -78,7 +78,7 @@
                     }
                     else
                     {
-                        context.getLogger().debug(
+                        context.getLog().debug(
                             "Artifact of type[" + type + "] is not supported, ignoring[" + artifact + "]" );
                     }
                 }

Modified: maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/ClassesPackagingTask.java
URL: http://svn.apache.org/viewvc/maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/ClassesPackagingTask.java?view=diff&rev=557155&r1=557154&r2=557155
==============================================================================
--- maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/ClassesPackagingTask.java (original)
+++ maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/ClassesPackagingTask.java Tue Jul 17 22:34:01 2007
@@ -26,7 +26,11 @@
     public void performPackaging( WarPackagingContext context )
         throws MojoExecutionException
     {
-        final File webappClassesDirectory = new File( context.getWebAppDirectory(), CLASSES_PATH );
+        final File webappClassesDirectory = new File( context.getWebappDirectory(), CLASSES_PATH );
+        if ( !webappClassesDirectory.exists() )
+        {
+            webappClassesDirectory.mkdirs();
+        }
 
         if ( context.getClassesDirectory().exists() && !context.getClassesDirectory().equals( webappClassesDirectory ) )
         {
@@ -39,7 +43,7 @@
                 final PathSet sources = getFilesToIncludes( context.getClassesDirectory(), null, null );
                 try
                 {
-                    copyFiles( context, webappClassesDirectory, sources );
+                    copyFiles( context, context.getClassesDirectory(), sources, CLASSES_PATH );
                 }
                 catch ( IOException e )
                 {
@@ -55,17 +59,17 @@
     {
         //TODO use ArtifactFactory and resolve the final name the usual way instead
         final String archiveName = context.getProject().getBuild().getFinalName() + ".jar";
-        final String targetFilename = LIB_PATH + File.separator + archiveName;
+        final String targetFilename = LIB_PATH + archiveName;
 
         // TODO: this is bit hackish here ; check if the specified path is registered
         if ( context.getProtectedFiles().contains( targetFilename ) )
         {
-            context.getLogger().warn(
+            context.getLog().warn(
                 "Could not generate archive classes file[" + targetFilename + "] has already been copied." );
         }
         else
         {
-            final File libDirectory = new File( context.getWebAppDirectory(), LIB_PATH );
+            final File libDirectory = new File( context.getWebappDirectory(), LIB_PATH );
             final File jarFile = new File( libDirectory, archiveName );
 
             try
@@ -73,8 +77,8 @@
                 final MavenArchiver archiver = new MavenArchiver();
                 archiver.setArchiver( context.getJarArchiver() );
                 archiver.setOutputFile( jarFile );
-                archiver.getArchiver().addDirectory( context.getClassesDirectory(), context.getWebAppSourceIncludes(),
-                                                     context.getWebAppSourceExcludes() );
+                archiver.getArchiver().addDirectory( context.getClassesDirectory(), context.getWebappSourceIncludes(),
+                                                     context.getWebappSourceExcludes() );
                 archiver.createArchive( context.getProject(), context.getArchive() );
             }
             catch ( ArchiverException e )

Modified: maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/OverlayPackagingTask.java
URL: http://svn.apache.org/viewvc/maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/OverlayPackagingTask.java?view=diff&rev=557155&r1=557154&r2=557155
==============================================================================
--- maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/OverlayPackagingTask.java (original)
+++ maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/OverlayPackagingTask.java Tue Jul 17 22:34:01 2007
@@ -22,6 +22,7 @@
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.war.Overlay;
 import org.apache.maven.plugin.war.util.PathSet;
+import org.codehaus.plexus.util.FileUtils;
 
 import java.io.File;
 import java.io.IOException;
@@ -56,13 +57,13 @@
     {
         if ( overlay.shouldSkip() )
         {
-            context.getLogger().info( "Skipping overlay[" + overlay + "]" );
+            context.getLog().info( "Skipping overlay[" + overlay + "]" );
         }
         else
         {
             try
             {
-                context.getLogger().info( "Processing overlay[" + overlay + "]" );
+                context.getLog().info( "Processing overlay[" + overlay + "]" );
 
                 // Step1: Extract if necessary
                 final File tmpDir = unpackOverlay( context, overlay );
@@ -97,14 +98,15 @@
         final File tmpDir = getOverlayTempDirectory( context, overlay );
 
         // TODO: not sure it's good, we should reuse the markers of the dependency plugin
-        if ( overlay.getArtifact().getFile().lastModified() > tmpDir.lastModified() )
+        if ( FileUtils.sizeOfDirectory( tmpDir ) == 0 ||
+            overlay.getArtifact().getFile().lastModified() > tmpDir.lastModified() )
         {
-            context.getLogger().info( "Unpacking overlay[" + overlay + "]" );
+            context.getLog().info( "Unpacking overlay[" + overlay + "]" );
             doUnpack( context, overlay.getArtifact().getFile(), tmpDir );
         }
         else
         {
-            context.getLogger().debug( "Overlay[" + overlay + "] was already unpacked" );
+            context.getLog().debug( "Overlay[" + overlay + "] was already unpacked" );
         }
         return tmpDir;
     }
@@ -126,7 +128,7 @@
         final File result = new File( groupIdDir, overlay.getArtifactId() );
         if ( !result.exists() )
         {
-            result.mkdir();
+            result.mkdirs();
         }
         return result;
     }

Modified: maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/WarPackagingContext.java
URL: http://svn.apache.org/viewvc/maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/WarPackagingContext.java?view=diff&rev=557155&r1=557154&r2=557155
==============================================================================
--- maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/WarPackagingContext.java (original)
+++ maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/WarPackagingContext.java Tue Jul 17 22:34:01 2007
@@ -21,11 +21,11 @@
 
 import org.apache.maven.archiver.MavenArchiveConfiguration;
 import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.logging.Log;
 import org.apache.maven.plugin.war.util.PathSet;
 import org.apache.maven.project.MavenProject;
 import org.codehaus.plexus.archiver.jar.JarArchiver;
 import org.codehaus.plexus.archiver.manager.ArchiverManager;
-import org.codehaus.plexus.logging.Logger;
 
 import java.io.File;
 import java.util.List;
@@ -51,28 +51,28 @@
      *
      * @return the webapp directory
      */
-    File getWebAppDirectory();
+    File getWebappDirectory();
 
     /**
      * Returns the main webapp source directory.
      *
      * @return the webapp source directory
      */
-    File getWebAppSourceDirectory();
+    File getWebappSourceDirectory();
 
     /**
      * Returns the webapp source includes.
      *
      * @return the webapp source includes
      */
-    String[] getWebAppSourceIncludes();
+    String[] getWebappSourceIncludes();
 
     /**
      * Returns the webapp source excludes.
      *
      * @return the webapp source excludes
      */
-    String[] getWebAppSourceExcludes();
+    String[] getWebappSourceExcludes();
 
     /**
      * Returns the directory holding generated classes.
@@ -94,7 +94,7 @@
      *
      * @return the logger
      */
-    Logger getLogger();
+    Log getLog();
 
     /**
      * Returns the directory to unpack dependent WARs into if needed.

Modified: maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/WarPackagingTask.java
URL: http://svn.apache.org/viewvc/maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/WarPackagingTask.java?view=diff&rev=557155&r1=557154&r2=557155
==============================================================================
--- maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/WarPackagingTask.java (original)
+++ maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/WarPackagingTask.java Tue Jul 17 22:34:01 2007
@@ -20,6 +20,7 @@
  */
 
 import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
 
 /**
  * The base packaging task.
@@ -37,8 +38,10 @@
      *
      * @param context the packaging context
      * @throws MojoExecutionException if an error occured
+     * @throws MojoFailureException   if the project configuration is invalid
      */
-    void performPackaging(WarPackagingContext context) throws MojoExecutionException;
+    void performPackaging( WarPackagingContext context )
+        throws MojoExecutionException, MojoFailureException;
 
 
 }

Modified: maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/WarProjectPackagingTask.java
URL: http://svn.apache.org/viewvc/maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/WarProjectPackagingTask.java?view=diff&rev=557155&r1=557154&r2=557155
==============================================================================
--- maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/WarProjectPackagingTask.java (original)
+++ maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/packaging/WarProjectPackagingTask.java Tue Jul 17 22:34:01 2007
@@ -2,8 +2,10 @@
 
 import org.apache.maven.model.Resource;
 import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
 import org.apache.maven.plugin.war.util.PathSet;
 import org.codehaus.plexus.util.DirectoryScanner;
+import org.codehaus.plexus.util.StringUtils;
 
 import java.io.File;
 import java.io.IOException;
@@ -13,6 +15,7 @@
  * <ul
  * <li>The list of web resources, if any</li>
  * <li>The content of the webapp directory if it exists</li>
+ * <li>The custom deployment descriptor(s), if any</li>
  * <li>The content of the classes directory if it exists</li>
  * <li>The dependencies of the project</li>
  * </ul>
@@ -24,8 +27,12 @@
 {
     private final Resource[] webResources;
 
+    private final File webXml;
 
-    public WarProjectPackagingTask( Resource[] webResources )
+    private final File containerConfigXML;
+
+
+    public WarProjectPackagingTask( Resource[] webResources, File webXml, File containerConfigXml )
     {
         if ( webResources != null )
         {
@@ -35,16 +42,26 @@
         {
             this.webResources = new Resource[0];
         }
+        this.webXml = webXml;
+        this.containerConfigXML = containerConfigXml;
     }
 
     public void performPackaging( WarPackagingContext context )
-        throws MojoExecutionException
+        throws MojoExecutionException, MojoFailureException
     {
 
+        // Prepare the INF directories
+        File webinfDir = new File( context.getWebappDirectory(), WEB_INF_PATH );
+        webinfDir.mkdirs();
+        File metainfDir = new File( context.getWebappDirectory(), META_INF_PATH );
+        metainfDir.mkdirs();
+
         handleWebResources( context );
 
         handeWebAppSourceDirectory( context );
 
+        handleDeploymentDescriptors( context, webinfDir, metainfDir );
+
         handleClassesDirectory( context );
 
         handleArtifacts( context );
@@ -69,7 +86,7 @@
             }
 
             // Make sure that the resource directory is not the same as the webappDirectory
-            if ( !resource.getDirectory().equals( context.getWebAppDirectory().getPath() ) )
+            if ( !resource.getDirectory().equals( context.getWebappDirectory().getPath() ) )
             {
 
                 try
@@ -93,22 +110,25 @@
     protected void handeWebAppSourceDirectory( WarPackagingContext context )
         throws MojoExecutionException
     {
-
-        // Make sure that the resource directory is not the same as the webappDirectory
-        if ( !context.getWebAppSourceDirectory().getAbsolutePath().equals( context.getWebAppDirectory().getPath() ) )
+        if ( !context.getWebappSourceDirectory().exists() )
+        {
+            context.getLog().debug( "webapp sources directory does not exist - skipping." );
+        }
+        else
+        if ( !context.getWebappSourceDirectory().getAbsolutePath().equals( context.getWebappDirectory().getPath() ) )
         {
-            final PathSet sources = getFilesToIncludes( context.getWebAppSourceDirectory(),
-                                                        context.getWebAppSourceIncludes(),
-                                                        context.getWebAppSourceExcludes() );
+            final PathSet sources = getFilesToIncludes( context.getWebappSourceDirectory(),
+                                                        context.getWebappSourceIncludes(),
+                                                        context.getWebappSourceExcludes() );
 
             try
             {
-                copyFiles( context, context.getWebAppSourceDirectory(), sources );
+                copyFiles( context, context.getWebappSourceDirectory(), sources );
             }
             catch ( IOException e )
             {
                 throw new MojoExecutionException(
-                    "Could not copy webapp sources[" + context.getWebAppDirectory().getAbsolutePath() + "]", e );
+                    "Could not copy webapp sources[" + context.getWebappDirectory().getAbsolutePath() + "]", e );
             }
         }
     }
@@ -139,6 +159,48 @@
         task.performPackaging( context );
     }
 
+    /**
+     * Handles the deployment descriptors, if specified. Note that the behavior
+     * here is slightly different since the customized entry always win, even if
+     * an overlay has already packaged a web.xml previously.
+     *
+     * @param context    the packaging context
+     * @param webinfDir  the web-inf directory
+     * @param metainfDir the meta-inf directory
+     * @throws MojoFailureException   if the web.xml is specified but does not exist
+     * @throws MojoExecutionException if an error occured while copying the descriptors
+     */
+    protected void handleDeploymentDescriptors( WarPackagingContext context, File webinfDir, File metainfDir )
+        throws MojoFailureException, MojoExecutionException
+    {
+        try
+        {
+            if ( webXml != null && StringUtils.isNotEmpty( webXml.getName() ) )
+            {
+                if ( !webXml.exists() )
+                {
+                    throw new MojoFailureException( "The specified web.xml file '" + webXml + "' does not exist" );
+                }
+
+                //rename to web.xml
+                //TODO refactor this
+                copyFileIfModified( webXml, new File( webinfDir, "web.xml" ) );
+                context.getProtectedFiles().add( WEB_INF_PATH + "/web.xml" );
+            }
+
+            if ( containerConfigXML != null && StringUtils.isNotEmpty( containerConfigXML.getName() ) )
+            {
+                String xmlFileName = containerConfigXML.getName();
+                copyFileIfModified( containerConfigXML, new File( metainfDir, xmlFileName ) );
+                context.getProtectedFiles().add( META_INF_PATH + "/" + xmlFileName );
+            }
+        }
+        catch ( IOException e )
+        {
+            throw new MojoExecutionException( "Failed to copy deployment descriptor", e );
+        }
+    }
+
 
     /**
      * Copies webapp webResources from the specified directory.
@@ -151,14 +213,14 @@
     public void copyResources( WarPackagingContext context, Resource resource )
         throws IOException, MojoExecutionException
     {
-        if ( !context.getWebAppDirectory().exists() )
+        if ( !context.getWebappDirectory().exists() )
         {
-            context.getLogger().warn( "Not copying webapp webResources[" + resource.getDirectory() +
-                "]: webapp directory[" + context.getWebAppDirectory().getAbsolutePath() + "] does not exist!" );
+            context.getLog().warn( "Not copying webapp webResources[" + resource.getDirectory() +
+                "]: webapp directory[" + context.getWebappDirectory().getAbsolutePath() + "] does not exist!" );
         }
 
-        context.getLogger().info( "Copy webapp webResources[" + resource.getDirectory() + "] to[" +
-            context.getWebAppDirectory().getAbsolutePath() + "]" );
+        context.getLog().info( "Copy webapp webResources[" + resource.getDirectory() + "] to[" +
+            context.getWebappDirectory().getAbsolutePath() + "]" );
         String[] fileNames = getFilesToCopy( resource );
         for ( int i = 0; i < fileNames.length; i++ )
         {

Modified: maven/plugins/branches/MWAR-97-2/src/test/java/org/apache/maven/plugin/war/WarExplodedMojoTest.java
URL: http://svn.apache.org/viewvc/maven/plugins/branches/MWAR-97-2/src/test/java/org/apache/maven/plugin/war/WarExplodedMojoTest.java?view=diff&rev=557155&r1=557154&r2=557155
==============================================================================
--- maven/plugins/branches/MWAR-97-2/src/test/java/org/apache/maven/plugin/war/WarExplodedMojoTest.java (original)
+++ maven/plugins/branches/MWAR-97-2/src/test/java/org/apache/maven/plugin/war/WarExplodedMojoTest.java Tue Jul 17 22:34:01 2007
@@ -249,10 +249,9 @@
         setVariableValueToObject( mojo, "workDirectory", workDirectory );
         mojo.execute();
 
-        // validate operation
+        // validate operation - META-INF is automatically excluded so remove the file from the list
         File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
         File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
-        File expectedManifestFile = new File( webAppDirectory, "META-INF/MANIFEST.MF" );
         File expectedWEBXMLFile = new File( webAppDirectory, "WEB-INF/web.xml" );
         File expectedWARFile = new File( webAppDirectory, "/org/sample/company/test.jsp" );
 
@@ -260,13 +259,11 @@
         assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
         // check simple.war in the unit test dir under resources to verify the list of files
         assertTrue( "web xml not found: " + expectedWEBXMLFile.toString(), expectedWEBXMLFile.exists() );
-        assertTrue( "manifest file not found: " + expectedManifestFile.toString(), expectedManifestFile.exists() );
         assertTrue( "war file not found: " + expectedWARFile.toString(), expectedWARFile.exists() );
 
         // house keeping
         expectedWebSourceFile.delete();
         expectedWebSource2File.delete();
-        expectedManifestFile.delete();
         expectedWEBXMLFile.delete();
         expectedWARFile.delete();
     }
@@ -283,7 +280,7 @@
 
         String testId = "testExplodedWarMergeWarLocalFileOverride";
         File webAppDirectory = new File( getTestDirectory(), testId );
-        File webAppSource = getWebAppSource( testId);
+        File webAppSource = getWebAppSource( testId );
         File simpleJSP = new File( webAppSource, "org/sample/company/test.jsp" );
         createFile( simpleJSP );
 
@@ -335,7 +332,7 @@
         File webAppDirectory = new File( getTestDirectory(), testId );
         FileUtils.deleteDirectory( webAppDirectory );
 
-        File webAppSource = getWebAppSource( testId);
+        File webAppSource = getWebAppSource( testId );
 
         File workDirectory = new File( getTestDirectory(), "/war/work-" + testId );
         createDir( workDirectory );
@@ -1074,8 +1071,6 @@
     }
 
     /* --------------------- 2.1 Overlay tests ----------------------------------- */
-
-    
 
     /*---------------------------*/
 

Modified: maven/plugins/branches/MWAR-97-2/src/test/java/org/apache/maven/plugin/war/stub/IncludeExcludeWarArtifactStub.java
URL: http://svn.apache.org/viewvc/maven/plugins/branches/MWAR-97-2/src/test/java/org/apache/maven/plugin/war/stub/IncludeExcludeWarArtifactStub.java?view=diff&rev=557155&r1=557154&r2=557155
==============================================================================
--- maven/plugins/branches/MWAR-97-2/src/test/java/org/apache/maven/plugin/war/stub/IncludeExcludeWarArtifactStub.java (original)
+++ maven/plugins/branches/MWAR-97-2/src/test/java/org/apache/maven/plugin/war/stub/IncludeExcludeWarArtifactStub.java Tue Jul 17 22:34:01 2007
@@ -27,6 +27,7 @@
     public IncludeExcludeWarArtifactStub( String id )
     {
         super( id );
+        setGroupId( "wartests" );
     }
 
     public String getArtifactId()

Modified: maven/plugins/branches/MWAR-97-2/src/test/java/org/apache/maven/plugin/war/stub/WarArtifactStub.java
URL: http://svn.apache.org/viewvc/maven/plugins/branches/MWAR-97-2/src/test/java/org/apache/maven/plugin/war/stub/WarArtifactStub.java?view=diff&rev=557155&r1=557154&r2=557155
==============================================================================
--- maven/plugins/branches/MWAR-97-2/src/test/java/org/apache/maven/plugin/war/stub/WarArtifactStub.java (original)
+++ maven/plugins/branches/MWAR-97-2/src/test/java/org/apache/maven/plugin/war/stub/WarArtifactStub.java Tue Jul 17 22:34:01 2007
@@ -29,6 +29,7 @@
 {
 
     private String groupId;
+
     private String artifactId;
 
     private File file;
@@ -63,7 +64,14 @@
 
     public String getGroupId()
     {
-        return groupId;
+        if ( groupId == null )
+        {
+            return "wartests";
+        }
+        else
+        {
+            return groupId;
+        }
     }
 
     public void setGroupId( String groupId )

Modified: maven/plugins/branches/MWAR-97-2/src/test/java/org/apache/maven/plugin/war/stub/WarOverlayStub.java
URL: http://svn.apache.org/viewvc/maven/plugins/branches/MWAR-97-2/src/test/java/org/apache/maven/plugin/war/stub/WarOverlayStub.java?view=diff&rev=557155&r1=557154&r2=557155
==============================================================================
--- maven/plugins/branches/MWAR-97-2/src/test/java/org/apache/maven/plugin/war/stub/WarOverlayStub.java (original)
+++ maven/plugins/branches/MWAR-97-2/src/test/java/org/apache/maven/plugin/war/stub/WarOverlayStub.java Tue Jul 17 22:34:01 2007
@@ -44,6 +44,11 @@
         return artifactId;
     }
 
+    public String getGroupId()
+    {
+        return "wartests";
+    }
+
     public File getFile()
     {
         return file;