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