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