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    }