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