1   package org.apache.maven.plugin.rar;
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.artifact.Artifact;
25  import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
26  import org.apache.maven.execution.MavenSession;
27  import org.apache.maven.model.Resource;
28  import org.apache.maven.plugin.AbstractMojo;
29  import org.apache.maven.plugin.MojoExecutionException;
30  import org.apache.maven.plugins.annotations.Component;
31  import org.apache.maven.plugins.annotations.LifecyclePhase;
32  import org.apache.maven.plugins.annotations.Mojo;
33  import org.apache.maven.plugins.annotations.Parameter;
34  import org.apache.maven.plugins.annotations.ResolutionScope;
35  import org.apache.maven.project.MavenProject;
36  import org.apache.maven.shared.filtering.MavenFilteringException;
37  import org.apache.maven.shared.filtering.MavenResourcesExecution;
38  import org.apache.maven.shared.filtering.MavenResourcesFiltering;
39  import org.codehaus.plexus.archiver.Archiver;
40  import org.codehaus.plexus.archiver.jar.JarArchiver;
41  import org.codehaus.plexus.util.FileUtils;
42  
43  import java.io.File;
44  import java.io.IOException;
45  import java.util.ArrayList;
46  import java.util.Collections;
47  import java.util.Iterator;
48  import java.util.LinkedHashSet;
49  import java.util.List;
50  import java.util.Set;
51  
52  
53  
54  
55  
56  
57  
58  @Mojo( name = "rar", threadSafe = true, defaultPhase = LifecyclePhase.PACKAGE,
59         requiresDependencyResolution = ResolutionScope.TEST )
60  public class RarMojo
61      extends AbstractMojo
62  {
63      public static final String RA_XML_URI = "META-INF/ra.xml";
64  
65      private static final String[] DEFAULT_INCLUDES = { "**/**" };
66  
67      
68  
69  
70      @Parameter( defaultValue = "${basedir}/src/main/rar", required = true )
71      private File rarSourceDirectory;
72  
73      
74  
75  
76      @Parameter( defaultValue = "${basedir}/src/main/rar/META-INF/ra.xml" )
77      private File raXmlFile;
78  
79      
80  
81  
82  
83      @Parameter
84      private Boolean includeJar = Boolean.TRUE;
85  
86      
87  
88  
89      @Parameter( defaultValue = "${basedir}/src/main/rar/META-INF/MANIFEST.MF" )
90      private File manifestFile;
91  
92      
93  
94  
95      @Parameter( defaultValue = "${project.build.directory}/${project.build.finalName}", required = true )
96      private String workDirectory;
97  
98      
99  
100 
101     @Parameter( defaultValue = "${project.build.directory}", required = true )
102     private String outputDirectory;
103 
104     
105 
106 
107     @Parameter( alias = "rarName", defaultValue = "${project.build.finalName}", required = true )
108     private String finalName;
109 
110     
111 
112 
113     @Component
114     private MavenProject project;
115 
116     
117 
118 
119     @Component( role = Archiver.class, hint = "jar" )
120     private JarArchiver jarArchiver;
121 
122     
123 
124 
125 
126     @Parameter
127     private MavenArchiveConfiguration archive = new MavenArchiveConfiguration();
128 
129     
130 
131 
132 
133 
134     @Parameter( property = "rar.filterRarSourceDirectory", defaultValue = "false" )
135     private boolean filterRarSourceDirectory;
136 
137 
138     
139 
140 
141     @Component( role = MavenResourcesFiltering.class, hint = "default" )
142     protected MavenResourcesFiltering mavenResourcesFiltering;
143 
144     
145 
146 
147     @Parameter( defaultValue = "${session}", required = true, readonly = true )
148     protected MavenSession session;
149 
150     
151 
152 
153     @Parameter( property = "encoding", defaultValue = "${project.build.sourceEncoding}" )
154     protected String encoding;
155 
156     
157 
158 
159 
160 
161     @Parameter( property = "maven.resources.escapeWindowsPaths", defaultValue = "true" )
162     protected boolean escapeWindowsPaths;
163 
164     
165 
166 
167 
168 
169 
170     @Parameter( property = "maven.resources.escapeString" )
171     protected String escapeString;
172 
173     
174 
175 
176 
177 
178     @Parameter( property = "maven.resources.overwrite", defaultValue = "false" )
179     private boolean overwrite;
180 
181     
182 
183 
184 
185 
186     @Parameter( property = "maven.resources.includeEmptyDirs", defaultValue = "false" )
187     protected boolean includeEmptyDirs;
188 
189     
190 
191 
192 
193 
194     @Parameter( property = "maven.resources.supportMultiLineFiltering", defaultValue = "false" )
195     private boolean supportMultiLineFiltering;
196 
197     
198 
199 
200     @Parameter( defaultValue = "true" )
201     protected boolean useDefaultDelimiters;
202 
203     
204 
205 
206 
207 
208 
209 
210 
211 
212 
213 
214 
215 
216 
217 
218 
219 
220 
221 
222     @Parameter
223     protected List<String> delimiters;
224 
225     
226 
227 
228 
229 
230 
231 
232 
233 
234 
235 
236 
237 
238 
239     @Parameter
240     protected List<String> filters;
241 
242     
243 
244 
245 
246 
247     @Parameter
248     protected List<String> nonFilteredFileExtensions;
249 
250     
251 
252 
253 
254 
255     @Parameter
256     protected List<RarResource> rarResources;
257 
258 
259     
260 
261 
262 
263 
264 
265 
266     @Parameter( property = "warnOnMissingRaXml", defaultValue = "true" )
267     protected boolean warnOnMissingRaXml = true;
268 
269     private File buildDir;
270 
271 
272     public void execute()
273         throws MojoExecutionException
274     {
275         getLog().debug( " ======= RarMojo settings =======" );
276         getLog().debug( "rarSourceDirectory[" + rarSourceDirectory + "]" );
277         getLog().debug( "manifestFile[" + manifestFile + "]" );
278         getLog().debug( "raXmlFile[" + raXmlFile + "]" );
279         getLog().debug( "workDirectory[" + workDirectory + "]" );
280         getLog().debug( "outputDirectory[" + outputDirectory + "]" );
281         getLog().debug( "finalName[" + finalName + "]" );
282 
283         
284         try
285         {
286             if ( includeJar.booleanValue() )
287             {
288                 File generatedJarFile = new File( outputDirectory, finalName + ".jar" );
289                 if ( generatedJarFile.exists() )
290                 {
291                     getLog().info( "Including generated jar file[" + generatedJarFile.getName() + "]" );
292                     FileUtils.copyFileToDirectory( generatedJarFile, getBuildDir() );
293                 }
294             }
295         }
296         catch ( IOException e )
297         {
298             throw new MojoExecutionException( "Error copying generated Jar file", e );
299         }
300 
301         
302         try
303         {
304             Set artifacts = project.getArtifacts();
305             for ( Iterator iter = artifacts.iterator(); iter.hasNext(); )
306             {
307                 Artifact artifact = (Artifact) iter.next();
308 
309                 ScopeArtifactFilter filter = new ScopeArtifactFilter( Artifact.SCOPE_RUNTIME );
310                 if ( !artifact.isOptional() && filter.include( artifact )
311                     && artifact.getArtifactHandler().isAddedToClasspath() )
312                 {
313                     getLog().info( "Copying artifact[" + artifact.getGroupId() + ", " + artifact.getId() + ", "
314                                        + artifact.getScope() + "]" );
315                     FileUtils.copyFileToDirectory( artifact.getFile(), getBuildDir() );
316                 }
317             }
318         }
319         catch ( IOException e )
320         {
321             throw new MojoExecutionException( "Error copying RAR dependencies", e );
322         }
323 
324         Resource resource = new Resource();
325         resource.setDirectory( rarSourceDirectory.getAbsolutePath() );
326         resource.setTargetPath( getBuildDir().getAbsolutePath() );
327         resource.setFiltering( filterRarSourceDirectory );
328 
329         List<Resource> resources = new ArrayList<Resource>();
330         resources.add( resource );
331 
332         if ( rarResources != null && !rarResources.isEmpty() )
333         {
334             resources.addAll( rarResources );
335         }
336 
337         MavenResourcesExecution mavenResourcesExecution =
338             new MavenResourcesExecution( resources, getBuildDir(), project, encoding, filters,
339                                          Collections.<String>emptyList(), session );
340 
341         mavenResourcesExecution.setEscapeWindowsPaths( escapeWindowsPaths );
342 
343         
344         
345         mavenResourcesExecution.setInjectProjectBuildFilters( false );
346 
347         mavenResourcesExecution.setEscapeString( escapeString );
348         mavenResourcesExecution.setOverwrite( overwrite );
349         mavenResourcesExecution.setIncludeEmptyDirs( includeEmptyDirs );
350         mavenResourcesExecution.setSupportMultiLineFiltering( supportMultiLineFiltering );
351 
352         
353         if ( delimiters != null && !delimiters.isEmpty() )
354         {
355             LinkedHashSet<String> delims = new LinkedHashSet<String>();
356             if ( useDefaultDelimiters )
357             {
358                 delims.addAll( mavenResourcesExecution.getDelimiters() );
359             }
360 
361             for ( String delim : delimiters )
362             {
363                 if ( delim == null )
364                 {
365                     
366                     delims.add( "${*}" );
367                 }
368                 else
369                 {
370                     delims.add( delim );
371                 }
372             }
373 
374             mavenResourcesExecution.setDelimiters( delims );
375         }
376 
377         if ( nonFilteredFileExtensions != null )
378         {
379             mavenResourcesExecution.setNonFilteredFileExtensions( nonFilteredFileExtensions );
380         }
381         try
382         {
383             mavenResourcesFiltering.filterResources( mavenResourcesExecution );
384         }
385         catch ( MavenFilteringException e )
386         {
387             throw new MojoExecutionException( "Error copying RAR resources", e );
388         }
389 
390         
391         try
392         {
393             includeCustomRaXmlFile();
394         }
395         catch ( IOException e )
396         {
397             throw new MojoExecutionException( "Error copying ra.xml file", e );
398         }
399 
400         
401         File ddFile = new File( getBuildDir(), RA_XML_URI );
402         if ( !ddFile.exists() && warnOnMissingRaXml )
403         {
404             getLog().warn( "Connector deployment descriptor: " + ddFile.getAbsolutePath() + " does not exist." );
405         }
406 
407         try
408         {
409             File rarFile = new File( outputDirectory, finalName + ".rar" );
410             MavenArchiver archiver = new MavenArchiver();
411             archiver.setArchiver( jarArchiver );
412             archiver.setOutputFile( rarFile );
413 
414             
415             includeCustomManifestFile();
416 
417             archiver.getArchiver().addDirectory( getBuildDir() );
418             archiver.createArchive( session, project, archive );
419 
420             project.getArtifact().setFile( rarFile );
421         }
422         catch ( Exception e )
423         {
424             throw new MojoExecutionException( "Error assembling RAR", e );
425         }
426     }
427 
428     protected File getBuildDir()
429     {
430         if ( buildDir == null )
431         {
432             buildDir = new File( workDirectory );
433         }
434         return buildDir;
435     }
436 
437     private void includeCustomManifestFile()
438         throws IOException
439     {
440         File customManifestFile = manifestFile;
441         if ( !customManifestFile.exists() )
442         {
443             getLog().info( "Could not find manifest file: " + manifestFile + " - Generating one" );
444         }
445         else
446         {
447             getLog().info( "Including custom manifest file[" + customManifestFile + "]" );
448             archive.setManifestFile( customManifestFile );
449             File metaInfDir = new File( getBuildDir(), "META-INF" );
450             FileUtils.copyFileToDirectory( customManifestFile, metaInfDir );
451         }
452     }
453 
454     private void includeCustomRaXmlFile()
455         throws IOException
456     {
457         if ( raXmlFile == null )
458         {
459             return;
460         }
461         File raXml = raXmlFile;
462         if ( raXml.exists() )
463         {
464             getLog().info( "Using ra.xml " + raXmlFile );
465             File metaInfDir = new File( getBuildDir(), "META-INF" );
466             FileUtils.copyFileToDirectory( raXml, metaInfDir );
467         }
468     }
469 }