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.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 public 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
82 private Boolean includeJar = Boolean.TRUE;
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( alias = "rarName", defaultValue = "${project.build.finalName}", required = 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 = "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 List<String> delimiters;
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229 @Parameter
230 protected List<String> filters;
231
232
233
234
235
236
237 @Parameter
238 protected List<String> nonFilteredFileExtensions;
239
240
241
242
243
244
245 @Parameter
246 protected List<RarResource> rarResources;
247
248
249
250
251
252
253
254
255
256 @Parameter( property = "warnOnMissingRaXml", defaultValue = "true" )
257 protected boolean warnOnMissingRaXml = true;
258
259
260
261
262
263
264 @Parameter( property = "maven.rar.skip" )
265 private boolean skip;
266
267
268
269
270 @Parameter( defaultValue = "${project}", readonly = true, required = true )
271 private MavenProject project;
272
273
274
275
276 @Component( role = Archiver.class, hint = "jar" )
277 private JarArchiver jarArchiver;
278
279
280
281
282 @Component( role = MavenResourcesFiltering.class, hint = "default" )
283 protected MavenResourcesFiltering mavenResourcesFiltering;
284
285
286
287
288 @Component
289 private MavenProjectHelper projectHelper;
290
291 private File buildDir;
292
293
294 public void execute()
295 throws MojoExecutionException
296 {
297
298 if ( skip )
299 {
300 getLog().info( "Skipping rar generation." );
301 return;
302 }
303
304 getLog().debug( " ======= RarMojo settings =======" );
305 getLog().debug( "rarSourceDirectory[" + rarSourceDirectory + "]" );
306 getLog().debug( "manifestFile[" + manifestFile + "]" );
307 getLog().debug( "raXmlFile[" + raXmlFile + "]" );
308 getLog().debug( "workDirectory[" + workDirectory + "]" );
309 getLog().debug( "outputDirectory[" + outputDirectory + "]" );
310 getLog().debug( "finalName[" + finalName + "]" );
311 getLog().debug( "classifier[" + classifier + "]" );
312
313
314 try
315 {
316 if (includeJar)
317 {
318 File generatedJarFile = new File( outputDirectory, finalName + ".jar" );
319 if ( generatedJarFile.exists() )
320 {
321 getLog().info( "Including generated jar file[" + generatedJarFile.getName() + "]" );
322 FileUtils.copyFileToDirectory( generatedJarFile, getBuildDir() );
323 }
324 }
325 }
326 catch ( IOException e )
327 {
328 throw new MojoExecutionException( "Error copying generated Jar file", e );
329 }
330
331
332 try
333 {
334 @SuppressWarnings("unchecked")
335 Set<Artifact> artifacts = project.getArtifacts();
336 for (Artifact artifact : artifacts) {
337
338 ScopeArtifactFilter filter = new ScopeArtifactFilter(Artifact.SCOPE_RUNTIME);
339 if (!artifact.isOptional() && filter.include(artifact)
340 && artifact.getArtifactHandler().isAddedToClasspath()) {
341 getLog().info("Copying artifact[" + artifact.getGroupId() + ", " + artifact.getId() + ", "
342 + artifact.getScope() + "]");
343 FileUtils.copyFileToDirectory(artifact.getFile(), getBuildDir());
344 }
345 }
346 }
347 catch ( IOException e )
348 {
349 throw new MojoExecutionException( "Error copying RAR dependencies", e );
350 }
351
352 Resource resource = new Resource();
353 resource.setDirectory( rarSourceDirectory.getAbsolutePath() );
354 resource.setTargetPath( getBuildDir().getAbsolutePath() );
355 resource.setFiltering( filterRarSourceDirectory );
356
357 List<Resource> resources = new ArrayList<Resource>();
358 resources.add( resource );
359
360 if ( rarResources != null && !rarResources.isEmpty() )
361 {
362 resources.addAll( rarResources );
363 }
364
365 MavenResourcesExecution mavenResourcesExecution =
366 new MavenResourcesExecution( resources, getBuildDir(), project, encoding, filters,
367 Collections.<String>emptyList(), session );
368
369 mavenResourcesExecution.setEscapeWindowsPaths( escapeWindowsPaths );
370
371
372
373 mavenResourcesExecution.setInjectProjectBuildFilters( false );
374
375 mavenResourcesExecution.setEscapeString( escapeString );
376 mavenResourcesExecution.setOverwrite( overwrite );
377 mavenResourcesExecution.setIncludeEmptyDirs( includeEmptyDirs );
378 mavenResourcesExecution.setSupportMultiLineFiltering( supportMultiLineFiltering );
379
380
381 if ( delimiters != null && !delimiters.isEmpty() )
382 {
383 LinkedHashSet<String> delims = new LinkedHashSet<String>();
384 if ( useDefaultDelimiters )
385 {
386
387 delims.addAll( mavenResourcesExecution.getDelimiters() );
388 }
389
390 for ( String delim : delimiters )
391 {
392 if ( delim == null )
393 {
394
395 delims.add( "${*}" );
396 }
397 else
398 {
399 delims.add( delim );
400 }
401 }
402
403 mavenResourcesExecution.setDelimiters( delims );
404 }
405
406 if ( nonFilteredFileExtensions != null )
407 {
408 mavenResourcesExecution.setNonFilteredFileExtensions( nonFilteredFileExtensions );
409 }
410 try
411 {
412 mavenResourcesFiltering.filterResources( mavenResourcesExecution );
413 }
414 catch ( MavenFilteringException e )
415 {
416 throw new MojoExecutionException( "Error copying RAR resources", e );
417 }
418
419
420 try
421 {
422 includeCustomRaXmlFile();
423 }
424 catch ( IOException e )
425 {
426 throw new MojoExecutionException( "Error copying ra.xml file", e );
427 }
428
429
430 File ddFile = new File( getBuildDir(), RA_XML_URI );
431 if ( !ddFile.exists() && warnOnMissingRaXml )
432 {
433 getLog().warn( "Connector deployment descriptor: " + ddFile.getAbsolutePath() + " does not exist." );
434 }
435
436 File rarFile = getRarFile(outputDirectory, finalName, classifier);
437 try
438 {
439 MavenArchiver archiver = new MavenArchiver();
440 archiver.setArchiver( jarArchiver );
441 archiver.setOutputFile( rarFile );
442
443
444 includeCustomManifestFile();
445
446 archiver.getArchiver().addDirectory( getBuildDir() );
447 archiver.createArchive( session, project, archive );
448 }
449 catch ( Exception e )
450 {
451 throw new MojoExecutionException( "Error assembling RAR", e );
452 }
453
454 if ( classifier != null )
455 {
456 projectHelper.attachArtifact( project, "rar", classifier, rarFile );
457 }
458 else
459 {
460 project.getArtifact().setFile( rarFile );
461 }
462 }
463
464 protected File getBuildDir()
465 {
466 if ( buildDir == null )
467 {
468 buildDir = new File( workDirectory );
469 }
470 return buildDir;
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 }