001 package org.apache.maven.artifact.resolver;
002
003 /*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements. See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership. The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License. You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied. See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022 import java.util.Iterator;
023 import java.util.List;
024
025 import org.apache.maven.artifact.Artifact;
026 import org.apache.maven.artifact.repository.ArtifactRepository;
027 import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
028
029 /**
030 * Base class for artifact resolution exceptions.
031 *
032 * @author <a href="mailto:brett@apache.org">Brett Porter</a>
033 */
034 public class AbstractArtifactResolutionException
035 extends Exception
036 {
037 private String groupId;
038
039 private String artifactId;
040
041 private String version;
042
043 private String type;
044
045 private String classifier;
046
047 private Artifact artifact;
048
049 private List<ArtifactRepository> remoteRepositories;
050
051 private final String originalMessage;
052
053 private final String path;
054
055 static final String LS = System.getProperty( "line.separator" );
056
057 protected AbstractArtifactResolutionException( String message,
058 String groupId,
059 String artifactId,
060 String version,
061 String type,
062 String classifier,
063 List<ArtifactRepository> remoteRepositories,
064 List<String> path )
065 {
066 this( message, groupId, artifactId, version, type, classifier, remoteRepositories, path, null );
067 }
068
069 protected AbstractArtifactResolutionException( String message,
070 String groupId,
071 String artifactId,
072 String version,
073 String type,
074 String classifier,
075 List<ArtifactRepository> remoteRepositories,
076 List<String> path,
077 Throwable t )
078 {
079 super( constructMessageBase( message, groupId, artifactId, version, type, remoteRepositories, path ), t );
080
081 this.originalMessage = message;
082 this.groupId = groupId;
083 this.artifactId = artifactId;
084 this.type = type;
085 this.classifier = classifier;
086 this.version = version;
087 this.remoteRepositories = remoteRepositories;
088 this.path = constructArtifactPath( path, "" );
089 }
090
091 protected AbstractArtifactResolutionException( String message,
092 Artifact artifact )
093 {
094 this( message, artifact, null );
095 }
096
097 protected AbstractArtifactResolutionException( String message,
098 Artifact artifact,
099 List<ArtifactRepository> remoteRepositories )
100 {
101 this( message, artifact, remoteRepositories, null );
102 }
103
104 protected AbstractArtifactResolutionException( String message,
105 Artifact artifact,
106 List<ArtifactRepository> remoteRepositories,
107 Throwable t )
108 {
109 this( message, artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion(), artifact.getType(),
110 artifact.getClassifier(), remoteRepositories, artifact.getDependencyTrail(), t );
111 this.artifact = artifact;
112 }
113
114 public Artifact getArtifact()
115 {
116 return artifact;
117 }
118
119 public String getGroupId()
120 {
121 return groupId;
122 }
123
124 public String getArtifactId()
125 {
126 return artifactId;
127 }
128
129 public String getVersion()
130 {
131 return version;
132 }
133
134 public String getType()
135 {
136 return type;
137 }
138
139 /** @return the classifier */
140 public String getClassifier()
141 {
142 return this.classifier;
143 }
144
145 /** @return the path */
146 public String getPath()
147 {
148 return this.path;
149 }
150
151 public List<ArtifactRepository> getRemoteRepositories()
152 {
153 return remoteRepositories;
154 }
155
156 public String getOriginalMessage()
157 {
158 return originalMessage;
159 }
160
161 protected static String constructArtifactPath( List<String> path,
162 String indentation )
163 {
164 StringBuilder sb = new StringBuilder();
165
166 if ( path != null )
167 {
168 sb.append( LS );
169 sb.append( indentation );
170 sb.append( "Path to dependency: " );
171 sb.append( LS );
172 int num = 1;
173 for ( Iterator<String> i = path.iterator(); i.hasNext(); num++ )
174 {
175 sb.append( indentation );
176 sb.append( "\t" );
177 sb.append( num );
178 sb.append( ") " );
179 sb.append( i.next() );
180 sb.append( LS );
181 }
182 }
183
184 return sb.toString();
185 }
186
187 private static String constructMessageBase( String message,
188 String groupId,
189 String artifactId,
190 String version,
191 String type,
192 List<ArtifactRepository> remoteRepositories,
193 List<String> path )
194 {
195 StringBuilder sb = new StringBuilder();
196
197 sb.append( message );
198
199 if ( message == null || !message.contains( "from the specified remote repositories:" ) )
200 {
201 sb.append( LS );
202 sb.append( " " + groupId + ":" + artifactId + ":" + type + ":" + version );
203 sb.append( LS );
204 if ( remoteRepositories != null )
205 {
206 sb.append( LS );
207 sb.append( "from the specified remote repositories:" );
208 sb.append( LS + " " );
209
210 if ( remoteRepositories.isEmpty() )
211 {
212 sb.append( "(none)" );
213 }
214
215 for ( Iterator<ArtifactRepository> i = remoteRepositories.iterator(); i.hasNext(); )
216 {
217 ArtifactRepository remoteRepository = i.next();
218
219 sb.append( remoteRepository.getId() );
220 sb.append( " (" );
221 sb.append( remoteRepository.getUrl() );
222
223 ArtifactRepositoryPolicy releases = remoteRepository.getReleases();
224 if ( releases != null )
225 {
226 sb.append( ", releases=" ).append( releases.isEnabled() );
227 }
228
229 ArtifactRepositoryPolicy snapshots = remoteRepository.getSnapshots();
230 if ( snapshots != null )
231 {
232 sb.append( ", snapshots=" ).append( snapshots.isEnabled() );
233 }
234
235 sb.append( ")" );
236 if ( i.hasNext() )
237 {
238 sb.append( "," ).append( LS ).append( " " );
239 }
240 }
241 }
242
243 sb.append( constructArtifactPath( path, "" ) );
244 sb.append( LS );
245 }
246
247 return sb.toString();
248 }
249
250 protected static String constructMissingArtifactMessage( String message,
251 String indentation,
252 String groupId,
253 String artifactId,
254 String version,
255 String type,
256 String classifier,
257 String downloadUrl,
258 List<String> path )
259 {
260 StringBuilder sb = new StringBuilder( message );
261
262 if ( !"pom".equals( type ) )
263 {
264 if ( downloadUrl != null )
265 {
266 sb.append( LS );
267 sb.append( LS );
268 sb.append( indentation );
269 sb.append( "Try downloading the file manually from: " );
270 sb.append( LS );
271 sb.append( indentation );
272 sb.append( " " );
273 sb.append( downloadUrl );
274 }
275 else
276 {
277 sb.append( LS );
278 sb.append( LS );
279 sb.append( indentation );
280 sb.append( "Try downloading the file manually from the project website." );
281 }
282
283 sb.append( LS );
284 sb.append( LS );
285 sb.append( indentation );
286 sb.append( "Then, install it using the command: " );
287 sb.append( LS );
288 sb.append( indentation );
289 sb.append( " mvn install:install-file -DgroupId=" );
290 sb.append( groupId );
291 sb.append( " -DartifactId=" );
292 sb.append( artifactId );
293 sb.append( " -Dversion=" );
294 sb.append( version );
295
296 //insert classifier only if it was used in the artifact
297 if ( classifier != null && !classifier.equals( "" ) )
298 {
299 sb.append( " -Dclassifier=" );
300 sb.append( classifier );
301 }
302 sb.append( " -Dpackaging=" );
303 sb.append( type );
304 sb.append( " -Dfile=/path/to/file" );
305 sb.append( LS );
306
307 // If people want to deploy it
308 sb.append( LS );
309 sb.append( indentation );
310 sb.append( "Alternatively, if you host your own repository you can deploy the file there: " );
311 sb.append( LS );
312 sb.append( indentation );
313 sb.append( " mvn deploy:deploy-file -DgroupId=" );
314 sb.append( groupId );
315 sb.append( " -DartifactId=" );
316 sb.append( artifactId );
317 sb.append( " -Dversion=" );
318 sb.append( version );
319
320 //insert classifier only if it was used in the artifact
321 if ( classifier != null && !classifier.equals( "" ) )
322 {
323 sb.append( " -Dclassifier=" );
324 sb.append( classifier );
325 }
326 sb.append( " -Dpackaging=" );
327 sb.append( type );
328 sb.append( " -Dfile=/path/to/file" );
329 sb.append( " -Durl=[url] -DrepositoryId=[id]" );
330 sb.append( LS );
331 }
332
333 sb.append( constructArtifactPath( path, indentation ) );
334 sb.append( LS );
335
336 return sb.toString();
337 }
338
339 public String getArtifactPath()
340 {
341 return path;
342 }
343 }