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 return FixedStringSearchInterpolator.create(
201 new PropertiesBasedValueSource(session.getUserProperties()),
202 new PropertiesBasedValueSource(session.getSystemProperties()));
203 }
204 }
205 return FixedStringSearchInterpolator.empty();
206 }
207
208 private static FixedStringSearchInterpolator mainProjectOnlyInterpolator(MavenProject mainProject) {
209 if (mainProject != null) {
210
211 return FixedStringSearchInterpolator.create(
212 new org.codehaus.plexus.interpolation.fixed.PrefixedObjectValueSource(
213 InterpolationConstants.PROJECT_PREFIXES, mainProject, true));
214 } else {
215 return FixedStringSearchInterpolator.empty();
216 }
217 }
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 public static String fixRelativeRefs(String src) {
254 String value = src;
255
256 String[] separators = {"/", "\\"};
257
258 String finalSep = null;
259 for (String sep : separators) {
260 if (value.endsWith(sep)) {
261 finalSep = sep;
262 }
263
264 if (value.contains("." + sep)) {
265 List<String> parts = new ArrayList<>(Arrays.asList(value.split(sep.replace("\\", "\\\\"))));
266
267 for (ListIterator<String> it = parts.listIterator(); it.hasNext(); ) {
268 String part = it.next();
269 if (".".equals(part)) {
270 it.remove();
271 } else if ("..".equals(part)) {
272 it.remove();
273 if (it.hasPrevious()) {
274 it.previous();
275 it.remove();
276 }
277 }
278 }
279
280 value = StringUtils.join(parts.iterator(), sep);
281 }
282 }
283
284 if (finalSep != null && value.length() > 0 && !value.endsWith(finalSep)) {
285 value += finalSep;
286 }
287
288 return value;
289 }
290
291
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 public static String evaluateFileNameMapping(
326 final String expression,
327 final Artifact artifact,
328 final MavenProject mainProject,
329 final Artifact moduleArtifact,
330 final AssemblerConfigurationSource configSource,
331 FixedStringSearchInterpolator moduleProjectInterpolator,
332 FixedStringSearchInterpolator artifactProjectInterpolator) {
333 String value = expression;
334
335 final FixedStringSearchInterpolator interpolator = FixedStringSearchInterpolator.create(
336 moduleArtifactInterpolator(moduleArtifact),
337 moduleProjectInterpolator,
338 artifactInterpolator(artifact),
339 artifactProjectInterpolator,
340 mainProjectOnlyInterpolator(mainProject),
341 classifierRules(artifact),
342 executionPropertiesInterpolator(configSource),
343 configSource.getMainProjectInterpolator(),
344 configSource.getCommandLinePropsInterpolator(),
345 configSource.getEnvInterpolator());
346
347 value = interpolator.interpolate(value);
348
349 value = StringUtils.replace(value, "//", "/");
350 value = StringUtils.replace(value, "\\\\", "\\");
351 value = fixRelativeRefs(value);
352
353 return value;
354 }
355
356
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 public static String getOutputDirectory(
383 final String output,
384 final String finalName,
385 final AssemblerConfigurationSource configSource,
386 FixedStringSearchInterpolator moduleProjectIntrpolator,
387 FixedStringSearchInterpolator artifactProjectInterpolator)
388 throws AssemblyFormattingException {
389 String value = output;
390 if (value == null) {
391 value = "";
392 }
393
394 final FixedStringSearchInterpolator interpolator = FixedStringSearchInterpolator.create(
395 finalNameInterpolator(finalName),
396 moduleProjectIntrpolator,
397 artifactProjectInterpolator,
398 executionPropertiesInterpolator(configSource),
399 configSource.getMainProjectInterpolator(),
400 configSource.getCommandLinePropsInterpolator(),
401 configSource.getEnvInterpolator());
402
403 value = interpolator.interpolate(value);
404
405 if ((value.length() > 0) && !value.endsWith("/") && !value.endsWith("\\")) {
406 value += "/";
407 }
408
409 if ((value.length() > 0) && (value.startsWith("/") || value.startsWith("\\"))) {
410 value = value.substring(1);
411 }
412
413 value = StringUtils.replace(value, "//", "/");
414 value = StringUtils.replace(value, "\\\\", "\\");
415 value = fixRelativeRefs(value);
416
417 return value;
418 }
419
420 public static void warnForPlatformSpecifics(Logger logger, String destDirectory) {
421 if (Os.isFamily(Os.FAMILY_WINDOWS)) {
422 if (isUnixRootReference(destDirectory)) {
423 logger.error("OS=Windows and the assembly descriptor contains a *nix-specific root-relative reference"
424 + " (starting with slash): " + destDirectory);
425 } else if (isWindowsPath(destDirectory)) {
426 logger.warn("The assembly descriptor contains a Windows-specific directory reference"
427 + " (with a drive letter). This is not portable and will fail on non-Windows: "
428 + destDirectory);
429 }
430 } else {
431 if (isWindowsPath(destDirectory)) {
432 logger.error(
433 "OS=Non-Windows and the assembly descriptor contains a Windows-specific directory reference"
434 + " (with a drive letter): " + destDirectory);
435 } else if (isUnixRootReference(destDirectory)) {
436 logger.warn("The assembly descriptor contains a *nix-specific root-relative reference"
437 + " (starting with slash). This is not portable and might fail on Windows: "
438 + destDirectory);
439 }
440 }
441 }
442
443 static boolean isWindowsPath(String destDirectory) {
444 return (destDirectory != null && destDirectory.length() >= 2 && destDirectory.charAt(1) == ':');
445 }
446
447 static boolean isUnixRootReference(String destDirectory) {
448 return (destDirectory != null && destDirectory.startsWith("/"));
449 }
450 }