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 }