View Javadoc
1   package org.apache.maven.plugins.dependency.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 java.io.BufferedReader;
23  import java.io.File;
24  import java.io.FileWriter;
25  import java.io.IOException;
26  import java.io.StringReader;
27  
28  import org.apache.maven.artifact.Artifact;
29  import org.apache.maven.artifact.ArtifactUtils;
30  import org.apache.maven.plugin.logging.Log;
31  import org.codehaus.plexus.util.IOUtil;
32  import org.codehaus.plexus.util.StringUtils;
33  
34  /**
35   * Utility class with static helper methods
36   * 
37   * @author <a href="mailto:brianf@apache.org">Brian Fox</a>
38   * @version $Id: DependencyUtil.java 1807877 2017-09-09 10:35:59Z khmarbaise $
39   */
40  public final class DependencyUtil
41  {
42  
43      /**
44       * Builds the file name. If removeVersion is set, then the file name must be reconstructed from the artifactId,
45       * Classifier (if used) and Type. Otherwise, this method returns the artifact file name.
46       * 
47       * @param artifact File to be formatted.
48       * @param removeVersion Specifies if the version should be removed from the file name.
49       * @return Formatted file name in the format artifactId-[version]-[classifier].[type]
50       * @see #getFormattedFileName(Artifact, boolean, boolean)
51       */
52      public static String getFormattedFileName( Artifact artifact, boolean removeVersion )
53      {
54          return getFormattedFileName( artifact, removeVersion, false );
55      }
56  
57      /**
58       * Builds the file name. If removeVersion is set, then the file name must be reconstructed from the groupId (if
59       * <b>prependGroupId</b> is true) artifactId, Classifier (if used) and Type. Otherwise, this method returns the
60       * artifact file name.
61       * 
62       * @param artifact File to be formatted.
63       * @param removeVersion Specifies if the version should be removed from the file name.
64       * @param prependGroupId Specifies if the groupId should be prepended to the file name.
65       * @return Formatted file name in the format [groupId].artifactId-[version]-[classifier].[type]
66       */
67      public static String getFormattedFileName( Artifact artifact, boolean removeVersion, boolean prependGroupId )
68      {
69          return getFormattedFileName( artifact, removeVersion, prependGroupId, false );
70      }
71  
72      /**
73       * Builds the file name. If removeVersion is set, then the file name must be reconstructed from the groupId (if
74       * <b>prependGroupId</b> is true) artifactId, Classifier (if used) and Type. Otherwise, this method returns the
75       * artifact file name.
76       * 
77       * @param artifact File to be formatted.
78       * @param removeVersion Specifies if the version should be removed from the file name.
79       * @param prependGroupId Specifies if the groupId should be prepended to the file name.
80       * @param useBaseVersion Specifies if the baseVersion of the artifact should be used instead of the version.
81       * @return Formatted file name in the format [groupId].artifactId-[version]-[classifier].[type]
82       */
83      public static String getFormattedFileName( Artifact artifact, boolean removeVersion, boolean prependGroupId,
84                                                 boolean useBaseVersion )
85      {
86          return getFormattedFileName( artifact, removeVersion, prependGroupId, useBaseVersion, false );
87      }
88  
89      /**
90       * Builds the file name. If removeVersion is set, then the file name must be reconstructed from the groupId (if
91       * <b>prependGroupId</b> is true) artifactId, Classifier (if used) and Type. Otherwise, this method returns the
92       * artifact file name.
93       * 
94       * @param artifact File to be formatted.
95       * @param removeVersion Specifies if the version should be removed from the file name.
96       * @param prependGroupId Specifies if the groupId should be prepended to the file name.
97       * @param useBaseVersion Specifies if the baseVersion of the artifact should be used instead of the version.
98       * @param removeClassifier Specifies if the classifier of the artifact should be remved from the file name.
99       * @return Formatted file name in the format [groupId].artifactId-[version]-[classifier].[type]
100      */
101     public static String getFormattedFileName( Artifact artifact, boolean removeVersion, boolean prependGroupId,
102                                                boolean useBaseVersion, boolean removeClassifier )
103     {
104         StringBuilder destFileName = new StringBuilder();
105 
106         if ( prependGroupId )
107         {
108             destFileName.append( artifact.getGroupId() ).append( "." );
109         }
110 
111         String versionString;
112         if ( !removeVersion )
113         {
114             if ( useBaseVersion )
115             {
116                 versionString = "-" + ArtifactUtils.toSnapshotVersion( artifact.getVersion() );
117             }
118             else
119             {
120                 versionString = "-" + artifact.getVersion();
121             }
122         }
123         else
124         {
125             versionString = "";
126         }
127 
128         String classifierString = "";
129 
130         if ( !removeClassifier && StringUtils.isNotEmpty( artifact.getClassifier() ) )
131         {
132             classifierString = "-" + artifact.getClassifier();
133         }
134         destFileName.append( artifact.getArtifactId() ).append( versionString );
135         destFileName.append( classifierString ).append( "." );
136         destFileName.append( artifact.getArtifactHandler().getExtension() );
137 
138         return destFileName.toString();
139     }
140 
141     /**
142      * Formats the outputDirectory based on type.
143      * 
144      * @param useSubdirsPerScope if a new sub directory should be used for each scope.
145      * @param useSubdirsPerType if a new sub directory should be used for each type.
146      * @param useSubdirPerArtifact if a new sub directory should be used for each artifact.
147      * @param useRepositoryLayout if dependencies must be moved into a Maven repository layout, if set, other settings
148      *            will be ignored.
149      * @param removeVersion if the version must not be mentioned in the filename
150      * @param outputDirectory base outputDirectory.
151      * @param artifact information about the artifact.
152      * @return a formatted File object to use for output.
153      */
154     public static File getFormattedOutputDirectory( boolean useSubdirsPerScope, boolean useSubdirsPerType,
155                                                     boolean useSubdirPerArtifact, boolean useRepositoryLayout,
156                                                     boolean removeVersion, File outputDirectory, Artifact artifact )
157     {
158         StringBuilder sb = new StringBuilder( 128 );
159         if ( useRepositoryLayout )
160         {
161             // group id
162             sb.append( artifact.getGroupId().replace( '.', File.separatorChar ) ).append( File.separatorChar );
163             // artifact id
164             sb.append( artifact.getArtifactId() ).append( File.separatorChar );
165             // version
166             sb.append( artifact.getBaseVersion() ).append( File.separatorChar );
167         }
168         else
169         {
170             if ( useSubdirsPerScope )
171             {
172                 sb.append( artifact.getScope() ).append( File.separatorChar );
173             }
174             if ( useSubdirsPerType )
175             {
176                 sb.append( artifact.getType() ).append( "s" ).append( File.separatorChar );
177             }
178             if ( useSubdirPerArtifact )
179             {
180                 String artifactString = getDependencyId( artifact, removeVersion );
181                 sb.append( artifactString ).append( File.separatorChar );
182             }
183         }
184         return new File( outputDirectory, sb.toString() );
185     }
186 
187     private static String getDependencyId( Artifact artifact, boolean removeVersion )
188     {
189         StringBuilder sb = new StringBuilder();
190 
191         sb.append( artifact.getArtifactId() );
192 
193         if ( !removeVersion )
194         {
195             sb.append( "-" );
196             sb.append( artifact.getVersion() );
197         }
198 
199         if ( StringUtils.isNotEmpty( artifact.getClassifier() ) )
200         {
201             sb.append( "-" );
202             sb.append( artifact.getClassifier() );
203         }
204 
205         // if the classifier and type are the same (sources), then don't
206         // repeat.
207         // avoids names like foo-sources-sources
208         if ( !StringUtils.equals( artifact.getClassifier(), artifact.getType() ) )
209         {
210             sb.append( "-" );
211             sb.append( artifact.getType() );
212         }
213 
214         return sb.toString();
215     }
216 
217     /**
218      * Writes the specified string to the specified file.
219      * 
220      * @param string the string to write
221      * @param file the file to write to
222      * @param append append to existing file or not.
223      * @param log where to send the logging output.
224      * @throws IOException if an I/O error occurs
225      */
226     public static synchronized void write( String string, File file, boolean append, Log log )
227         throws IOException
228     {
229         file.getParentFile().mkdirs();
230 
231         FileWriter writer = null;
232 
233         try
234         {
235             writer = new FileWriter( file, append );
236 
237             writer.write( string );
238 
239             writer.close();
240             writer = null;
241         }
242         finally
243         {
244             IOUtil.close( writer );
245         }
246     }
247 
248     /**
249      * Writes the specified string to the log at info level.
250      * 
251      * @param string the string to write
252      * @param log where to log information.
253      * @throws IOException if an I/O error occurs
254      */
255     public static synchronized void log( String string, Log log )
256         throws IOException
257     {
258         BufferedReader reader = new BufferedReader( new StringReader( string ) );
259 
260         String line;
261 
262         while ( ( line = reader.readLine() ) != null )
263         {
264             log.info( line );
265         }
266 
267         reader.close();
268     }
269 
270     //
271     // mainly used to parse excludes,includes configuration
272     //
273     public static String[] tokenizer( String str )
274     {
275         return StringUtils.split( cleanToBeTokenizedString( str ), "," );
276     }
277 
278     //
279     // clean up configuration string before it can be tokenized
280     //
281     public static String cleanToBeTokenizedString( String str )
282     {
283         String ret = "";
284         if ( !StringUtils.isEmpty( str ) )
285         {
286             // remove initial and ending spaces, plus all spaces next to commas
287             ret = str.trim().replaceAll( "[\\s]*,[\\s]*", "," );
288         }
289 
290         return ret;
291     }
292 }