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/30 19:38:44 UTC

svn commit: r561059 - 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/ main/java/org/apache/maven/plugin/war/util/ test/java...

Author: snicoll
Date: Mon Jul 30 10:38:43 2007
New Revision: 561059

URL: http://svn.apache.org/viewvc?view=rev&rev=561059
Log:
- default includes/excludes are now applied by the overlay manager
- files are registered per source in a cache
- files are only modified if necessary

Added:
    maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/util/WebappStructure.java
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.java
    maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/overlay/DefaultOverlay.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/WarProjectPackagingTask.java
    maven/plugins/branches/MWAR-97-2/src/test/java/org/apache/maven/plugin/war/overlay/OverlayManagerTest.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=561059&r1=561058&r2=561059
==============================================================================
--- 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 Mon Jul 30 10:38:43 2007
@@ -34,7 +34,7 @@
 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.plugin.war.util.WebappStructure;
 import org.apache.maven.project.MavenProject;
 import org.codehaus.plexus.archiver.ArchiverException;
 import org.codehaus.plexus.archiver.UnArchiver;
@@ -166,6 +166,15 @@
     private String outputFileNameMapping;
 
     /**
+     * The file containing the webapp structure cache.
+     *
+     * @paramenter expression="${project.build.directory}/.webapp-cache.xml"
+     * @required
+     * @since 2.1
+     */
+    private File webappStructure;
+
+    /**
      * To look up Archiver/UnArchiver implementations
      *
      * @parameter expression="${component.org.codehaus.plexus.archiver.manager.ArchiverManager}"
@@ -206,7 +215,7 @@
      *
      * @parameter
      */
-    private String dependentWarIncludes = "**";
+    private String dependentWarIncludes = "**/**";
 
     /**
      * The comma separated list of tokens to exclude when doing
@@ -214,7 +223,7 @@
      *
      * @parameter
      */
-    private String dependentWarExcludes;
+    private String dependentWarExcludes = "META-INF/**";
 
     /**
      * The overlays to apply.
@@ -561,17 +570,28 @@
         throws MojoExecutionException, MojoFailureException, IOException
     {
 
+        WebappStructure cache = new WebappStructure();
+        if ( webappStructure != null && webappStructure.exists() )
+        {
+            // TODO: LOAD the webapp structure thingy using xstream
+        }
+
         final long startTime = System.currentTimeMillis();
         getLog().info( "Assembling webapp[" + project.getArtifactId() + "] in [" + webappDirectory + "]" );
 
-        final List packagingTasks = getPackagingTasks();
+        final OverlayManager overlayManager =
+            new OverlayManager( overlays, project, dependentWarIncludes, dependentWarExcludes );
+        final List packagingTasks = getPackagingTasks( overlayManager );
+        final WarPackagingContext context = new DefaultWarPackagingContext( webappDirectory, cache, overlayManager );
         final Iterator it = packagingTasks.iterator();
         while ( it.hasNext() )
         {
             WarPackagingTask warPackagingTask = (WarPackagingTask) it.next();
-            warPackagingTask.performPackaging( new DefaultWarPackagingContext( webappDirectory ) );
+            warPackagingTask.performPackaging( context );
         }
         getLog().info( "Webapp assembled in[" + ( System.currentTimeMillis() - startTime ) + " msecs]" );
+
+        //TODO save the cache
     }
 
 
@@ -579,14 +599,14 @@
      * Returns a <tt>List</tt> of the {@link org.apache.maven.plugin.war.packaging.WarPackagingTask}
      * instances to invoke to perform the packaging.
      *
+     * @param overlayManager the overlay manager
      * @return the list of packaging tasks
      * @throws MojoExecutionException if the packaging tasks could not be built
      */
-    private List getPackagingTasks()
+    private List getPackagingTasks( OverlayManager overlayManager )
         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() )
@@ -1189,14 +1209,31 @@
         implements WarPackagingContext
     {
 
-        private final PathSet pathSet = new PathSet();
+
+        private final WebappStructure webappStructure;
 
         private final File webappDirectory;
 
+        private final OverlayManager overlayManager;
+
 
-        public DefaultWarPackagingContext( File webappDirectory )
+        public DefaultWarPackagingContext( File webappDirectory, final WebappStructure webappStructure,
+                                           final OverlayManager overlayManager )
         {
             this.webappDirectory = webappDirectory;
+            this.webappStructure = webappStructure;
+            this.overlayManager = overlayManager;
+
+            // This is kinda stupid but if we loop over the current overlays and we request the path structure
+            // it will register it. This will avoid wrong warning messages in a later phase
+            final Iterator it = overlayManager.getOverlayIds().iterator();
+            while ( it.hasNext() )
+            {
+                String overlayId = (String) it.next();
+                webappStructure.getStructure( overlayId );
+            }
+
+
         }
 
 
@@ -1265,11 +1302,6 @@
             return jarArchiver;
         }
 
-        public PathSet getProtectedFiles()
-        {
-            return pathSet;
-        }
-
         public List getFilters()
         {
             return filters;
@@ -1280,6 +1312,16 @@
         {
             //TODO refactor this
             return getBuildFilterProperties();
+        }
+
+        public WebappStructure getWebappStructure()
+        {
+            return webappStructure;
+        }
+
+        public List getOwnerIds()
+        {
+            return overlayManager.getOverlayIds();
         }
     }
 }

Modified: maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/Overlay.java
URL: http://svn.apache.org/viewvc/maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/Overlay.java?view=diff&rev=561059&r1=561058&r2=561059
==============================================================================
--- maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/Overlay.java (original)
+++ maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/Overlay.java Mon Jul 30 10:38:43 2007
@@ -22,6 +22,7 @@
 import org.apache.maven.artifact.Artifact;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -42,6 +43,7 @@
 {
 
     public static final String[] DEFAULT_INCLUDES = new String[]{"**/**"};
+
     public static final String[] DEFAULT_EXCLUDES = new String[]{"META-INF/**"};
 
     private static Overlay currentProjectInstance;
@@ -233,7 +235,7 @@
 
         Overlay overlay = (Overlay) o;
 
-        if ( excludes != null ? !excludes.equals( overlay.excludes ) : overlay.excludes != null )
+        if ( excludes != null ? !Arrays.equals( excludes, overlay.excludes ) : overlay.excludes != null )
         {
             return false;
         }
@@ -241,7 +243,7 @@
         {
             return false;
         }
-        if ( includes != null ? !includes.equals( overlay.includes ) : overlay.includes != null )
+        if ( includes != null ? !Arrays.equals( includes, overlay.includes ) : overlay.includes != null )
         {
             return false;
         }
@@ -263,7 +265,7 @@
         final List result = new ArrayList();
         if ( s == null )
         {
-            return (String[]) result.toArray(new String[result.size()]);
+            return (String[]) result.toArray( new String[result.size()] );
         }
         else
         {
@@ -273,7 +275,7 @@
                 String token = tokens[i];
                 result.add( token.trim() );
             }
-            return (String[]) result.toArray(new String[result.size()]);
+            return (String[]) result.toArray( new String[result.size()] );
         }
     }
 }

Modified: maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/overlay/DefaultOverlay.java
URL: http://svn.apache.org/viewvc/maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/overlay/DefaultOverlay.java?view=diff&rev=561059&r1=561058&r2=561059
==============================================================================
--- maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/overlay/DefaultOverlay.java (original)
+++ maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/overlay/DefaultOverlay.java Mon Jul 30 10:38:43 2007
@@ -44,4 +44,18 @@
         setClassifier( a.getClassifier() );
         setArtifact( a );
     }
+
+    /**
+     * Creates an overlay for the specified artifact.
+     *
+     * @param a        the artifact
+     * @param includes the includes to use
+     * @param excludes the excludes to use
+     */
+    public DefaultOverlay( Artifact a, String includes, String excludes )
+    {
+        this( a );
+        setIncludes( includes );
+        setExcludes( excludes );
+    }
 }

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=561059&r1=561058&r2=561059
==============================================================================
--- 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 Mon Jul 30 10:38:43 2007
@@ -48,12 +48,14 @@
      * Note that the list is potentially updated by the
      * manager so a new list is created based on the overlays.
      *
-     * @param overlays the overlays
-     * @param project  the maven project
+     * @param overlays        the overlays
+     * @param project         the maven project
+     * @param defaultIncludes the default includes to use
+     * @param defaultExcludes the default excludes to use
      * @throws InvalidOverlayConfigurationException
      *          if the config is invalid
      */
-    public OverlayManager( List overlays, MavenProject project )
+    public OverlayManager( List overlays, MavenProject project, String defaultIncludes, String defaultExcludes )
         throws InvalidOverlayConfigurationException
     {
         this.overlays = new ArrayList();
@@ -66,7 +68,7 @@
         this.warArtifacts = getWarOverlaysAsArtifacts();
 
         // Initialize
-        initialize();
+        initialize( defaultIncludes, defaultExcludes );
 
     }
 
@@ -91,12 +93,32 @@
     }
 
     /**
+     * Returns the id of the resolved overlays.
+     *
+     * @return the overlay ids
+     */
+    public List getOverlayIds()
+    {
+        final Iterator it = overlays.iterator();
+        final List result = new ArrayList();
+        while ( it.hasNext() )
+        {
+            Overlay overlay = (Overlay) it.next();
+            result.add( overlay.getId() );
+        }
+        return result;
+
+    }
+
+    /**
      * Intializes the manager and validates the overlays configuration.
      *
-     * @throws org.apache.maven.plugin.war.overlay.InvalidOverlayConfigurationException
+     * @param defaultIncludes the default includes to use
+     * @param defaultExcludes the default excludes to use
+     * @throws InvalidOverlayConfigurationException
      *          if the configuration is invalid
      */
-    void initialize()
+    void initialize( String defaultIncludes, String defaultExcludes )
         throws InvalidOverlayConfigurationException
     {
 
@@ -111,6 +133,14 @@
             {
                 throw new InvalidOverlayConfigurationException( "overlay could not be null." );
             }
+            // default includes/excludes - only if the overlay uses the default settings
+            if ( Overlay.DEFAULT_INCLUDES.equals( overlay.getIncludes() ) &&
+                Overlay.DEFAULT_EXCLUDES.equals( overlay.getExcludes() ) )
+            {
+                overlay.setIncludes( defaultIncludes );
+                overlay.setExcludes( defaultExcludes );
+            }
+
             final Artifact artifact = getAssociatedArtifact( overlay );
             if ( artifact != null )
             {
@@ -128,7 +158,7 @@
             {
                 // Add a default overlay for the given artifact which will be applied after
                 // the ones that have been configured
-                overlays.add( new DefaultOverlay( artifact ) );
+                overlays.add( new DefaultOverlay( artifact, defaultIncludes, defaultExcludes ) );
             }
         }
 
@@ -145,21 +175,6 @@
         overlays.add( 0, Overlay.currentProjectInstance() );
     }
 
-
-    void initializeOverlay( final Overlay overlay )
-        throws InvalidOverlayConfigurationException
-    {
-        if ( overlay == null )
-        {
-            throw new InvalidOverlayConfigurationException( "overlay could not be null." );
-        }
-        final Artifact artifact = getAssociatedArtifact( overlay );
-        overlay.setArtifact( artifact );
-
-
-    }
-
-
     /**
      * Returns the Artifact associated to the specified overlay.
      * <p/>
@@ -180,6 +195,7 @@
             return null;
         }
 
+        // TODO this might not always return the artifacts in the right order. Hence some tests might fail
         final Iterator it = warArtifacts.iterator();
         while ( it.hasNext() )
         {

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=561059&r1=561058&r2=561059
==============================================================================
--- 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 Mon Jul 30 10:38:43 2007
@@ -70,13 +70,14 @@
      * directory the files should be copied. Use <tt>null</tt> to copy the files with
      * the same structure
      *
+     * @param sourceId       the source id
      * @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( String sourceId, WarPackagingContext context, File sourceBaseDir, PathSet sourceFilesSet,
                               String targetPrefix )
         throws IOException
     {
@@ -95,7 +96,7 @@
                 destinationFileName = targetPrefix + fileToCopyName;
             }
 
-            copyFile( context, sourceFile, destinationFileName );
+            copyFile( sourceId, context, sourceFile, destinationFileName );
         }
     }
 
@@ -106,15 +107,16 @@
      * 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 sourceId       the source id
      * @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 )
+    protected void copyFiles( String sourceId, WarPackagingContext context, File sourceBaseDir, PathSet sourceFilesSet )
         throws IOException
     {
-        copyFiles( context, sourceBaseDir, sourceFilesSet, null );
+        copyFiles( sourceId, context, sourceBaseDir, sourceFilesSet, null );
     }
 
     /**
@@ -123,30 +125,48 @@
      * The <tt>targetFileName</tt> is the relative path according to the root of
      * the generated web application.
      *
+     * @param sourceId       the source id
      * @param context        the context to use
      * @param file           the file to copy
      * @param targetFilename the relative path according to the root of the webapp
      * @return true if the file has been copied, false otherwise
      * @throws IOException if an error occured while copying
      */
-    protected boolean copyFile( WarPackagingContext context, File file, String targetFilename )
+    protected boolean copyFile( String sourceId, WarPackagingContext context, File file, String targetFilename )
         throws IOException
     {
-        if ( !context.getProtectedFiles().contains( targetFilename ) )
-        {
-            File targetFile = new File( context.getWebappDirectory(), targetFilename );
-            copyFile( file, targetFile );
 
-            // Add the file to the protected list
-            context.getProtectedFiles().add( targetFilename );
-            context.getLog().debug( " + " + targetFilename + " has been copied." );
-            return true;
+        File targetFile = new File( context.getWebappDirectory(), targetFilename );
+        // Check if the file already belongs to *this* source. If so only copy if it has changed. If it does not
+        // belong to this source, check if the source is still registered in the project. If so, skip the file,
+        // if not overwrite the file and issue a warning
+        if ( context.getWebappStructure().isRegistered( targetFilename ) )
+        {
+            final String owner = context.getWebappStructure().getOwner( targetFilename );
+            if ( sourceId.equals( owner ) )
+            {
+                return copyFile( context, file, targetFile, targetFilename, true );
+            }
+            else if ( context.getOwnerIds().contains( owner ) )
+            {
+                context.getLog().info(
+                    " - " + targetFilename + " wasn't copied because it has already been packaged." );
+                return false;
+            }
+            else
+            {
+                context.getLog().warn( "Overlay with id[" + owner +
+                    "] does not exist anymore in the current project. " +
+                    "It is recommended to invoke clean if the dependencies of the project changed." );
+                return copyFile( context, file, targetFile, targetFilename, false );
+            }
         }
         else
         {
-            context.getLog().debug( " - " + targetFilename + " wasn't copied because it has already been packaged." );
-            return false;
+            context.getWebappStructure().registerFile( sourceId, targetFilename );
+            return copyFile( context, file, targetFile, targetFilename, false );
         }
+
     }
 
     /**
@@ -156,6 +176,7 @@
      * The <tt>targetFileName</tt> is the relative path according to the root of
      * the generated web application.
      *
+     * @param sourceId       the source id
      * @param context        the context to use
      * @param file           the file to copy
      * @param targetFilename the relative path according to the root of the webapp
@@ -163,11 +184,11 @@
      * @throws IOException            if an error occured while copying
      * @throws MojoExecutionException if an error occured while retrieving the filter properties
      */
-    protected boolean copyFilteredFile( WarPackagingContext context, File file, String targetFilename )
+    protected boolean copyFilteredFile( String sourceId, WarPackagingContext context, File file, String targetFilename )
         throws IOException, MojoExecutionException
     {
 
-        if ( !context.getProtectedFiles().contains( targetFilename ) )
+        if ( context.getWebappStructure().registerFile( sourceId, targetFilename ) )
         {
             final File targetFile = new File( context.getWebappDirectory(), targetFilename );
             // buffer so it isn't reading a byte at a time!
@@ -196,7 +217,6 @@
                 IOUtil.close( fileWriter );
             }
             // Add the file to the protected list
-            context.getProtectedFiles().add( targetFilename );
             context.getLog().debug( " + " + targetFilename + " has been copied." );
             return true;
         }
@@ -248,23 +268,37 @@
 
     /**
      * Copy file from source to destination. 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.
+     * will be created if they don't already exist. if the <code>onlyIfModified</code> flag
+     * is <tt>false</tt>, <code>destination</code> will be overwritten if it already exists. If the
+     * flag is <tt>true</tt> destination will be overwritten if it's not up to date.
      * <p/>
-     * TODO: Remove this method when Maven moves to plexus-util version 1.4
      *
-     * @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
+     * @param context        the packaging context
+     * @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).
+     * @param targetFilename the relative path of the file from the webapp root directory
+     * @param onlyIfModified if true, copy the file only if the source has changed, always copy otherwise
+     * @return true if the file has been copied/updated, false otherwise
+     * @throws IOException if <code>source</code> does not exist, <code>destination</code> cannot
+     *                     be written to, or an IO error occurs during copying
      */
-    private void copyFile( File source, File destination )
+    private boolean copyFile( WarPackagingContext context, File source, File destination, String targetFilename,
+                              boolean onlyIfModified )
         throws IOException
     {
-        FileUtils.copyFile( source.getCanonicalFile(), destination );
-        // preserve timestamp
-        destination.setLastModified( source.lastModified() );
+        if ( onlyIfModified && destination.lastModified() >= source.lastModified() )
+        {
+            context.getLog().info( " * " + targetFilename + " is up to date." );
+            return false;
+        }
+        else
+        {
+            FileUtils.copyFile( source.getCanonicalFile(), destination );
+            // preserve timestamp
+            destination.setLastModified( source.lastModified() );
+            context.getLog().info( " + " + targetFilename + " has been copied." );
+            return true;
+        }
     }
 
 
@@ -275,7 +309,6 @@
      *
      * @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

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=561059&r1=561058&r2=561059
==============================================================================
--- 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 Mon Jul 30 10:38:43 2007
@@ -3,6 +3,7 @@
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
 import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.war.Overlay;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -25,10 +26,13 @@
 
     private final Set artifacts;
 
+    private final String id;
+
 
     public ArtifactsPackagingTask( Set artifacts )
     {
         this.artifacts = artifacts;
+        this.id = Overlay.currentProjectInstance().getId();
     }
 
 
@@ -60,21 +64,21 @@
                     String type = artifact.getType();
                     if ( "tld".equals( type ) )
                     {
-                        copyFile( context, artifact.getFile(), TLD_PATH + targetFileName );
+                        copyFile( id, context, artifact.getFile(), TLD_PATH + targetFileName );
                     }
                     else if ( "aar".equals( type ) )
                     {
-                        copyFile( context, artifact.getFile(), SERVICES_PATH + targetFileName );
+                        copyFile( id, context, artifact.getFile(), SERVICES_PATH + targetFileName );
                     }
                     else if ( "jar".equals( type ) || "ejb".equals( type ) || "ejb-client".equals( type ) ||
                         "test-jar".equals( type ) )
                     {
-                        copyFile( context, artifact.getFile(), LIB_PATH + targetFileName );
+                        copyFile( id, context, artifact.getFile(), LIB_PATH + targetFileName );
                     }
                     else if ( "par".equals( type ) )
                     {
                         targetFileName = targetFileName.substring( 0, targetFileName.lastIndexOf( '.' ) ) + ".jar";
-                        copyFile( context, artifact.getFile(), LIB_PATH + targetFileName );
+                        copyFile( id, context, artifact.getFile(), LIB_PATH + targetFileName );
                     }
                     else
                     {

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=561059&r1=561058&r2=561059
==============================================================================
--- 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 Mon Jul 30 10:38:43 2007
@@ -3,6 +3,7 @@
 import org.apache.maven.archiver.MavenArchiver;
 import org.apache.maven.artifact.DependencyResolutionRequiredException;
 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.archiver.ArchiverException;
 import org.codehaus.plexus.archiver.jar.ManifestException;
@@ -43,7 +44,8 @@
                 final PathSet sources = getFilesToIncludes( context.getClassesDirectory(), null, null );
                 try
                 {
-                    copyFiles( context, context.getClassesDirectory(), sources, CLASSES_PATH );
+                    copyFiles( Overlay.currentProjectInstance().getId(), context, context.getClassesDirectory(),
+                               sources, CLASSES_PATH );
                 }
                 catch ( IOException e )
                 {
@@ -61,14 +63,9 @@
         final String archiveName = context.getProject().getBuild().getFinalName() + ".jar";
         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.getLog().warn(
-                "Could not generate archive classes file[" + targetFilename + "] has already been copied." );
-        }
-        else
+        if ( context.getWebappStructure().registerFile( Overlay.currentProjectInstance().getId(), targetFilename ) )
         {
+
             final File libDirectory = new File( context.getWebappDirectory(), LIB_PATH );
             final File jarFile = new File( libDirectory, archiveName );
 
@@ -97,6 +94,11 @@
             {
                 throw new MojoExecutionException( "Could not create classes archive", e );
             }
+        }
+        else
+        {
+            context.getLog().warn(
+                "Could not generate archive classes file[" + targetFilename + "] has already been copied." );
         }
     }
 }

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=561059&r1=561058&r2=561059
==============================================================================
--- 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 Mon Jul 30 10:38:43 2007
@@ -72,7 +72,7 @@
                 final PathSet includes = getFilesToIncludes( tmpDir, overlay.getIncludes(), overlay.getExcludes() );
 
                 // Copy
-                copyFiles( context, tmpDir, includes );
+                copyFiles( overlay.getId(), context, tmpDir, includes );
             }
             catch ( IOException e )
             {

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=561059&r1=561058&r2=561059
==============================================================================
--- 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 Mon Jul 30 10:38:43 2007
@@ -22,7 +22,7 @@
 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.plugin.war.util.WebappStructure;
 import org.apache.maven.project.MavenProject;
 import org.codehaus.plexus.archiver.jar.JarArchiver;
 import org.codehaus.plexus.archiver.manager.ArchiverManager;
@@ -126,18 +126,6 @@
     JarArchiver getJarArchiver();
 
     /**
-     * Returns the list of files that have already been copied during the
-     * packaging tasks.
-     * <p/>
-     * Tasks are responsible to update this file to make sure that the
-     * overwriting strategy is applied properly.
-     *
-     * @return the list of files that have already been copied
-     */
-    PathSet getProtectedFiles();
-
-
-    /**
      * Returns the output file name mapping to use, if any. Returns <tt>null</tt>
      * if no file name mapping is set.
      *
@@ -163,5 +151,21 @@
     Map getFilterProperties()
         throws MojoExecutionException;
 
+    /**
+     * Returns the {@link WebappStructure}.
+     *
+     * @return the webapp structure
+     */
+    WebappStructure getWebappStructure();
+
+    /**
+     * Returns the list of registered overlays for this session. This list might
+     * differ from the one returned by the cache; in this case, it means that the
+     * project's configuration has changed. The plugin will handle thos cases nicely
+     * but it would be better in general to invoke the clean goal.
+     *
+     * @return the list of registered overlays, including the current project
+     */
+    List getOwnerIds();
 
 }

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=561059&r1=561058&r2=561059
==============================================================================
--- 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 Mon Jul 30 10:38:43 2007
@@ -3,6 +3,7 @@
 import org.apache.maven.model.Resource;
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.war.Overlay;
 import org.apache.maven.plugin.war.util.PathSet;
 import org.codehaus.plexus.util.DirectoryScanner;
 import org.codehaus.plexus.util.StringUtils;
@@ -31,6 +32,8 @@
 
     private final File containerConfigXML;
 
+    private final String id;
+
 
     public WarProjectPackagingTask( Resource[] webResources, File webXml, File containerConfigXml )
     {
@@ -44,6 +47,7 @@
         }
         this.webXml = webXml;
         this.containerConfigXML = containerConfigXml;
+        this.id = Overlay.currentProjectInstance().getId();
     }
 
     public void performPackaging( WarPackagingContext context )
@@ -123,7 +127,7 @@
 
             try
             {
-                copyFiles( context, context.getWebappSourceDirectory(), sources );
+                copyFiles( id, context, context.getWebappSourceDirectory(), sources );
             }
             catch ( IOException e )
             {
@@ -185,14 +189,14 @@
                 //rename to web.xml
                 //TODO refactor this
                 copyFileIfModified( webXml, new File( webinfDir, "web.xml" ) );
-                context.getProtectedFiles().add( WEB_INF_PATH + "/web.xml" );
+                context.getWebappStructure().getFullStructure().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 );
+                context.getWebappStructure().getFullStructure().add( META_INF_PATH + "/" + xmlFileName );
             }
         }
         catch ( IOException e )
@@ -232,11 +236,11 @@
             }
             if ( resource.isFiltering() )
             {
-                copyFilteredFile( context, new File( resource.getDirectory(), fileNames[i] ), targetFileName );
+                copyFilteredFile( id, context, new File( resource.getDirectory(), fileNames[i] ), targetFileName );
             }
             else
             {
-                copyFile( context, new File( resource.getDirectory(), fileNames[i] ), targetFileName );
+                copyFile( id, context, new File( resource.getDirectory(), fileNames[i] ), targetFileName );
             }
         }
     }

Added: maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/util/WebappStructure.java
URL: http://svn.apache.org/viewvc/maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/util/WebappStructure.java?view=auto&rev=561059
==============================================================================
--- maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/util/WebappStructure.java (added)
+++ maven/plugins/branches/MWAR-97-2/src/main/java/org/apache/maven/plugin/war/util/WebappStructure.java Mon Jul 30 10:38:43 2007
@@ -0,0 +1,142 @@
+package org.apache.maven.plugin.war.util;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Represents the structure of a web application composed of multiple
+ * overlays. Each overlay is registered within this structure with the
+ * set of files it holds.
+ * <p/>
+ * Note that this structure is persisted to disk at each invocation to
+ * store wich owner holds which path (file).
+ *
+ * @author Stephane Nicoll
+ */
+public class WebappStructure
+{
+
+    private final Map registeredFiles;
+
+    private final transient PathSet allFiles;
+
+    /**
+     * Creates a new instance.
+     */
+    public WebappStructure()
+    {
+        this.registeredFiles = new HashMap();
+        this.allFiles = new PathSet();
+    }
+
+    /**
+     * Specify if the specified <tt>path</tt> is registered or not.
+     *
+     * @param path the relative path from the webapp root directory
+     * @return true if the path is registered, false otherwise
+     */
+    public boolean isRegistered( String path )
+    {
+        return getFullStructure().contains( path );
+
+    }
+
+    /**
+     * Registers the specified path for the specified owner. Returns <tt>true</tt>
+     * if the path is not already registered, <tt>false</tt> otherwise.
+     *
+     * @param id   the owner of the path
+     * @param path the relative path from the webapp root directory
+     * @return true if the file was registered successfully
+     */
+    public boolean registerFile( String id, String path )
+    {
+        if ( !isRegistered( path ) )
+        {
+            getFullStructure().add( path );
+            getStructure( id ).add( path );
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+    /**
+     * Returns the owner of the specified <tt>path</tt>. If the file is not
+     * registered, returns <tt>null</tt>
+     *
+     * @param path the relative path from the webapp root directory
+     * @return the owner or <tt>null</tt>.
+     */
+    public String getOwner( String path )
+    {
+        if ( !isRegistered( path ) )
+        {
+            return null;
+        }
+        else
+        {
+            final Iterator it = registeredFiles.keySet().iterator();
+            while ( it.hasNext() )
+            {
+                final String owner = (String) it.next();
+                final PathSet structure = getStructure( owner );
+                if ( structure.contains( path ) )
+                {
+                    return owner;
+                }
+
+            }
+            throw new IllegalStateException(
+                "Should not happen, path[" + path + "] is flagged as being registered but was not found." );
+        }
+
+    }
+
+    /**
+     * Returns the owners. Note that this the returned {@link Set} may be
+     * inconsistent since it represents a persistent cache accross multiple
+     * invocations.
+     * <p/>
+     * For instance, if an overlay was removed in this execution, it will be
+     * still be there till the cache is cleaned. This happens when the clean
+     * mojo is invoked.
+     *
+     * @return the list of owners
+     */
+    public Set getOwners()
+    {
+        return registeredFiles.keySet();
+    }
+
+    /**
+     * Returns all paths that have been registered so far.
+     *
+     * @return all registered path
+     */
+    public PathSet getFullStructure()
+    {
+        return allFiles;
+    }
+
+    /**
+     * Returns the list of registered files for the specified owner.
+     *
+     * @param id the owner
+     * @return the list of files registered for that owner
+     */
+    public PathSet getStructure( String id )
+    {
+        PathSet pathSet = (PathSet) registeredFiles.get( id );
+        if ( pathSet == null )
+        {
+            pathSet = new PathSet();
+            registeredFiles.put( id, pathSet );
+        }
+        return pathSet;
+    }
+}

Modified: maven/plugins/branches/MWAR-97-2/src/test/java/org/apache/maven/plugin/war/overlay/OverlayManagerTest.java
URL: http://svn.apache.org/viewvc/maven/plugins/branches/MWAR-97-2/src/test/java/org/apache/maven/plugin/war/overlay/OverlayManagerTest.java?view=diff&rev=561059&r1=561058&r2=561059
==============================================================================
--- maven/plugins/branches/MWAR-97-2/src/test/java/org/apache/maven/plugin/war/overlay/OverlayManagerTest.java (original)
+++ maven/plugins/branches/MWAR-97-2/src/test/java/org/apache/maven/plugin/war/overlay/OverlayManagerTest.java Mon Jul 30 10:38:43 2007
@@ -43,7 +43,7 @@
         final List overlays = new ArrayList();
         try
         {
-            OverlayManager manager = new OverlayManager( overlays, project );
+            OverlayManager manager = new OverlayManager( overlays, project, "**/**", "META-INF/**" );
             assertNotNull( manager.getOverlays() );
             assertEquals( 1, manager.getOverlays().size() );
             assertEquals( Overlay.currentProjectInstance(), manager.getOverlays().get( 0 ) );
@@ -67,7 +67,7 @@
 
         try
         {
-            OverlayManager manager = new OverlayManager( overlays, project );
+            OverlayManager manager = new OverlayManager( overlays, project, "**/**", "META-INF/**" );
             assertNotNull( manager.getOverlays() );
             assertEquals( 2, manager.getOverlays().size() );
             assertEquals( Overlay.currentProjectInstance(), manager.getOverlays().get( 0 ) );
@@ -93,7 +93,7 @@
 
         try
         {
-            OverlayManager manager = new OverlayManager( overlays, project );
+            OverlayManager manager = new OverlayManager( overlays, project, "**/**", "META-INF/**" );
             assertNotNull( manager.getOverlays() );
             assertEquals( 2, manager.getOverlays().size() );
             assertEquals( Overlay.currentProjectInstance(), manager.getOverlays().get( 0 ) );
@@ -119,7 +119,7 @@
 
         try
         {
-            new OverlayManager( overlays, project );
+            new OverlayManager( overlays, project, "**/**", "META-INF/**" );
             fail( "Should have failed to validate an unknown overlay" );
         }
         catch ( InvalidOverlayConfigurationException e )
@@ -144,7 +144,7 @@
 
         try
         {
-            OverlayManager manager = new OverlayManager( overlays, project );
+            OverlayManager manager = new OverlayManager( overlays, project, "**/**", "META-INF/**" );
             assertNotNull( manager.getOverlays() );
             assertEquals( 3, manager.getOverlays().size() );
             assertEquals( overlays.get( 0 ), manager.getOverlays().get( 0 ) );