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