1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugins.assembly.utils;
20
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.Collections;
24 import java.util.List;
25 import java.util.ListIterator;
26 import java.util.Properties;
27
28 import org.apache.maven.artifact.Artifact;
29 import org.apache.maven.execution.MavenSession;
30 import org.apache.maven.plugins.assembly.AssemblerConfigurationSource;
31 import org.apache.maven.plugins.assembly.format.AssemblyFormattingException;
32 import org.apache.maven.plugins.assembly.model.Assembly;
33 import org.apache.maven.project.MavenProject;
34 import org.codehaus.plexus.interpolation.fixed.FixedStringSearchInterpolator;
35 import org.codehaus.plexus.interpolation.fixed.MapBasedValueSource;
36 import org.codehaus.plexus.interpolation.fixed.PrefixedObjectValueSource;
37 import org.codehaus.plexus.interpolation.fixed.PrefixedPropertiesValueSource;
38 import org.codehaus.plexus.interpolation.fixed.PropertiesBasedValueSource;
39 import org.codehaus.plexus.util.Os;
40 import org.codehaus.plexus.util.StringUtils;
41 import org.slf4j.Logger;
42
43
44
45
46 public final class AssemblyFormatUtils {
47
48 private AssemblyFormatUtils() {}
49
50
51
52
53
54
55
56 public static String getDistributionName(final Assembly assembly, final AssemblerConfigurationSource configSource) {
57 final String finalName = configSource.getFinalName();
58 final boolean appendAssemblyId = configSource.isAssemblyIdAppended();
59
60 String distributionName = finalName;
61 if (appendAssemblyId) {
62 distributionName = finalName + "-" + assembly.getId();
63 }
64
65 return distributionName;
66 }
67
68 public static FixedStringSearchInterpolator finalNameInterpolator(String finalName) {
69 final Properties specialExpressionOverrides = new Properties();
70
71 if (finalName != null) {
72 specialExpressionOverrides.setProperty("finalName", finalName);
73 specialExpressionOverrides.setProperty("build.finalName", finalName);
74 } else {
75 return FixedStringSearchInterpolator.empty();
76 }
77
78 return FixedStringSearchInterpolator.create(new PropertiesBasedValueSource(specialExpressionOverrides));
79 }
80
81 public static FixedStringSearchInterpolator moduleProjectInterpolator(final MavenProject moduleProject) {
82 if (moduleProject != null) {
83 return FixedStringSearchInterpolator.createWithPermittedNulls(
84 new PrefixedObjectValueSource("module.", moduleProject),
85 new PrefixedPropertiesValueSource("module.properties.", moduleProject.getProperties()),
86 moduleProject.getArtifact() != null
87 ? new PrefixedObjectValueSource("module.", moduleProject.getArtifact())
88 : null);
89 } else {
90 return FixedStringSearchInterpolator.empty();
91 }
92 }
93
94 public static FixedStringSearchInterpolator moduleArtifactInterpolator(Artifact moduleArtifact) {
95 if (moduleArtifact != null) {
96 final String groupIdPath = moduleArtifact.getGroupId().replace('.', '/');
97
98 return FixedStringSearchInterpolator.create(
99 new MapBasedValueSource(Collections.singletonMap("module.groupIdPath", groupIdPath)),
100 new PrefixedObjectValueSource("module.", moduleArtifact),
101 new PrefixedObjectValueSource("module.", moduleArtifact.getArtifactHandler()),
102 new PrefixedObjectValueSource("module.handler.", moduleArtifact.getArtifactHandler()));
103 } else {
104 return FixedStringSearchInterpolator.empty();
105 }
106 }
107
108 public static FixedStringSearchInterpolator artifactProjectInterpolator(final MavenProject artifactProject) {
109 if (artifactProject != null) {
110 PrefixedObjectValueSource vs = null;
111 if (artifactProject.getArtifact() != null) {
112 vs = new PrefixedObjectValueSource("artifact.", artifactProject.getArtifact());
113 }
114
115 final String groupIdPath = artifactProject.getGroupId().replace('.', '/');
116
117 return FixedStringSearchInterpolator.createWithPermittedNulls(
118 new MapBasedValueSource(Collections.singletonMap("artifact.groupIdPath", groupIdPath)),
119 new PrefixedObjectValueSource("artifact.", artifactProject),
120 new PrefixedPropertiesValueSource("artifact.properties.", artifactProject.getProperties()),
121 vs);
122 } else {
123 return FixedStringSearchInterpolator.empty();
124 }
125 }
126
127 public static FixedStringSearchInterpolator artifactInterpolator(final Artifact artifact) {
128 final String groupIdPath = artifact.getGroupId().replace('.', '/');
129
130 return FixedStringSearchInterpolator.create(
131 new MapBasedValueSource(Collections.singletonMap("artifact.groupIdPath", groupIdPath)),
132 new PrefixedObjectValueSource("artifact.", artifact),
133 new PrefixedObjectValueSource("artifact.", artifact.getArtifactHandler()),
134 new PrefixedObjectValueSource("artifact.handler.", artifact.getArtifactHandler()));
135 }
136
137 public static FixedStringSearchInterpolator classifierRules(final Artifact artifact) {
138 final Properties specialRules = new Properties();
139
140 final String classifier = ProjectUtils.getClassifier(artifact);
141 if (classifier != null) {
142 specialRules.setProperty("dashClassifier?", "-" + classifier);
143 specialRules.setProperty("dashClassifier", "-" + classifier);
144 } else {
145 specialRules.setProperty("dashClassifier?", "");
146 specialRules.setProperty("dashClassifier", "");
147 }
148
149 return FixedStringSearchInterpolator.create(new PropertiesBasedValueSource(specialRules));
150 }
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178 public static String getOutputDirectory(
179 final String output,
180 final MavenProject artifactProject,
181 final String finalName,
182 final AssemblerConfigurationSource configSource)
183 throws AssemblyFormattingException {
184 return getOutputDirectory(
185 output,
186 finalName,
187 configSource,
188 moduleProjectInterpolator(null),
189 artifactProjectInterpolator(artifactProject));
190 }
191
192 private static FixedStringSearchInterpolator executionPropertiesInterpolator(
193 AssemblerConfigurationSource configSource) {
194 MavenSession session;
195
196 if (configSource != null) {
197 session = configSource.getMavenSession();
198
199 if (session != null) {
200 Properties userProperties = session.getExecutionProperties();
201
202 if (userProperties != null) {
203 return FixedStringSearchInterpolator.create(new PropertiesBasedValueSource(userProperties));
204 }
205 }
206 }
207 return FixedStringSearchInterpolator.empty();
208 }
209
210 private static FixedStringSearchInterpolator mainProjectOnlyInterpolator(MavenProject mainProject) {
211 if (mainProject != null) {
212
213 return FixedStringSearchInterpolator.create(
214 new org.codehaus.plexus.interpolation.fixed.PrefixedObjectValueSource(
215 InterpolationConstants.PROJECT_PREFIXES, mainProject, true));
216 } else {
217 return FixedStringSearchInterpolator.empty();
218 }
219 }
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255 public static String fixRelativeRefs(String src) {
256 String value = src;
257
258 String[] separators = {"/", "\\"};
259
260 String finalSep = null;
261 for (String sep : separators) {
262 if (value.endsWith(sep)) {
263 finalSep = sep;
264 }
265
266 if (value.contains("." + sep)) {
267 List<String> parts = new ArrayList<>();
268 parts.addAll(Arrays.asList(value.split(sep.replace("\\", "\\\\"))));
269
270 for (ListIterator<String> it = parts.listIterator(); it.hasNext(); ) {
271 String part = it.next();
272 if (".".equals(part)) {
273 it.remove();
274 } else if ("..".equals(part)) {
275 it.remove();
276 if (it.hasPrevious()) {
277 it.previous();
278 it.remove();
279 }
280 }
281 }
282
283 value = StringUtils.join(parts.iterator(), sep);
284 }
285 }
286
287 if (finalSep != null && value.length() > 0 && !value.endsWith(finalSep)) {
288 value += finalSep;
289 }
290
291 return value;
292 }
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328 public static String evaluateFileNameMapping(
329 final String expression,
330 final Artifact artifact,
331 final MavenProject mainProject,
332 final Artifact moduleArtifact,
333 final AssemblerConfigurationSource configSource,
334 FixedStringSearchInterpolator moduleProjectInterpolator,
335 FixedStringSearchInterpolator artifactProjectInterpolator) {
336 String value = expression;
337
338 final FixedStringSearchInterpolator interpolator = FixedStringSearchInterpolator.create(
339 moduleArtifactInterpolator(moduleArtifact),
340 moduleProjectInterpolator,
341 artifactInterpolator(artifact),
342 artifactProjectInterpolator,
343 mainProjectOnlyInterpolator(mainProject),
344 classifierRules(artifact),
345 executionPropertiesInterpolator(configSource),
346 configSource.getMainProjectInterpolator(),
347 configSource.getCommandLinePropsInterpolator(),
348 configSource.getEnvInterpolator());
349
350 value = interpolator.interpolate(value);
351
352 value = StringUtils.replace(value, "//", "/");
353 value = StringUtils.replace(value, "\\\\", "\\");
354 value = fixRelativeRefs(value);
355
356 return value;
357 }
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385 public static String getOutputDirectory(
386 final String output,
387 final String finalName,
388 final AssemblerConfigurationSource configSource,
389 FixedStringSearchInterpolator moduleProjectIntrpolator,
390 FixedStringSearchInterpolator artifactProjectInterpolator)
391 throws AssemblyFormattingException {
392 String value = output;
393 if (value == null) {
394 value = "";
395 }
396
397 final FixedStringSearchInterpolator interpolator = FixedStringSearchInterpolator.create(
398 finalNameInterpolator(finalName),
399 moduleProjectIntrpolator,
400 artifactProjectInterpolator,
401 executionPropertiesInterpolator(configSource),
402 configSource.getMainProjectInterpolator(),
403 configSource.getCommandLinePropsInterpolator(),
404 configSource.getEnvInterpolator());
405
406 value = interpolator.interpolate(value);
407
408 if ((value.length() > 0) && !value.endsWith("/") && !value.endsWith("\\")) {
409 value += "/";
410 }
411
412 if ((value.length() > 0) && (value.startsWith("/") || value.startsWith("\\"))) {
413 value = value.substring(1);
414 }
415
416 value = StringUtils.replace(value, "//", "/");
417 value = StringUtils.replace(value, "\\\\", "\\");
418 value = fixRelativeRefs(value);
419
420 return value;
421 }
422
423 public static void warnForPlatformSpecifics(Logger logger, String destDirectory) {
424 if (Os.isFamily(Os.FAMILY_WINDOWS)) {
425 if (isUnixRootReference(destDirectory)) {
426 logger.error("OS=Windows and the assembly descriptor contains a *nix-specific root-relative reference"
427 + " (starting with slash): " + destDirectory);
428 } else if (isWindowsPath(destDirectory)) {
429 logger.warn("The assembly descriptor contains a Windows-specific directory reference"
430 + " (with a drive letter). This is not portable and will fail on non-Windows: "
431 + destDirectory);
432 }
433 } else {
434 if (isWindowsPath(destDirectory)) {
435 logger.error(
436 "OS=Non-Windows and the assembly descriptor contains a Windows-specific directory reference"
437 + " (with a drive letter): " + destDirectory);
438 } else if (isUnixRootReference(destDirectory)) {
439 logger.warn("The assembly descriptor contains a *nix-specific root-relative reference"
440 + " (starting with slash). This is not portable and might fail on Windows: "
441 + destDirectory);
442 }
443 }
444 }
445
446 static boolean isWindowsPath(String destDirectory) {
447 return (destDirectory != null && destDirectory.length() >= 2 && destDirectory.charAt(1) == ':');
448 }
449
450 static boolean isUnixRootReference(String destDirectory) {
451 return (destDirectory != null && destDirectory.startsWith("/"));
452 }
453 }