Coverage Report - org.apache.maven.shared.filtering.DefaultMavenResourcesFiltering
 
Classes in this File Line Coverage Branch Coverage Complexity
DefaultMavenResourcesFiltering
80%
110/137
69%
65/94
6.4
 
 1  
 package org.apache.maven.shared.filtering;
 2  
 
 3  
 /*
 4  
  * Licensed to the Apache Software Foundation (ASF) under one
 5  
  * or more contributor license agreements.  See the NOTICE file
 6  
  * distributed with this work for additional information
 7  
  * regarding copyright ownership.  The ASF licenses this file
 8  
  * to you under the Apache License, Version 2.0 (the
 9  
  * "License"); you may not use this file except in compliance
 10  
  * with the License.  You may obtain a copy of the License at
 11  
  *
 12  
  *    http://www.apache.org/licenses/LICENSE-2.0
 13  
  *
 14  
  * Unless required by applicable law or agreed to in writing,
 15  
  * software distributed under the License is distributed on an
 16  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17  
  * KIND, either express or implied.  See the License for the
 18  
  * specific language governing permissions and limitations
 19  
  * under the License.
 20  
  */
 21  
 
 22  
 import org.apache.maven.execution.MavenSession;
 23  
 import org.apache.maven.model.Resource;
 24  
 import org.apache.maven.project.MavenProject;
 25  
 import org.codehaus.plexus.logging.AbstractLogEnabled;
 26  
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
 27  
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
 28  
 import org.codehaus.plexus.util.FileUtils;
 29  
 import org.codehaus.plexus.util.PathTool;
 30  
 import org.codehaus.plexus.util.ReaderFactory;
 31  
 import org.codehaus.plexus.util.Scanner;
 32  
 import org.codehaus.plexus.util.StringUtils;
 33  
 import org.sonatype.plexus.build.incremental.BuildContext;
 34  
 
 35  
 import java.io.File;
 36  
 import java.io.IOException;
 37  
 import java.util.ArrayList;
 38  
 import java.util.Arrays;
 39  
 import java.util.List;
 40  
 
 41  
 /**
 42  
  * @author Olivier Lamy
 43  
  * @plexus.component role="org.apache.maven.shared.filtering.MavenResourcesFiltering"
 44  
  * role-hint="default"
 45  
  */
 46  25
 public class DefaultMavenResourcesFiltering
 47  
     extends AbstractLogEnabled
 48  
     implements MavenResourcesFiltering, Initializable
 49  
 {
 50  
 
 51  1
     private static final String[] EMPTY_STRING_ARRAY = { };
 52  
 
 53  1
     private static final String[] DEFAULT_INCLUDES = { "**/**" };
 54  
 
 55  
     private List<String> defaultNonFilteredFileExtensions;
 56  
 
 57  
     /**
 58  
      * @plexus.requirement
 59  
      */
 60  
     private BuildContext buildContext;
 61  
 
 62  
     // ------------------------------------------------
 63  
     //  Plexus lifecycle
 64  
     // ------------------------------------------------
 65  
     public void initialize()
 66  
         throws InitializationException
 67  
     {
 68  
         // jpg,jpeg,gif,bmp,png
 69  25
         this.defaultNonFilteredFileExtensions = new ArrayList<String>( 5 );
 70  25
         this.defaultNonFilteredFileExtensions.add( "jpg" );
 71  25
         this.defaultNonFilteredFileExtensions.add( "jpeg" );
 72  25
         this.defaultNonFilteredFileExtensions.add( "gif" );
 73  25
         this.defaultNonFilteredFileExtensions.add( "bmp" );
 74  25
         this.defaultNonFilteredFileExtensions.add( "png" );
 75  25
     }
 76  
 
 77  
 
 78  
     /**
 79  
      * @plexus.requirement role-hint="default"
 80  
      */
 81  
     private MavenFileFilter mavenFileFilter;
 82  
 
 83  
     public void filterResources( List<Resource> resources, File outputDirectory, MavenProject mavenProject,
 84  
                                  String encoding, List<String> fileFilters, List<String> nonFilteredFileExtensions,
 85  
                                  MavenSession mavenSession )
 86  
         throws MavenFilteringException
 87  
     {
 88  12
         MavenResourcesExecution mavenResourcesExecution =
 89  
             new MavenResourcesExecution( resources, outputDirectory, mavenProject, encoding, fileFilters,
 90  
                                          nonFilteredFileExtensions, mavenSession );
 91  12
         mavenResourcesExecution.setUseDefaultFilterWrappers( true );
 92  
 //        mavenResourcesExecution.setEscapeWindowsPaths( false );
 93  
 
 94  12
         filterResources( mavenResourcesExecution );
 95  12
     }
 96  
 
 97  
     public void filterResources( List<Resource> resources, File outputDirectory, String encoding,
 98  
                                  List<FileUtils.FilterWrapper> filterWrappers, File resourcesBaseDirectory,
 99  
                                  List<String> nonFilteredFileExtensions )
 100  
         throws MavenFilteringException
 101  
     {
 102  0
         MavenResourcesExecution mavenResourcesExecution =
 103  
             new MavenResourcesExecution( resources, outputDirectory, encoding, filterWrappers, resourcesBaseDirectory,
 104  
                                          nonFilteredFileExtensions );
 105  0
         filterResources( mavenResourcesExecution );
 106  0
     }
 107  
 
 108  
 
 109  
     public boolean filteredFileExtension( String fileName, List<String> userNonFilteredFileExtensions )
 110  
     {
 111  71
         List<String> nonFilteredFileExtensions = new ArrayList<String>( getDefaultNonFilteredFileExtensions() );
 112  71
         if ( userNonFilteredFileExtensions != null )
 113  
         {
 114  71
             nonFilteredFileExtensions.addAll( userNonFilteredFileExtensions );
 115  
         }
 116  71
         boolean filteredFileExtension =
 117  
             !nonFilteredFileExtensions.contains( StringUtils.lowerCase( FileUtils.extension( fileName ) ) );
 118  71
         if ( getLogger().isDebugEnabled() )
 119  
         {
 120  0
             getLogger().debug(
 121  
                 "file " + fileName + " has a" + ( filteredFileExtension ? " " : " non " ) + "filtered file extension" );
 122  
         }
 123  71
         return filteredFileExtension;
 124  
     }
 125  
 
 126  
     public List<String> getDefaultNonFilteredFileExtensions()
 127  
     {
 128  71
         if ( this.defaultNonFilteredFileExtensions == null )
 129  
         {
 130  0
             this.defaultNonFilteredFileExtensions = new ArrayList<String>();
 131  
         }
 132  71
         return this.defaultNonFilteredFileExtensions;
 133  
     }
 134  
 
 135  
     public void filterResources( MavenResourcesExecution mavenResourcesExecution )
 136  
         throws MavenFilteringException
 137  
     {
 138  25
         if ( mavenResourcesExecution == null )
 139  
         {
 140  0
             throw new MavenFilteringException( "mavenResourcesExecution cannot be null" );
 141  
         }
 142  
 
 143  25
         if ( mavenResourcesExecution.getResources() == null )
 144  
         {
 145  0
             getLogger().info( "No resources configured skip copying/filtering" );
 146  0
             return;
 147  
         }
 148  
 
 149  25
         if ( mavenResourcesExecution.getOutputDirectory() == null )
 150  
         {
 151  0
             throw new MavenFilteringException( "outputDirectory cannot be null" );
 152  
         }
 153  
 
 154  25
         if ( mavenResourcesExecution.isUseDefaultFilterWrappers() )
 155  
         {
 156  25
             List<FileUtils.FilterWrapper> filterWrappers = new ArrayList<FileUtils.FilterWrapper>();
 157  25
             if ( mavenResourcesExecution.getFilterWrappers() != null )
 158  
             {
 159  1
                 filterWrappers.addAll( mavenResourcesExecution.getFilterWrappers() );
 160  
             }
 161  25
             filterWrappers.addAll( mavenFileFilter.getDefaultFilterWrappers( mavenResourcesExecution ) );
 162  25
             mavenResourcesExecution.setFilterWrappers( filterWrappers );
 163  
         }
 164  
 
 165  25
         if ( mavenResourcesExecution.getEncoding() == null || mavenResourcesExecution.getEncoding().length() < 1 )
 166  
         {
 167  0
             getLogger().warn( "Using platform encoding (" + ReaderFactory.FILE_ENCODING
 168  
                                   + " actually) to copy filtered resources, i.e. build is platform dependent!" );
 169  
         }
 170  
         else
 171  
         {
 172  25
             getLogger().info(
 173  
                 "Using '" + mavenResourcesExecution.getEncoding() + "' encoding to copy filtered resources." );
 174  
         }
 175  
 
 176  25
         for ( Resource resource : mavenResourcesExecution.getResources() )
 177  
         {
 178  
 
 179  27
             if ( getLogger().isDebugEnabled() )
 180  
             {
 181  0
                 String ls = System.getProperty( "line.separator" );
 182  0
                 StringBuffer debugMessage =
 183  
                     new StringBuffer( "resource with targetPath " + resource.getTargetPath() ).append( ls );
 184  0
                 debugMessage.append( "directory " + resource.getDirectory() ).append( ls );
 185  0
                 debugMessage.append( "excludes " + ( resource.getExcludes() == null
 186  
                     ? " empty "
 187  
                     : resource.getExcludes().toString() ) ).append( ls );
 188  0
                 debugMessage.append(
 189  
                     "includes " + ( resource.getIncludes() == null ? " empty " : resource.getIncludes().toString() ) );
 190  0
                 getLogger().debug( debugMessage.toString() );
 191  
             }
 192  
 
 193  27
             String targetPath = resource.getTargetPath();
 194  
 
 195  27
             File resourceDirectory = new File( resource.getDirectory() );
 196  
 
 197  27
             if ( !resourceDirectory.isAbsolute() )
 198  
             {
 199  0
                 resourceDirectory =
 200  
                     new File( mavenResourcesExecution.getResourcesBaseDirectory(), resourceDirectory.getPath() );
 201  
             }
 202  
 
 203  27
             if ( !resourceDirectory.exists() )
 204  
             {
 205  0
                 getLogger().info( "skip non existing resourceDirectory " + resourceDirectory.getPath() );
 206  0
                 continue;
 207  
             }
 208  
 
 209  
             // this part is required in case the user specified "../something" as destination
 210  
             // see MNG-1345
 211  27
             File outputDirectory = mavenResourcesExecution.getOutputDirectory();
 212  27
             boolean outputExists = outputDirectory.exists();
 213  27
             if ( !outputExists && !outputDirectory.mkdirs() )
 214  
             {
 215  0
                 throw new MavenFilteringException( "Cannot create resource output directory: " + outputDirectory );
 216  
             }
 217  
 
 218  27
             boolean ignoreDelta = !outputExists || buildContext.hasDelta( mavenResourcesExecution.getFileFilters() )
 219  
                 || buildContext.hasDelta( getRelativeOutputDirectory( mavenResourcesExecution ) );
 220  27
             getLogger().debug( "ignoreDelta " + ignoreDelta );
 221  27
             Scanner scanner = buildContext.newScanner( resourceDirectory, ignoreDelta );
 222  
 
 223  27
             setupScanner( resource, scanner );
 224  
 
 225  27
             scanner.scan();
 226  
 
 227  27
             if ( mavenResourcesExecution.isIncludeEmptyDirs() )
 228  
             {
 229  
                 try
 230  
                 {
 231  5
                     File targetDirectory =
 232  
                         targetPath == null ? outputDirectory : new File( outputDirectory, targetPath );
 233  5
                     copyDirectoryLayout( resourceDirectory, targetDirectory, scanner );
 234  
                 }
 235  0
                 catch ( IOException e )
 236  
                 {
 237  0
                     throw new MavenFilteringException(
 238  
                         "Cannot copy directory structure from " + resourceDirectory.getPath() + " to "
 239  
                             + outputDirectory.getPath() );
 240  5
                 }
 241  
             }
 242  
 
 243  27
             List<String> includedFiles = Arrays.asList( scanner.getIncludedFiles() );
 244  
 
 245  27
             getLogger().info(
 246  
                 "Copying " + includedFiles.size() + " resource" + ( includedFiles.size() > 1 ? "s" : "" ) + (
 247  
                     targetPath == null ? "" : " to " + targetPath ) );
 248  
 
 249  27
             for ( String name : includedFiles )
 250  
             {
 251  
 
 252  71
                 File source = new File( resourceDirectory, name );
 253  
 
 254  
                 //File destinationFile = new File( outputDirectory, destination );
 255  
 
 256  71
                 File destinationFile = getDestinationFile( outputDirectory, targetPath, name );
 257  
 
 258  71
                 boolean filteredExt =
 259  
                     filteredFileExtension( source.getName(), mavenResourcesExecution.getNonFilteredFileExtensions() );
 260  
 
 261  71
                 mavenFileFilter.copyFile( source, destinationFile, resource.isFiltering() && filteredExt,
 262  
                                           mavenResourcesExecution.getFilterWrappers(),
 263  
                                           mavenResourcesExecution.getEncoding(),
 264  
                                           mavenResourcesExecution.isOverwrite() );
 265  71
             }
 266  
 
 267  
             // deal with deleted source files
 268  
 
 269  27
             scanner = buildContext.newDeleteScanner( resourceDirectory );
 270  
 
 271  27
             setupScanner( resource, scanner );
 272  
 
 273  27
             scanner.scan();
 274  
 
 275  27
             List<String> deletedFiles = Arrays.asList( scanner.getIncludedFiles() );
 276  
 
 277  27
             for ( String name : deletedFiles )
 278  
             {
 279  3
                 File destinationFile = getDestinationFile( outputDirectory, targetPath, name );
 280  
 
 281  3
                 destinationFile.delete();
 282  
 
 283  3
                 buildContext.refresh( destinationFile );
 284  3
             }
 285  
 
 286  27
         }
 287  
 
 288  25
     }
 289  
 
 290  
     private File getDestinationFile( File outputDirectory, String targetPath, String name )
 291  
     {
 292  74
         String destination = name;
 293  
 
 294  74
         if ( targetPath != null )
 295  
         {
 296  2
             destination = targetPath + "/" + name;
 297  
         }
 298  
 
 299  74
         File destinationFile = new File( destination );
 300  74
         if ( !destinationFile.isAbsolute() )
 301  
         {
 302  73
             destinationFile = new File( outputDirectory, destination );
 303  
         }
 304  
 
 305  74
         if ( !destinationFile.getParentFile().exists() )
 306  
         {
 307  13
             destinationFile.getParentFile().mkdirs();
 308  
         }
 309  74
         return destinationFile;
 310  
     }
 311  
 
 312  
     private String[] setupScanner( Resource resource, Scanner scanner )
 313  
     {
 314  54
         String[] includes = null;
 315  54
         if ( resource.getIncludes() != null && !resource.getIncludes().isEmpty() )
 316  
         {
 317  8
             includes = (String[]) resource.getIncludes().toArray( EMPTY_STRING_ARRAY );
 318  
         }
 319  
         else
 320  
         {
 321  46
             includes = DEFAULT_INCLUDES;
 322  
         }
 323  54
         scanner.setIncludes( includes );
 324  
 
 325  54
         String[] excludes = null;
 326  54
         if ( resource.getExcludes() != null && !resource.getExcludes().isEmpty() )
 327  
         {
 328  4
             excludes = (String[]) resource.getExcludes().toArray( EMPTY_STRING_ARRAY );
 329  4
             scanner.setExcludes( excludes );
 330  
         }
 331  
 
 332  54
         scanner.addDefaultExcludes();
 333  54
         return includes;
 334  
     }
 335  
 
 336  
     private void copyDirectoryLayout( File sourceDirectory, File destinationDirectory, Scanner scanner )
 337  
         throws IOException
 338  
     {
 339  5
         if ( sourceDirectory == null )
 340  
         {
 341  0
             throw new IOException( "source directory can't be null." );
 342  
         }
 343  
 
 344  5
         if ( destinationDirectory == null )
 345  
         {
 346  0
             throw new IOException( "destination directory can't be null." );
 347  
         }
 348  
 
 349  5
         if ( sourceDirectory.equals( destinationDirectory ) )
 350  
         {
 351  0
             throw new IOException( "source and destination are the same directory." );
 352  
         }
 353  
 
 354  5
         if ( !sourceDirectory.exists() )
 355  
         {
 356  0
             throw new IOException( "Source directory doesn't exists (" + sourceDirectory.getAbsolutePath() + ")." );
 357  
         }
 358  
 
 359  5
         List<String> includedDirectories = Arrays.asList( scanner.getIncludedDirectories() );
 360  
 
 361  5
         for ( String name : includedDirectories )
 362  
         {
 363  9
             File source = new File( sourceDirectory, name );
 364  
 
 365  9
             if ( source.equals( sourceDirectory ) )
 366  
             {
 367  5
                 continue;
 368  
             }
 369  
 
 370  4
             File destination = new File( destinationDirectory, name );
 371  4
             destination.mkdirs();
 372  4
         }
 373  5
     }
 374  
 
 375  
     private String getRelativeOutputDirectory( MavenResourcesExecution execution )
 376  
     {
 377  5
         String relOutDir = execution.getOutputDirectory().getAbsolutePath();
 378  
 
 379  5
         if ( execution.getMavenProject() != null && execution.getMavenProject().getBasedir() != null )
 380  
         {
 381  5
             String basedir = execution.getMavenProject().getBasedir().getAbsolutePath();
 382  5
             relOutDir = PathTool.getRelativeFilePath( basedir, relOutDir );
 383  5
             if ( relOutDir == null )
 384  
             {
 385  0
                 relOutDir = execution.getOutputDirectory().getPath();
 386  
             }
 387  
             else
 388  
             {
 389  5
                 relOutDir = relOutDir.replace( '\\', '/' );
 390  
             }
 391  
         }
 392  
 
 393  5
         return relOutDir;
 394  
     }
 395  
 
 396  
 }