View Javadoc

1   package org.apache.maven.plugin.assembly.utils;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
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.codehaus.plexus.interpolation.InterpolationException;
29  import org.codehaus.plexus.interpolation.PrefixedObjectValueSource;
30  import org.codehaus.plexus.interpolation.PrefixedPropertiesValueSource;
31  import org.codehaus.plexus.interpolation.PropertiesBasedValueSource;
32  import org.codehaus.plexus.interpolation.StringSearchInterpolator;
33  import org.codehaus.plexus.util.StringUtils;
34  
35  import java.io.IOException;
36  import java.util.Collections;
37  import java.util.Properties;
38  
39  /**
40   * @version $Id: AssemblyFormatUtils.java 1005618 2010-10-07 20:43:22Z jdcasey $
41   */
42  public final class AssemblyFormatUtils
43  {
44  
45      private AssemblyFormatUtils()
46      {
47      }
48  
49      /**
50       * Get the full name of the distribution artifact
51       * 
52       * @param assembly
53       * @return the distribution name
54       */
55      public static String getDistributionName( final Assembly assembly, final AssemblerConfigurationSource configSource )
56      {
57          final String finalName = configSource.getFinalName();
58          final boolean appendAssemblyId = configSource.isAssemblyIdAppended();
59          final String classifier = configSource.getClassifier();
60  
61          String distributionName = finalName;
62          if ( appendAssemblyId )
63          {
64              if ( !StringUtils.isEmpty( assembly.getId() ) )
65              {
66                  distributionName = finalName + "-" + assembly.getId();
67              }
68          }
69          else if ( classifier != null )
70          {
71              distributionName = finalName + "-" + classifier;
72          }
73  
74          return distributionName;
75      }
76  
77      /**
78       * @deprecated Use
79       *             {@link AssemblyFormatUtils#getOutputDirectory(String, MavenProject, MavenProject, String, AssemblerConfigurationSource)}
80       *             instead.
81       */
82      @Deprecated
83      public static String getOutputDirectory( final String output, final MavenProject mainProject,
84                                               final MavenProject artifactProject, final String finalName )
85          throws AssemblyFormattingException
86      {
87          return getOutputDirectory( output, mainProject, null, artifactProject, finalName, null );
88      }
89  
90      public static String getOutputDirectory( final String output, final MavenProject mainProject,
91                                               final MavenProject artifactProject, final String finalName,
92                                               final AssemblerConfigurationSource configSource )
93          throws AssemblyFormattingException
94      {
95          return getOutputDirectory( output, mainProject, null, artifactProject, finalName, configSource );
96      }
97  
98      /**
99       * ORDER OF INTERPOLATION PRECEDENCE:
100      * <ol>
101      * <li>Support for special expressions, like ${finalName} (use the assembly plugin configuration not the build
102      * config)</li>
103      * <li>prefixed with "module." if moduleProject is non-null
104      * <ol>
105      * <li>MavenProject instance for module being assembled</li>
106      * </ol>
107      * </li>
108      * <li>prefixed with "artifact." if artifactProject is non-null
109      * <ol>
110      * <li>MavenProject instance for artifact</li>
111      * </ol>
112      * </li>
113      * <li>user-defined properties from the command line</li>
114      * <li>prefixed with "pom." or "project.", or no prefix at all
115      * <ol>
116      * <li>MavenProject instance from current build</li>
117      * </ol>
118      * </li>
119      * <li>properties from main project</li>
120      * <li>system properties, from the MavenSession instance (to support IDEs)</li>
121      * <li>environment variables.</li>
122      * </ol>
123      */
124     public static String getOutputDirectory( final String output, final MavenProject mainProject,
125                                              final MavenProject moduleProject, final MavenProject artifactProject,
126                                              final String finalName, final AssemblerConfigurationSource configSource )
127         throws AssemblyFormattingException
128     {
129         String value = output;
130         if ( value == null )
131         {
132             value = "";
133         }
134 
135         final StringSearchInterpolator interpolator = new StringSearchInterpolator();
136 
137         final Properties specialExpressionOverrides = new Properties();
138 
139         if ( finalName != null )
140         {
141             specialExpressionOverrides.setProperty( "finalName", finalName );
142             specialExpressionOverrides.setProperty( "build.finalName", finalName );
143         }
144 
145         // 1
146         interpolator.addValueSource( new PropertiesBasedValueSource( specialExpressionOverrides ) );
147 
148         if ( moduleProject != null )
149         {
150             // 2
151             interpolator.addValueSource( new PrefixedObjectValueSource( "module.", moduleProject ) );
152             interpolator.addValueSource( new PrefixedPropertiesValueSource( "module.properties.",
153                                                                             moduleProject.getProperties() ) );
154             if ( moduleProject.getArtifact() != null )
155             {
156                 interpolator.addValueSource( new PrefixedObjectValueSource( "module.", moduleProject.getArtifact() ) );
157             }
158         }
159 
160         if ( artifactProject != null )
161         {
162             // 3
163             interpolator.addValueSource( new PrefixedObjectValueSource( "artifact.", artifactProject ) );
164             interpolator.addValueSource( new PrefixedPropertiesValueSource( "artifact.properties.",
165                                                                             artifactProject.getProperties() ) );
166             if ( artifactProject.getArtifact() != null )
167             {
168                 interpolator.addValueSource( new PrefixedObjectValueSource( "artifact.", artifactProject.getArtifact() ) );
169             }
170         }
171 
172         MavenSession session = null;
173 
174         if ( configSource != null )
175         {
176             session = configSource.getMavenSession();
177 
178             if ( session != null )
179             {
180                 Properties userProperties = null;
181                 try
182                 {
183                     userProperties = session.getExecutionProperties();
184                 }
185                 catch ( final NoSuchMethodError nsmer )
186                 {
187                     // OK, so user is using Maven <= 2.0.8. No big deal.
188                 }
189 
190                 if ( userProperties != null )
191                 {
192                     // 4
193                     interpolator.addValueSource( new PropertiesBasedValueSource( userProperties ) );
194                 }
195             }
196         }
197 
198         if ( mainProject != null )
199         {
200             // 5
201             interpolator.addValueSource( new PrefixedObjectValueSource( InterpolationConstants.PROJECT_PREFIXES,
202                                                                         mainProject, true ) );
203 
204             // 6
205             interpolator.addValueSource( new PrefixedPropertiesValueSource(
206                                                                             InterpolationConstants.PROJECT_PROPERTIES_PREFIXES,
207                                                                             mainProject.getProperties(), true ) );
208         }
209 
210         Properties commandLineProperties = System.getProperties();
211         if ( session != null )
212         {
213             commandLineProperties = new Properties();
214             if ( session.getExecutionProperties() != null )
215             {
216                 commandLineProperties.putAll( session.getExecutionProperties() );
217             }
218 
219             if ( session.getUserProperties() != null )
220             {
221                 commandLineProperties.putAll( session.getUserProperties() );
222             }
223         }
224 
225         // 7
226         interpolator.addValueSource( new PropertiesBasedValueSource( commandLineProperties ) );
227 
228         try
229         {
230             // 8
231             interpolator.addValueSource( new PrefixedPropertiesValueSource( Collections.singletonList( "env." ),
232                                                                             CommandLineUtils.getSystemEnvVars( false ),
233                                                                             true ) );
234         }
235         catch ( final IOException e )
236         {
237             throw new AssemblyFormattingException( "Failed to retrieve OS environment variables. Reason: "
238                             + e.getMessage(), e );
239         }
240 
241         try
242         {
243             value = interpolator.interpolate( value );
244         }
245         catch ( final InterpolationException e )
246         {
247             throw new AssemblyFormattingException( "Failed to interpolate output directory. Reason: " + e.getMessage(),
248                                                    e );
249         }
250 
251         if ( ( value.length() > 0 ) && !value.endsWith( "/" ) && !value.endsWith( "\\" ) )
252         {
253             value += "/";
254         }
255 
256         if ( ( value.length() > 0 ) && ( value.startsWith( "/" ) || value.startsWith( "\\" ) ) )
257         {
258             value = value.substring( 1 );
259         }
260 
261         value = StringUtils.replace( value, "//", "/" );
262         value = StringUtils.replace( value, "\\\\", "\\" );
263         value = StringUtils.replace( value, "./", "" );
264         value = StringUtils.replace( value, ".\\", "" );
265 
266         return value;
267     }
268 
269     /**
270      * @deprecated Use
271      *             {@link AssemblyFormatUtils#evaluateFileNameMapping(String, Artifact, MavenProject, MavenProject, AssemblerConfigurationSource)}
272      *             instead.
273      */
274     @Deprecated
275     public static String evaluateFileNameMapping( final String expression, final Artifact artifact,
276                                                   final MavenProject mainProject, final MavenProject artifactProject )
277         throws AssemblyFormattingException
278     {
279         return evaluateFileNameMapping( expression, artifact, mainProject, null, null, artifactProject, null );
280     }
281 
282     public static String evaluateFileNameMapping( final String expression, final Artifact artifact,
283                                                   final MavenProject mainProject, final MavenProject artifactProject,
284                                                   final AssemblerConfigurationSource configSource )
285         throws AssemblyFormattingException
286     {
287         return evaluateFileNameMapping( expression, artifact, mainProject, null, null, artifactProject, configSource );
288     }
289 
290     /**
291      * ORDER OF INTERPOLATION PRECEDENCE:
292      * <ol>
293      * <li>prefixed with "module.", if moduleProject != null
294      * <ol>
295      * <li>Artifact instance for module, if moduleArtifact != null</li>
296      * <li>ArtifactHandler instance for module, if moduleArtifact != null</li>
297      * <li>MavenProject instance for module</li>
298      * </ol>
299      * </li>
300      * <li>prefixed with "artifact."
301      * <ol>
302      * <li>Artifact instance</li>
303      * <li>ArtifactHandler instance for artifact</li>
304      * <li>MavenProject instance for artifact</li>
305      * </ol>
306      * </li>
307      * <li>prefixed with "pom." or "project."
308      * <ol>
309      * <li>MavenProject instance from current build</li>
310      * </ol>
311      * </li>
312      * <li>no prefix, using main project instance
313      * <ol>
314      * <li>MavenProject instance from current build</li>
315      * </ol>
316      * </li>
317      * <li>Support for special expressions, like ${dashClassifier?}</li>
318      * <li>user-defined properties from the command line</li>
319      * <li>properties from main project</li>
320      * <li>system properties, from the MavenSession instance (to support IDEs)</li>
321      * <li>environment variables.</li>
322      * </ol>
323      */
324     public static String evaluateFileNameMapping( final String expression, final Artifact artifact,
325                                                   final MavenProject mainProject, final MavenProject moduleProject,
326                                                   final Artifact moduleArtifact, final MavenProject artifactProject,
327                                                   final AssemblerConfigurationSource configSource )
328         throws AssemblyFormattingException
329     {
330         String value = expression;
331 
332         // TODO: This is BAD! Accessors SHOULD NOT change the behavior of the object.
333         // [jdcasey; 16-Aug-1007] This is fixed in SVN, just waiting for it to pass out of legacy.
334         artifact.isSnapshot();
335 
336         final StringSearchInterpolator interpolator = new StringSearchInterpolator();
337 
338         if ( moduleArtifact != null )
339         {
340             // 1A
341             interpolator.addValueSource( new PrefixedObjectValueSource( "module.", moduleArtifact ) );
342 
343             // 1B
344             interpolator.addValueSource( new PrefixedObjectValueSource( "module.", moduleArtifact.getArtifactHandler() ) );
345             interpolator.addValueSource( new PrefixedObjectValueSource( "module.handler.",
346                                                                         moduleArtifact.getArtifactHandler() ) );
347         }
348 
349         // 1C
350         if ( moduleProject != null )
351         {
352             interpolator.addValueSource( new PrefixedObjectValueSource( "module.", moduleProject ) );
353             interpolator.addValueSource( new PrefixedPropertiesValueSource( "module.properties.",
354                                                                             moduleProject.getProperties() ) );
355             if ( moduleProject.getArtifact() != null )
356             {
357                 interpolator.addValueSource( new PrefixedObjectValueSource( "module.", moduleProject.getArtifact() ) );
358             }
359         }
360 
361         // 2A
362         interpolator.addValueSource( new PrefixedObjectValueSource( "artifact.", artifact ) );
363 
364         // 2B
365         interpolator.addValueSource( new PrefixedObjectValueSource( "artifact.", artifact.getArtifactHandler() ) );
366         interpolator.addValueSource( new PrefixedObjectValueSource( "artifact.handler.", artifact.getArtifactHandler() ) );
367 
368         // 2C
369         if ( artifactProject != null )
370         {
371             interpolator.addValueSource( new PrefixedObjectValueSource( "artifact.", artifactProject ) );
372             interpolator.addValueSource( new PrefixedPropertiesValueSource( "artifact.properties.",
373                                                                             artifactProject.getProperties() ) );
374             if ( artifactProject.getArtifact() != null )
375             {
376                 interpolator.addValueSource( new PrefixedObjectValueSource( "artifact.", artifactProject.getArtifact() ) );
377             }
378         }
379 
380         if ( mainProject != null )
381         {
382             // 3
383             // 4
384             interpolator.addValueSource( new PrefixedObjectValueSource( InterpolationConstants.PROJECT_PREFIXES,
385                                                                         mainProject, true ) );
386         }
387 
388         final Properties specialRules = new Properties();
389 
390         final String classifier = artifact.getClassifier();
391         if ( classifier != null )
392         {
393             specialRules.setProperty( "dashClassifier?", "-" + classifier );
394             specialRules.setProperty( "dashClassifier", "-" + classifier );
395         }
396         else
397         {
398             specialRules.setProperty( "dashClassifier?", "" );
399             specialRules.setProperty( "dashClassifier", "" );
400         }
401 
402         // 5
403         interpolator.addValueSource( new PropertiesBasedValueSource( specialRules ) );
404 
405         MavenSession session = null;
406         if ( configSource != null )
407         {
408             session = configSource.getMavenSession();
409 
410             if ( session != null )
411             {
412                 Properties userProperties = null;
413                 try
414                 {
415                     userProperties = session.getExecutionProperties();
416                 }
417                 catch ( final NoSuchMethodError nsmer )
418                 {
419                     // OK, so user is using Maven <= 2.0.8. No big deal.
420                 }
421 
422                 if ( userProperties != null )
423                 {
424                     // 6
425                     interpolator.addValueSource( new PropertiesBasedValueSource( userProperties ) );
426                 }
427             }
428         }
429 
430         if ( mainProject != null )
431         {
432             // 7
433             interpolator.addValueSource( new PrefixedPropertiesValueSource(
434                                                                             InterpolationConstants.PROJECT_PROPERTIES_PREFIXES,
435                                                                             mainProject.getProperties(), true ) );
436         }
437 
438         Properties commandLineProperties = System.getProperties();
439         if ( session != null )
440         {
441             commandLineProperties = new Properties();
442             if ( session.getExecutionProperties() != null )
443             {
444                 commandLineProperties.putAll( session.getExecutionProperties() );
445             }
446 
447             if ( session.getUserProperties() != null )
448             {
449                 commandLineProperties.putAll( session.getUserProperties() );
450             }
451         }
452 
453         // 8
454         interpolator.addValueSource( new PropertiesBasedValueSource( commandLineProperties ) );
455 
456         try
457         {
458             // 9
459             interpolator.addValueSource( new PrefixedPropertiesValueSource( Collections.singletonList( "env." ),
460                                                                             CommandLineUtils.getSystemEnvVars( false ),
461                                                                             true ) );
462         }
463         catch ( final IOException e )
464         {
465             throw new AssemblyFormattingException( "Failed to retrieve OS environment variables. Reason: "
466                             + e.getMessage(), e );
467         }
468 
469         try
470         {
471             value = interpolator.interpolate( value );
472         }
473         catch ( final InterpolationException e )
474         {
475             throw new AssemblyFormattingException( "Failed to interpolate output filename mapping. Reason: "
476                             + e.getMessage(), e );
477         }
478 
479         value = StringUtils.replace( value, "//", "/" );
480         value = StringUtils.replace( value, "\\\\", "\\" );
481         value = StringUtils.replace( value, "./", "" );
482         value = StringUtils.replace( value, ".\\", "" );
483 
484         return value;
485     }
486 
487 }