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