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