1 package org.apache.maven.plugin.war.packaging;
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
25 import org.apache.commons.io.input.XmlStreamReader;
26 import org.apache.maven.artifact.Artifact;
27 import org.apache.maven.plugin.MojoExecutionException;
28 import org.apache.maven.plugin.war.util.PathSet;
29 import org.apache.maven.plugin.war.util.WebappStructure;
30 import org.apache.maven.shared.filtering.MavenFilteringException;
31 import org.apache.maven.shared.mapping.MappingUtils;
32 import org.codehaus.plexus.archiver.ArchiverException;
33 import org.codehaus.plexus.archiver.UnArchiver;
34 import org.codehaus.plexus.archiver.jar.JarArchiver;
35 import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
36 import org.codehaus.plexus.interpolation.InterpolationException;
37 import org.codehaus.plexus.util.DirectoryScanner;
38 import org.codehaus.plexus.util.FileUtils;
39 import org.codehaus.plexus.util.IOUtil;
40
41
42
43
44
45 public abstract class AbstractWarPackagingTask
46 implements WarPackagingTask
47 {
48 public static final String[] DEFAULT_INCLUDES = { "**/**" };
49
50 public static final String WEB_INF_PATH = "WEB-INF";
51
52 public static final String META_INF_PATH = "META-INF";
53
54 public static final String CLASSES_PATH = "WEB-INF/classes/";
55
56 public static final String LIB_PATH = "WEB-INF/lib/";
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75 protected void copyFiles( String sourceId, WarPackagingContext context, File sourceBaseDir, PathSet sourceFilesSet,
76 String targetPrefix, boolean filtered )
77 throws IOException, MojoExecutionException
78 {
79 for ( String fileToCopyName : sourceFilesSet.paths() )
80 {
81 final File sourceFile = new File( sourceBaseDir, fileToCopyName );
82
83 String destinationFileName;
84 if ( targetPrefix == null )
85 {
86 destinationFileName = fileToCopyName;
87 }
88 else
89 {
90 destinationFileName = targetPrefix + fileToCopyName;
91 }
92
93 if ( filtered && !context.isNonFilteredExtension( sourceFile.getName() ) )
94 {
95 copyFilteredFile( sourceId, context, sourceFile, destinationFileName );
96 }
97 else
98 {
99 copyFile( sourceId, context, sourceFile, destinationFileName );
100 }
101 }
102 }
103
104
105
106
107
108
109
110
111
112
113
114
115
116 protected void copyFiles( String sourceId, WarPackagingContext context, File sourceBaseDir, PathSet sourceFilesSet,
117 boolean filtered )
118 throws IOException, MojoExecutionException
119 {
120 copyFiles( sourceId, context, sourceBaseDir, sourceFilesSet, null, filtered );
121 }
122
123
124
125
126
127
128
129
130
131
132
133
134 protected void copyFile( String sourceId, final WarPackagingContext context, final File file, String targetFilename )
135 throws IOException
136 {
137 final File targetFile = new File( context.getWebappDirectory(), targetFilename );
138
139 if ( file.isFile() )
140 {
141 context.getWebappStructure().registerFile( sourceId, targetFilename,
142 new WebappStructure.RegistrationCallback()
143 {
144 public void registered( String ownerId, String targetFilename )
145 throws IOException
146 {
147 copyFile( context, file, targetFile, targetFilename,
148 false );
149 }
150
151 public void alreadyRegistered( String ownerId,
152 String targetFilename )
153 throws IOException
154 {
155 copyFile( context, file, targetFile, targetFilename,
156 true );
157 }
158
159 public void refused( String ownerId, String targetFilename,
160 String actualOwnerId )
161 throws IOException
162 {
163 context.getLog().debug( " - "
164 + targetFilename
165 + " wasn't copied because it has "
166 + "already been packaged for overlay ["
167 + actualOwnerId + "]." );
168 }
169
170 public void superseded( String ownerId,
171 String targetFilename,
172 String deprecatedOwnerId )
173 throws IOException
174 {
175 context.getLog().info( "File ["
176 + targetFilename
177 + "] belonged to overlay ["
178 + deprecatedOwnerId
179 + "] so it will be overwritten." );
180 copyFile( context, file, targetFile, targetFilename,
181 false );
182 }
183
184 public void supersededUnknownOwner( String ownerId,
185 String targetFilename,
186 String unknownOwnerId )
187 throws IOException
188 {
189 context.getLog().warn( "File ["
190 + targetFilename
191 + "] belonged to overlay ["
192 + unknownOwnerId
193 + "] which does not exist anymore in the current project. It is recommended to invoke "
194 + "clean if the dependencies of the project changed." );
195 copyFile( context, file, targetFile, targetFilename,
196 false );
197 }
198 } );
199 }
200 else if ( !targetFile.exists() && !targetFile.mkdirs() )
201 {
202 context.getLog().info( "Failed to create directory " + targetFile.getAbsolutePath() );
203 }
204 }
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220 protected boolean copyFilteredFile( String sourceId, final WarPackagingContext context, File file,
221 String targetFilename )
222 throws IOException, MojoExecutionException
223 {
224
225 if ( context.getWebappStructure().registerFile( sourceId, targetFilename ) )
226 {
227 final File targetFile = new File( context.getWebappDirectory(), targetFilename );
228 final String encoding;
229 try
230 {
231 if ( isXmlFile( file ) )
232 {
233
234 encoding = getEncoding( file );
235 }
236 else
237 {
238
239 encoding = context.getResourceEncoding();
240 }
241
242 targetFile.getParentFile().mkdirs();
243
244 context.getMavenFileFilter().copyFile( file, targetFile, true, context.getFilterWrappers(), encoding );
245 }
246 catch ( MavenFilteringException e )
247 {
248 throw new MojoExecutionException( e.getMessage(), e );
249 }
250
251 context.getLog().debug( " + " + targetFilename + " has been copied (filtered encoding='" + encoding + "')." );
252 return true;
253 }
254 else
255 {
256 context.getLog().debug( " - " + targetFilename
257 + " wasn't copied because it has already been packaged (filtered)." );
258 return false;
259 }
260 }
261
262
263
264
265
266
267
268
269
270 protected void doUnpack( WarPackagingContext context, File file, File unpackDirectory )
271 throws MojoExecutionException
272 {
273 String archiveExt = FileUtils.getExtension( file.getAbsolutePath() ).toLowerCase();
274
275 try
276 {
277 UnArchiver unArchiver = context.getArchiverManager().getUnArchiver( archiveExt );
278 unArchiver.setSourceFile( file );
279 unArchiver.setUseJvmChmod( context.isUseJvmChmod() );
280 unArchiver.setDestDirectory( unpackDirectory );
281 unArchiver.setOverwrite( true );
282 unArchiver.extract();
283 }
284 catch ( ArchiverException e )
285 {
286 throw new MojoExecutionException( "Error unpacking file [" + file.getAbsolutePath() + "]" + "to ["
287 + unpackDirectory.getAbsolutePath() + "]", e );
288 }
289 catch ( NoSuchArchiverException e )
290 {
291 context.getLog().warn( "Skip unpacking dependency file [" + file.getAbsolutePath()
292 + " with unknown extension [" + archiveExt + "]" );
293 }
294 }
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312 protected boolean copyFile( WarPackagingContext context, File source, File destination, String targetFilename,
313 boolean onlyIfModified )
314 throws IOException
315 {
316 if ( onlyIfModified && destination.lastModified() >= source.lastModified() )
317 {
318 context.getLog().debug( " * " + targetFilename + " is up to date." );
319 return false;
320 }
321 else
322 {
323 if ( source.isDirectory() )
324 {
325 context.getLog().warn( " + " + targetFilename + " is packaged from the source folder" );
326
327 try
328 {
329 JarArchiver archiver = context.getJarArchiver();
330 archiver.addDirectory( source );
331 archiver.setDestFile( destination );
332 archiver.createArchive();
333 }
334 catch ( ArchiverException e )
335 {
336 String msg = "Failed to create " + targetFilename;
337 context.getLog().error( msg, e );
338 IOException ioe = new IOException( msg );
339 ioe.initCause( e );
340 throw ioe;
341 }
342 }
343 else
344 {
345 FileUtils.copyFile( source.getCanonicalFile(), destination );
346
347 destination.setLastModified( source.lastModified() );
348 context.getLog().debug( " + " + targetFilename + " has been copied." );
349 }
350 return true;
351 }
352 }
353
354
355
356
357
358
359
360
361 protected String getEncoding( File webXml )
362 throws IOException
363 {
364 XmlStreamReader xmlReader = new XmlStreamReader( webXml );
365 try
366 {
367 return xmlReader.getEncoding();
368 }
369 finally
370 {
371 IOUtil.close( xmlReader );
372 }
373 }
374
375
376
377
378
379
380
381
382
383 protected PathSet getFilesToIncludes( File baseDir, String[] includes, String[] excludes )
384 {
385 return getFilesToIncludes( baseDir, includes, excludes, false );
386 }
387
388
389
390
391
392
393
394
395
396 protected PathSet getFilesToIncludes( File baseDir, String[] includes, String[] excludes, boolean includeDirectories )
397 {
398 final DirectoryScanner scanner = new DirectoryScanner();
399 scanner.setBasedir( baseDir );
400
401 if ( excludes != null )
402 {
403 scanner.setExcludes( excludes );
404 }
405 scanner.addDefaultExcludes();
406
407 if ( includes != null && includes.length > 0 )
408 {
409 scanner.setIncludes( includes );
410 }
411 else
412 {
413 scanner.setIncludes( DEFAULT_INCLUDES );
414 }
415
416 scanner.scan();
417
418 PathSet pathSet = new PathSet( scanner.getIncludedFiles() );
419
420 if ( includeDirectories )
421 {
422 pathSet.addAll( scanner.getIncludedDirectories() );
423 }
424
425 return pathSet;
426 }
427
428
429
430
431
432
433
434
435
436
437 protected String getArtifactFinalName( WarPackagingContext context, Artifact artifact )
438 throws InterpolationException
439 {
440 if ( context.getOutputFileNameMapping() != null )
441 {
442 return MappingUtils.evaluateFileNameMapping( context.getOutputFileNameMapping(), artifact );
443 }
444
445 String classifier = artifact.getClassifier();
446 if ( ( classifier != null ) && !( "".equals( classifier.trim() ) ) )
447 {
448 return MappingUtils.evaluateFileNameMapping( MappingUtils.DEFAULT_FILE_NAME_MAPPING_CLASSIFIER, artifact );
449 }
450 else
451 {
452 return MappingUtils.evaluateFileNameMapping( MappingUtils.DEFAULT_FILE_NAME_MAPPING, artifact );
453 }
454
455 }
456
457
458
459
460
461
462
463
464
465 private boolean isXmlFile( File file )
466 {
467 return file != null && file.isFile() && file.getName().endsWith( ".xml" );
468 }
469 }