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 }