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