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