001package 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 022import java.util.Iterator; 023import java.util.List; 024 025import org.apache.maven.artifact.Artifact; 026import org.apache.maven.artifact.repository.ArtifactRepository; 027import 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 */ 034public 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( " " ).append( groupId ).append( ":" ).append( artifactId ).append( ":" ).append( type ).append( 203 ":" ).append( version ); 204 sb.append( LS ); 205 if ( remoteRepositories != null ) 206 { 207 sb.append( LS ); 208 sb.append( "from the specified remote repositories:" ); 209 sb.append( LS ).append( " " ); 210 211 if ( remoteRepositories.isEmpty() ) 212 { 213 sb.append( "(none)" ); 214 } 215 216 for ( Iterator<ArtifactRepository> i = remoteRepositories.iterator(); i.hasNext(); ) 217 { 218 ArtifactRepository remoteRepository = i.next(); 219 220 sb.append( remoteRepository.getId() ); 221 sb.append( " (" ); 222 sb.append( remoteRepository.getUrl() ); 223 224 ArtifactRepositoryPolicy releases = remoteRepository.getReleases(); 225 if ( releases != null ) 226 { 227 sb.append( ", releases=" ).append( releases.isEnabled() ); 228 } 229 230 ArtifactRepositoryPolicy snapshots = remoteRepository.getSnapshots(); 231 if ( snapshots != null ) 232 { 233 sb.append( ", snapshots=" ).append( snapshots.isEnabled() ); 234 } 235 236 sb.append( ")" ); 237 if ( i.hasNext() ) 238 { 239 sb.append( "," ).append( LS ).append( " " ); 240 } 241 } 242 } 243 244 sb.append( constructArtifactPath( path, "" ) ); 245 sb.append( LS ); 246 } 247 248 return sb.toString(); 249 } 250 251 protected static String constructMissingArtifactMessage( String message, 252 String indentation, 253 String groupId, 254 String artifactId, 255 String version, 256 String type, 257 String classifier, 258 String downloadUrl, 259 List<String> path ) 260 { 261 StringBuilder sb = new StringBuilder( message ); 262 263 if ( !"pom".equals( type ) ) 264 { 265 if ( downloadUrl != null ) 266 { 267 sb.append( LS ); 268 sb.append( LS ); 269 sb.append( indentation ); 270 sb.append( "Try downloading the file manually from: " ); 271 sb.append( LS ); 272 sb.append( indentation ); 273 sb.append( " " ); 274 sb.append( downloadUrl ); 275 } 276 else 277 { 278 sb.append( LS ); 279 sb.append( LS ); 280 sb.append( indentation ); 281 sb.append( "Try downloading the file manually from the project website." ); 282 } 283 284 sb.append( LS ); 285 sb.append( LS ); 286 sb.append( indentation ); 287 sb.append( "Then, install it using the command: " ); 288 sb.append( LS ); 289 sb.append( indentation ); 290 sb.append( " mvn install:install-file -DgroupId=" ); 291 sb.append( groupId ); 292 sb.append( " -DartifactId=" ); 293 sb.append( artifactId ); 294 sb.append( " -Dversion=" ); 295 sb.append( version ); 296 297 //insert classifier only if it was used in the artifact 298 if ( classifier != null && !classifier.equals( "" ) ) 299 { 300 sb.append( " -Dclassifier=" ); 301 sb.append( classifier ); 302 } 303 sb.append( " -Dpackaging=" ); 304 sb.append( type ); 305 sb.append( " -Dfile=/path/to/file" ); 306 sb.append( LS ); 307 308 // If people want to deploy it 309 sb.append( LS ); 310 sb.append( indentation ); 311 sb.append( "Alternatively, if you host your own repository you can deploy the file there: " ); 312 sb.append( LS ); 313 sb.append( indentation ); 314 sb.append( " mvn deploy:deploy-file -DgroupId=" ); 315 sb.append( groupId ); 316 sb.append( " -DartifactId=" ); 317 sb.append( artifactId ); 318 sb.append( " -Dversion=" ); 319 sb.append( version ); 320 321 //insert classifier only if it was used in the artifact 322 if ( classifier != null && !classifier.equals( "" ) ) 323 { 324 sb.append( " -Dclassifier=" ); 325 sb.append( classifier ); 326 } 327 sb.append( " -Dpackaging=" ); 328 sb.append( type ); 329 sb.append( " -Dfile=/path/to/file" ); 330 sb.append( " -Durl=[url] -DrepositoryId=[id]" ); 331 sb.append( LS ); 332 } 333 334 sb.append( constructArtifactPath( path, indentation ) ); 335 sb.append( LS ); 336 337 return sb.toString(); 338 } 339 340 public String getArtifactPath() 341 { 342 return path; 343 } 344}