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 import java.util.Iterator;
25
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.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 import org.codehaus.plexus.util.xml.XmlStreamReader;
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 ( Iterator iter = sourceFilesSet.iterator(); iter.hasNext(); )
83 {
84 final String fileToCopyName = (String) iter.next();
85 final File sourceFile = new File( sourceBaseDir, fileToCopyName );
86
87 String destinationFileName;
88 if ( targetPrefix == null )
89 {
90 destinationFileName = fileToCopyName;
91 }
92 else
93 {
94 destinationFileName = targetPrefix + fileToCopyName;
95 }
96
97
98 if ( filtered
99 && !context.isNonFilteredExtension( sourceFile.getName() ) )
100 {
101 copyFilteredFile( sourceId, context, sourceFile, destinationFileName );
102 }
103 else
104 {
105 copyFile( sourceId, context, sourceFile, destinationFileName );
106 }
107 }
108 }
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123 protected void copyFiles( String sourceId, WarPackagingContext context, File sourceBaseDir, PathSet sourceFilesSet,
124 boolean filtered )
125 throws IOException, MojoExecutionException
126 {
127 copyFiles( sourceId, context, sourceBaseDir, sourceFilesSet, null, filtered );
128 }
129
130
131
132
133
134
135
136
137
138
139
140
141
142 protected void copyFile( String sourceId, final WarPackagingContext context, final File file,
143 String targetFilename )
144 throws IOException
145 {
146 final File targetFile = new File( context.getWebappDirectory(), targetFilename );
147 context.getWebappStructure().registerFile( sourceId, targetFilename, new WebappStructure.RegistrationCallback()
148 {
149 public void registered( String ownerId, String targetFilename )
150 throws IOException
151 {
152 copyFile( context, file, targetFile, targetFilename, false );
153 }
154
155 public void alreadyRegistered( String ownerId, String targetFilename )
156 throws IOException
157 {
158 copyFile( context, file, targetFile, targetFilename, true );
159 }
160
161 public void refused( String ownerId, String targetFilename, String actualOwnerId )
162 throws IOException
163 {
164 context.getLog().debug( " - " + targetFilename + " wasn't copied because it has "
165 + "already been packaged for overlay [" + actualOwnerId + "]." );
166 }
167
168 public void superseded( String ownerId, String targetFilename, String deprecatedOwnerId )
169 throws IOException
170 {
171 context.getLog().info( "File [" + targetFilename + "] belonged to overlay [" + deprecatedOwnerId
172 + "] so it will be overwritten." );
173 copyFile( context, file, targetFile, targetFilename, false );
174 }
175
176 public void supersededUnknownOwner( String ownerId, String targetFilename, String unknownOwnerId )
177 throws IOException
178 {
179 context.getLog()
180 .warn( "File [" + targetFilename + "] belonged to overlay [" + unknownOwnerId
181 + "] which does not exist anymore in the current project. It is recommended to invoke "
182 + "clean if the dependencies of the project changed." );
183 copyFile( context, file, targetFile, targetFilename, false );
184 }
185 } );
186 }
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203 protected boolean copyFilteredFile( String sourceId, final WarPackagingContext context, File file,
204 String targetFilename )
205 throws IOException, MojoExecutionException
206 {
207
208 if ( context.getWebappStructure().registerFile( sourceId, targetFilename ) )
209 {
210 final File targetFile = new File( context.getWebappDirectory(), targetFilename );
211 final String encoding;
212 try
213 {
214 if ( isXmlFile( file ) )
215 {
216
217 encoding = getEncoding( file );
218 }
219 else
220 {
221
222 encoding = context.getResourceEncoding();
223 }
224
225 targetFile.getParentFile().mkdirs();
226 context.getMavenFileFilter().copyFile( file, targetFile, true, context.getFilterWrappers(), encoding );
227 }
228 catch ( MavenFilteringException e )
229 {
230 throw new MojoExecutionException( e.getMessage(), e );
231 }
232
233 context.getLog().debug( " + " + targetFilename + " has been copied (filtered encoding='" + encoding + "')." );
234 return true;
235 }
236 else
237 {
238 context.getLog().debug(
239 " - " + targetFilename + " wasn't copied because it has already been packaged (filtered)." );
240 return false;
241 }
242 }
243
244
245
246
247
248
249
250
251
252 protected void doUnpack( WarPackagingContext context, File file, File unpackDirectory )
253 throws MojoExecutionException
254 {
255 String archiveExt = FileUtils.getExtension( file.getAbsolutePath() ).toLowerCase();
256
257 try
258 {
259 UnArchiver unArchiver = context.getArchiverManager().getUnArchiver( archiveExt );
260 unArchiver.setSourceFile( file );
261 unArchiver.setDestDirectory( unpackDirectory );
262 unArchiver.setOverwrite( true );
263 unArchiver.extract();
264 }
265 catch ( ArchiverException e )
266 {
267 throw new MojoExecutionException( "Error unpacking file [" + file.getAbsolutePath() + "]" + "to ["
268 + unpackDirectory.getAbsolutePath() + "]", e );
269 }
270 catch ( NoSuchArchiverException e )
271 {
272 context.getLog().warn( "Skip unpacking dependency file [" + file.getAbsolutePath()
273 + " with unknown extension [" + archiveExt + "]" );
274 }
275 }
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293 protected boolean copyFile( WarPackagingContext context, File source, File destination, String targetFilename,
294 boolean onlyIfModified )
295 throws IOException
296 {
297 if ( onlyIfModified && destination.lastModified() >= source.lastModified() )
298 {
299 context.getLog().debug( " * " + targetFilename + " is up to date." );
300 return false;
301 }
302 else
303 {
304 FileUtils.copyFile( source.getCanonicalFile(), destination );
305
306 destination.setLastModified( source.lastModified() );
307 context.getLog().debug( " + " + targetFilename + " has been copied." );
308 return true;
309 }
310 }
311
312
313
314
315
316
317
318
319 protected String getEncoding( File webXml )
320 throws IOException
321 {
322 XmlStreamReader xmlReader = new XmlStreamReader( webXml );
323 try
324 {
325 return xmlReader.getEncoding();
326 }
327 finally
328 {
329 IOUtil.close( xmlReader );
330 }
331 }
332
333
334
335
336
337
338
339
340
341
342 protected PathSet getFilesToIncludes( File baseDir, String[] includes, String[] excludes )
343 {
344 final DirectoryScanner scanner = new DirectoryScanner();
345 scanner.setBasedir( baseDir );
346
347 if ( excludes != null )
348 {
349 scanner.setExcludes( excludes );
350 }
351 scanner.addDefaultExcludes();
352
353 if ( includes != null && includes.length > 0 )
354 {
355 scanner.setIncludes( includes );
356 }
357 else
358 {
359 scanner.setIncludes( DEFAULT_INCLUDES );
360 }
361
362 scanner.scan();
363
364 return new PathSet( scanner.getIncludedFiles() );
365
366 }
367
368
369
370
371
372
373
374
375
376
377
378 protected String getArtifactFinalName( WarPackagingContext context, Artifact artifact )
379 throws InterpolationException
380 {
381 if ( context.getOutputFileNameMapping() != null )
382 {
383 return MappingUtils.evaluateFileNameMapping( context.getOutputFileNameMapping(), artifact );
384 }
385
386 String classifier = artifact.getClassifier();
387 if ( ( classifier != null ) && !( "".equals( classifier.trim() ) ) )
388 {
389 return MappingUtils.evaluateFileNameMapping( AbstractWarMojo.DEFAULT_FILE_NAME_MAPPING_CLASSIFIER,
390 artifact );
391 }
392 else
393 {
394 return MappingUtils.evaluateFileNameMapping( AbstractWarMojo.DEFAULT_FILE_NAME_MAPPING, artifact );
395 }
396
397 }
398
399
400
401
402
403
404
405
406
407
408 private boolean isXmlFile( File file )
409 {
410 return file != null && file.isFile() && file.getName().endsWith( ".xml" );
411 }
412 }