1 package org.apache.maven.plugin.ear;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.archiver.MavenArchiveConfiguration;
23 import org.apache.maven.archiver.MavenArchiver;
24 import org.apache.maven.execution.MavenSession;
25 import org.apache.maven.plugin.MojoExecutionException;
26 import org.apache.maven.plugin.MojoFailureException;
27 import org.apache.maven.plugin.ear.util.EarMavenArchiver;
28 import org.apache.maven.project.MavenProjectHelper;
29 import org.apache.maven.shared.filtering.MavenFileFilter;
30 import org.apache.maven.shared.filtering.MavenFilteringException;
31 import org.apache.maven.shared.filtering.MavenResourcesExecution;
32 import org.apache.maven.shared.filtering.MavenResourcesFiltering;
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.ArchiverManager;
37 import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
38 import org.codehaus.plexus.util.DirectoryScanner;
39 import org.codehaus.plexus.util.FileUtils;
40 import org.codehaus.plexus.util.StringUtils;
41
42 import java.io.File;
43 import java.io.IOException;
44 import java.util.ArrayList;
45 import java.util.Arrays;
46 import java.util.Iterator;
47 import java.util.List;
48
49
50
51
52
53
54
55
56
57
58
59 public class EarMojo
60 extends AbstractEarMojo
61 {
62 private static final String[] EMPTY_STRING_ARRAY = {};
63
64
65
66
67
68
69
70
71 private File earSourceDirectory;
72
73
74
75
76
77
78 private String earSourceIncludes;
79
80
81
82
83
84
85 private String earSourceExcludes;
86
87
88
89
90
91
92
93 private boolean filtering;
94
95
96
97
98
99
100
101 private List filters;
102
103
104
105
106
107
108
109
110 private List nonFilteredFileExtensions;
111
112
113
114
115
116
117
118
119 private boolean escapedBackslashesInFilePath;
120
121
122
123
124
125
126
127
128 protected String escapeString;
129
130
131
132
133
134
135
136
137
138 private File manifestFile;
139
140
141
142
143
144
145
146 private String applicationXml;
147
148
149
150
151
152
153
154 private String outputDirectory;
155
156
157
158
159
160
161
162 private String finalName;
163
164
165
166
167
168
169
170 private String unpackTypes;
171
172
173
174
175
176
177
178 private String classifier;
179
180
181
182
183
184
185
186 private File resourcesDir;
187
188
189
190
191
192
193 private JarArchiver jarArchiver;
194
195
196
197
198
199
200
201 private MavenArchiveConfiguration archive = new MavenArchiveConfiguration();
202
203
204
205
206 private MavenProjectHelper projectHelper;
207
208
209
210
211
212
213 private ArchiverManager archiverManager;
214
215
216
217
218
219 private MavenFileFilter mavenFileFilter;
220
221
222
223
224
225 private MavenResourcesFiltering mavenResourcesFiltering;
226
227
228
229
230
231
232
233 private MavenSession session;
234
235
236 private List filterWrappers;
237
238
239 public void execute()
240 throws MojoExecutionException, MojoFailureException
241 {
242
243 super.execute();
244
245
246 List unpackTypesList = new ArrayList();
247 if ( unpackTypes != null )
248 {
249 unpackTypesList = Arrays.asList( unpackTypes.split( "," ) );
250 final Iterator it = unpackTypesList.iterator();
251 while ( it.hasNext() )
252 {
253 String type = (String) it.next();
254 if ( !EarModuleFactory.standardArtifactTypes.contains( type ) )
255 {
256 throw new MojoExecutionException(
257 "Invalid type[" + type + "] supported types are " + EarModuleFactory.standardArtifactTypes );
258 }
259 }
260 getLog().debug( "Initialized unpack types " + unpackTypesList );
261 }
262
263
264 try
265 {
266 for ( Iterator iter = getModules().iterator(); iter.hasNext(); )
267 {
268 EarModule module = (EarModule) iter.next();
269 if ( module instanceof JavaModule )
270 {
271 getLog().warn( "JavaModule is deprecated (" + module + "), please use JarModule instead." );
272 }
273 if ( module instanceof Ejb3Module )
274 {
275 getLog().warn( "Ejb3Module is deprecated (" + module + "), please use EjbModule instead." );
276 }
277 final File sourceFile = module.getArtifact().getFile();
278 final File destinationFile = buildDestinationFile( getWorkDirectory(), module.getUri() );
279 if ( !sourceFile.isFile() )
280 {
281 throw new MojoExecutionException(
282 "Cannot copy a directory: " + sourceFile.getAbsolutePath() + "; Did you package/install " +
283 module.getArtifact() + "?" );
284 }
285
286 if ( destinationFile.getCanonicalPath().equals( sourceFile.getCanonicalPath() ) )
287 {
288 getLog().info(
289 "Skipping artifact[" + module + "], as it already exists at[" + module.getUri() + "]" );
290 continue;
291 }
292
293
294
295 if ( ( unpackTypesList.contains( module.getType() ) &&
296 ( module.shouldUnpack() == null || module.shouldUnpack().booleanValue() ) ) ||
297 ( module.shouldUnpack() != null && module.shouldUnpack().booleanValue() ) )
298 {
299 getLog().info( "Copying artifact[" + module + "] to[" + module.getUri() + "] (unpacked)" );
300
301 destinationFile.mkdirs();
302 unpack( sourceFile, destinationFile );
303 }
304 else
305 {
306 if ( sourceFile.lastModified() > destinationFile.lastModified() )
307 {
308 getLog().info( "Copying artifact[" + module + "] to[" + module.getUri() + "]" );
309 FileUtils.copyFile( sourceFile, destinationFile );
310 }
311 else
312 {
313 getLog().debug(
314 "Skipping artifact[" + module + "], as it is already up to date at[" + module.getUri() +
315 "]" );
316 }
317 }
318 }
319 }
320 catch ( IOException e )
321 {
322 throw new MojoExecutionException( "Error copying EAR modules", e );
323 }
324 catch ( ArchiverException e )
325 {
326 throw new MojoExecutionException( "Error unpacking EAR modules", e );
327 }
328 catch ( NoSuchArchiverException e )
329 {
330 throw new MojoExecutionException( "No Archiver found for EAR modules", e );
331 }
332
333
334 try
335 {
336 File earSourceDir = earSourceDirectory;
337 if ( earSourceDir.exists() )
338 {
339 getLog().info( "Copy ear sources to " + getWorkDirectory().getAbsolutePath() );
340 String[] fileNames = getEarFiles( earSourceDir );
341 for ( int i = 0; i < fileNames.length; i++ )
342 {
343 copyFile( new File( earSourceDir, fileNames[i] ), new File( getWorkDirectory(), fileNames[i] ) );
344 }
345 }
346
347 if ( applicationXml != null && !"".equals( applicationXml ) )
348 {
349
350 getLog().info( "Including custom application.xml[" + applicationXml + "]" );
351 File metaInfDir = new File( getWorkDirectory(), META_INF );
352 copyFile( new File( applicationXml ), new File( metaInfDir, "/application.xml" ) );
353 }
354
355 }
356 catch ( IOException e )
357 {
358 throw new MojoExecutionException( "Error copying EAR sources", e );
359 }
360 catch ( MavenFilteringException e )
361 {
362 throw new MojoExecutionException( "Error filtering EAR sources", e );
363 }
364
365
366 try
367 {
368 if ( resourcesDir != null && resourcesDir.exists() )
369 {
370 getLog().warn( "resourcesDir is deprecated. Please use the earSourceDirectory property instead." );
371 getLog().info( "Copy ear resources to " + getWorkDirectory().getAbsolutePath() );
372 String[] fileNames = getEarFiles( resourcesDir );
373 for ( int i = 0; i < fileNames.length; i++ )
374 {
375 FileUtils.copyFile( new File( resourcesDir, fileNames[i] ),
376 new File( getWorkDirectory(), fileNames[i] ) );
377 }
378 }
379 }
380 catch ( IOException e )
381 {
382 throw new MojoExecutionException( "Error copying EAR resources", e );
383 }
384
385
386 File ddFile = new File( getWorkDirectory(), APPLICATION_XML_URI );
387 if ( !ddFile.exists() && ( !( version.equals( VERSION_5 ) || version.equals( VERSION_6 ) ) ) )
388 {
389 throw new MojoExecutionException(
390 "Deployment descriptor: " + ddFile.getAbsolutePath() + " does not exist." );
391 }
392
393 try
394 {
395 File earFile = getEarFile( outputDirectory, finalName, classifier );
396 final MavenArchiver archiver = new EarMavenArchiver( getModules() );
397 final JarArchiver jarArchiver = getJarArchiver();
398 getLog().debug( "Jar archiver implementation[" + jarArchiver.getClass().getName() + "]" );
399 archiver.setArchiver( jarArchiver );
400 archiver.setOutputFile( earFile );
401
402
403 includeCustomManifestFile();
404
405 archiver.getArchiver().addDirectory( getWorkDirectory() );
406 archiver.createArchive( getProject(), archive );
407
408 if ( classifier != null )
409 {
410 projectHelper.attachArtifact( getProject(), "ear", classifier, earFile );
411 }
412 else
413 {
414 getProject().getArtifact().setFile( earFile );
415 }
416 }
417 catch ( Exception e )
418 {
419 throw new MojoExecutionException( "Error assembling EAR", e );
420 }
421 }
422
423 public String getApplicationXml()
424 {
425 return applicationXml;
426 }
427
428 public void setApplicationXml( String applicationXml )
429 {
430 this.applicationXml = applicationXml;
431 }
432
433
434
435
436
437
438
439 protected String[] getExcludes()
440 {
441 List excludeList = new ArrayList( FileUtils.getDefaultExcludesAsList() );
442 if ( earSourceExcludes != null && !"".equals( earSourceExcludes ) )
443 {
444 excludeList.addAll( Arrays.asList( StringUtils.split( earSourceExcludes, "," ) ) );
445 }
446
447
448 if ( getApplicationXml() != null && !"".equals( getApplicationXml() ) )
449 {
450 excludeList.add( "**/" + META_INF + "/application.xml" );
451 }
452
453 return (String[]) excludeList.toArray( EMPTY_STRING_ARRAY );
454 }
455
456
457
458
459
460
461
462 protected String[] getIncludes()
463 {
464 return StringUtils.split( StringUtils.defaultString( earSourceIncludes ), "," );
465 }
466
467 private static File buildDestinationFile( File buildDir, String uri )
468 {
469 return new File( buildDir, uri );
470 }
471
472 private void includeCustomManifestFile()
473 {
474 if ( manifestFile == null )
475 {
476 manifestFile = new File( getWorkDirectory(), "META-INF/MANIFEST.MF" );
477 }
478
479 if ( !manifestFile.exists() )
480 {
481 getLog().info( "Could not find manifest file: " + manifestFile + " - Generating one" );
482 }
483 else
484 {
485 getLog().info( "Including custom manifest file[" + manifestFile + "]" );
486 archive.setManifestFile( manifestFile );
487 }
488 }
489
490
491
492
493
494
495
496
497
498 private static File getEarFile( String basedir, String finalName, String classifier )
499 {
500 if ( classifier == null )
501 {
502 classifier = "";
503 }
504 else if ( classifier.trim().length() > 0 && !classifier.startsWith( "-" ) )
505 {
506 classifier = "-" + classifier;
507 }
508
509 return new File( basedir, finalName + classifier + ".ear" );
510 }
511
512
513
514
515
516
517
518
519 private String[] getEarFiles( File sourceDir )
520 {
521 DirectoryScanner scanner = new DirectoryScanner();
522 scanner.setBasedir( sourceDir );
523 scanner.setExcludes( getExcludes() );
524 scanner.addDefaultExcludes();
525
526 scanner.setIncludes( getIncludes() );
527
528 scanner.scan();
529
530 return scanner.getIncludedFiles();
531 }
532
533
534
535
536
537
538
539 public void unpack( File source, File destDir )
540 throws NoSuchArchiverException, IOException, ArchiverException
541 {
542 UnArchiver unArchiver = archiverManager.getUnArchiver( "zip" );
543 unArchiver.setSourceFile( source );
544 unArchiver.setDestDirectory( destDir );
545
546
547 unArchiver.extract();
548 }
549
550
551
552
553
554
555
556
557
558 protected JarArchiver getJarArchiver()
559 {
560 return jarArchiver;
561 }
562
563 private void copyFile( File source, File target )
564 throws MavenFilteringException, IOException, MojoExecutionException
565 {
566 if ( filtering && !isNonFilteredExtension( source.getName() ) )
567 {
568
569 if ( target.getParentFile() != null && !target.getParentFile().exists() )
570 {
571 target.getParentFile().mkdirs();
572 }
573 mavenFileFilter.copyFile( source, target, true, getFilterWrappers(), null );
574 }
575 else
576 {
577 FileUtils.copyFile( source, target );
578 }
579 }
580
581 public boolean isNonFilteredExtension( String fileName )
582 {
583 return !mavenResourcesFiltering.filteredFileExtension( fileName, nonFilteredFileExtensions );
584 }
585
586 private List getFilterWrappers()
587 throws MojoExecutionException
588 {
589 if ( filterWrappers == null )
590 {
591 try
592 {
593 MavenResourcesExecution mavenResourcesExecution = new MavenResourcesExecution();
594 mavenResourcesExecution.setEscapeString( escapeString );
595 filterWrappers =
596 mavenFileFilter.getDefaultFilterWrappers( project, filters, escapedBackslashesInFilePath,
597 this.session, mavenResourcesExecution );
598 }
599 catch ( MavenFilteringException e )
600 {
601 getLog().error( "fail to build filering wrappers " + e.getMessage() );
602 throw new MojoExecutionException( e.getMessage(), e );
603 }
604 }
605 return filterWrappers;
606 }
607 }