View Javadoc
1   package org.apache.maven.artifact.resolver;
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.util.Iterator;
23  import java.util.List;
24  
25  import org.apache.maven.artifact.Artifact;
26  import org.apache.maven.artifact.repository.ArtifactRepository;
27  import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
28  
29  /**
30   * Base class for artifact resolution exceptions.
31   *
32   * @author <a href="mailto:brett@apache.org">Brett Porter</a>
33   */
34  public class AbstractArtifactResolutionException
35      extends Exception
36  {
37      private String groupId;
38  
39      private String artifactId;
40  
41      private String version;
42  
43      private String type;
44  
45      private String classifier;
46  
47      private Artifact artifact;
48  
49      private List<ArtifactRepository> remoteRepositories;
50  
51      private final String originalMessage;
52  
53      private final String path;
54  
55      static final String LS = System.lineSeparator();
56  
57      @SuppressWarnings( "checkstyle:parameternumber" )
58      protected AbstractArtifactResolutionException( String message,
59                                                     String groupId,
60                                                     String artifactId,
61                                                     String version,
62                                                     String type,
63                                                     String classifier,
64                                                     List<ArtifactRepository> remoteRepositories,
65                                                     List<String> path )
66      {
67          this( message, groupId, artifactId, version, type, classifier, remoteRepositories, path, null );
68      }
69  
70      @SuppressWarnings( "checkstyle:parameternumber" )
71      protected AbstractArtifactResolutionException( String message,
72                                                     String groupId,
73                                                     String artifactId,
74                                                     String version,
75                                                     String type,
76                                                     String classifier,
77                                                     List<ArtifactRepository> remoteRepositories,
78                                                     List<String> path,
79                                                     Throwable t )
80      {
81          super( constructMessageBase( message, groupId, artifactId, version, type, remoteRepositories, path ), t );
82  
83          this.originalMessage = message;
84          this.groupId = groupId;
85          this.artifactId = artifactId;
86          this.type = type;
87          this.classifier = classifier;
88          this.version = version;
89          this.remoteRepositories = remoteRepositories;
90          this.path = constructArtifactPath( path, "" );
91      }
92  
93      protected AbstractArtifactResolutionException( String message,
94                                                     Artifact artifact )
95      {
96          this( message, artifact, null );
97      }
98  
99      protected AbstractArtifactResolutionException( String message,
100                                                    Artifact artifact,
101                                                    List<ArtifactRepository> remoteRepositories )
102     {
103         this( message, artifact, remoteRepositories, null );
104     }
105 
106     protected AbstractArtifactResolutionException( String message,
107                                                    Artifact artifact,
108                                                    List<ArtifactRepository> remoteRepositories,
109                                                    Throwable t )
110     {
111         this( message, artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(), artifact.getType(),
112             artifact.getClassifier(), remoteRepositories, artifact.getDependencyTrail(), t );
113         this.artifact = artifact;
114     }
115 
116     public Artifact getArtifact()
117     {
118         return artifact;
119     }
120 
121     public String getGroupId()
122     {
123         return groupId;
124     }
125 
126     public String getArtifactId()
127     {
128         return artifactId;
129     }
130 
131     public String getVersion()
132     {
133         return version;
134     }
135 
136     public String getType()
137     {
138         return type;
139     }
140 
141     /** @return the classifier */
142     public String getClassifier()
143     {
144         return this.classifier;
145     }
146 
147     /** @return the path */
148     public String getPath()
149     {
150         return this.path;
151     }
152 
153     public List<ArtifactRepository> getRemoteRepositories()
154     {
155         return remoteRepositories;
156     }
157 
158     public String getOriginalMessage()
159     {
160         return originalMessage;
161     }
162 
163     protected static String constructArtifactPath( List<String> path,
164                                                    String indentation )
165     {
166         StringBuilder sb = new StringBuilder();
167 
168         if ( path != null )
169         {
170             sb.append( LS );
171             sb.append( indentation );
172             sb.append( "Path to dependency: " );
173             sb.append( LS );
174             int num = 1;
175             for ( Iterator<String> i = path.iterator(); i.hasNext(); num++ )
176             {
177                 sb.append( indentation );
178                 sb.append( '\t' );
179                 sb.append( num );
180                 sb.append( ") " );
181                 sb.append( i.next() );
182                 sb.append( LS );
183             }
184         }
185 
186         return sb.toString();
187     }
188 
189     private static String constructMessageBase( String message,
190                                                 String groupId,
191                                                 String artifactId,
192                                                 String version,
193                                                 String type,
194                                                 List<ArtifactRepository> remoteRepositories,
195                                                 List<String> path )
196     {
197         StringBuilder sb = new StringBuilder();
198 
199         sb.append( message );
200 
201         if ( message == null || !message.contains( "from the specified remote repositories:" ) )
202         {
203             sb.append( LS );
204             sb.append( "  " ).append( groupId ).append( ':' ).append( artifactId ).append( ':' ).append( type ).append(
205                 ':' ).append( version );
206             sb.append( LS );
207             if ( remoteRepositories != null )
208             {
209                 sb.append( LS );
210                 sb.append( "from the specified remote repositories:" );
211                 sb.append( LS ).append( "  " );
212 
213                 if ( remoteRepositories.isEmpty() )
214                 {
215                     sb.append( "(none)" );
216                 }
217 
218                 for ( Iterator<ArtifactRepository> i = remoteRepositories.iterator(); i.hasNext(); )
219                 {
220                     ArtifactRepository remoteRepository = i.next();
221 
222                     sb.append( remoteRepository.getId() );
223                     sb.append( " (" );
224                     sb.append( remoteRepository.getUrl() );
225 
226                     ArtifactRepositoryPolicy releases = remoteRepository.getReleases();
227                     if ( releases != null )
228                     {
229                         sb.append( ", releases=" ).append( releases.isEnabled() );
230                     }
231 
232                     ArtifactRepositoryPolicy snapshots = remoteRepository.getSnapshots();
233                     if ( snapshots != null )
234                     {
235                         sb.append( ", snapshots=" ).append( snapshots.isEnabled() );
236                     }
237 
238                     sb.append( ')' );
239                     if ( i.hasNext() )
240                     {
241                         sb.append( ',' ).append( LS ).append( "  " );
242                     }
243                 }
244             }
245 
246             sb.append( constructArtifactPath( path, "" ) );
247             sb.append( LS );
248         }
249 
250         return sb.toString();
251     }
252 
253     @SuppressWarnings( "checkstyle:parameternumber" )
254     protected static String constructMissingArtifactMessage( String message,
255                                                              String indentation,
256                                                              String groupId,
257                                                              String artifactId,
258                                                              String version,
259                                                              String type,
260                                                              String classifier,
261                                                              String downloadUrl,
262                                                              List<String> path )
263     {
264         StringBuilder sb = new StringBuilder( message );
265 
266         if ( !"pom".equals( type ) )
267         {
268             if ( downloadUrl != null )
269             {
270                 sb.append( LS );
271                 sb.append( LS );
272                 sb.append( indentation );
273                 sb.append( "Try downloading the file manually from: " );
274                 sb.append( LS );
275                 sb.append( indentation );
276                 sb.append( "    " );
277                 sb.append( downloadUrl );
278             }
279             else
280             {
281                 sb.append( LS );
282                 sb.append( LS );
283                 sb.append( indentation );
284                 sb.append( "Try downloading the file manually from the project website." );
285             }
286 
287             sb.append( LS );
288             sb.append( LS );
289             sb.append( indentation );
290             sb.append( "Then, install it using the command: " );
291             sb.append( LS );
292             sb.append( indentation );
293             sb.append( "    mvn install:install-file -DgroupId=" );
294             sb.append( groupId );
295             sb.append( " -DartifactId=" );
296             sb.append( artifactId );
297             sb.append( " -Dversion=" );
298             sb.append( version );
299 
300             //insert classifier only if it was used in the artifact
301             if ( classifier != null && !classifier.equals( "" ) )
302             {
303                 sb.append( " -Dclassifier=" );
304                 sb.append( classifier );
305             }
306             sb.append( " -Dpackaging=" );
307             sb.append( type );
308             sb.append( " -Dfile=/path/to/file" );
309             sb.append( LS );
310 
311             // If people want to deploy it
312             sb.append( LS );
313             sb.append( indentation );
314             sb.append( "Alternatively, if you host your own repository you can deploy the file there: " );
315             sb.append( LS );
316             sb.append( indentation );
317             sb.append( "    mvn deploy:deploy-file -DgroupId=" );
318             sb.append( groupId );
319             sb.append( " -DartifactId=" );
320             sb.append( artifactId );
321             sb.append( " -Dversion=" );
322             sb.append( version );
323 
324             //insert classifier only if it was used in the artifact
325             if ( classifier != null && !classifier.equals( "" ) )
326             {
327                 sb.append( " -Dclassifier=" );
328                 sb.append( classifier );
329             }
330             sb.append( " -Dpackaging=" );
331             sb.append( type );
332             sb.append( " -Dfile=/path/to/file" );
333             sb.append( " -Durl=[url] -DrepositoryId=[id]" );
334             sb.append( LS );
335         }
336 
337         sb.append( constructArtifactPath( path, indentation ) );
338         sb.append( LS );
339 
340         return sb.toString();
341     }
342 
343     public String getArtifactPath()
344     {
345         return path;
346     }
347 }