View Javadoc
1   package org.eclipse.aether.resolution;
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.Collections;
23  import java.util.List;
24  
25  import org.eclipse.aether.RepositoryException;
26  import org.eclipse.aether.transfer.ArtifactNotFoundException;
27  import org.eclipse.aether.transfer.RepositoryOfflineException;
28  
29  /**
30   * Thrown in case of a unresolvable artifacts.
31   */
32  public class ArtifactResolutionException
33      extends RepositoryException
34  {
35  
36      private final transient List<ArtifactResult> results;
37  
38      /**
39       * Creates a new exception with the specified results.
40       * 
41       * @param results The resolution results at the point the exception occurred, may be {@code null}.
42       */
43      public ArtifactResolutionException( List<ArtifactResult> results )
44      {
45          super( getMessage( results ), getCause( results ) );
46          this.results = ( results != null ) ? results : Collections.<ArtifactResult>emptyList();
47      }
48  
49      /**
50       * Creates a new exception with the specified results and detail message.
51       * 
52       * @param results The resolution results at the point the exception occurred, may be {@code null}.
53       * @param message The detail message, may be {@code null}.
54       */
55      public ArtifactResolutionException( List<ArtifactResult> results, String message )
56      {
57          super( message, getCause( results ) );
58          this.results = ( results != null ) ? results : Collections.<ArtifactResult>emptyList();
59      }
60  
61      /**
62       * Creates a new exception with the specified results, detail message and cause.
63       * 
64       * @param results The resolution results at the point the exception occurred, may be {@code null}.
65       * @param message The detail message, may be {@code null}.
66       * @param cause The exception that caused this one, may be {@code null}.
67       */
68      public ArtifactResolutionException( List<ArtifactResult> results, String message, Throwable cause )
69      {
70          super( message, cause );
71          this.results = ( results != null ) ? results : Collections.<ArtifactResult>emptyList();
72      }
73  
74      /**
75       * Gets the resolution results at the point the exception occurred. Despite being incomplete, callers might want to
76       * use these results to fail gracefully and continue their operation with whatever interim data has been gathered.
77       * 
78       * @return The resolution results or {@code null} if unknown.
79       */
80      public List<ArtifactResult> getResults()
81      {
82          return results;
83      }
84  
85      /**
86       * Gets the first result from {@link #getResults()}. This is a convenience method for cases where callers know only
87       * a single result/request is involved.
88       * 
89       * @return The (first) resolution result or {@code null} if none.
90       */
91      public ArtifactResult getResult()
92      {
93          return ( results != null && !results.isEmpty() ) ? results.get( 0 ) : null;
94      }
95  
96      private static String getMessage( List<? extends ArtifactResult> results )
97      {
98          StringBuilder buffer = new StringBuilder( 256 );
99  
100         buffer.append( "The following artifacts could not be resolved: " );
101 
102         int unresolved = 0;
103 
104         String sep = "";
105         for ( ArtifactResult result : results )
106         {
107             if ( !result.isResolved() )
108             {
109                 unresolved++;
110 
111                 buffer.append( sep );
112                 buffer.append( result.getRequest().getArtifact() );
113                 sep = ", ";
114             }
115         }
116 
117         Throwable cause = getCause( results );
118         if ( cause != null )
119         {
120             if ( unresolved == 1 )
121             {
122                 buffer.setLength( 0 );
123                 buffer.append( cause.getMessage() );
124             }
125             else
126             {
127                 buffer.append( ": " ).append( cause.getMessage() );
128             }
129         }
130 
131         return buffer.toString();
132     }
133 
134     private static Throwable getCause( List<? extends ArtifactResult> results )
135     {
136         for ( ArtifactResult result : results )
137         {
138             if ( !result.isResolved() )
139             {
140                 Throwable notFound = null, offline = null;
141                 for ( Throwable t : result.getExceptions() )
142                 {
143                     if ( t instanceof ArtifactNotFoundException )
144                     {
145                         if ( notFound == null )
146                         {
147                             notFound = t;
148                         }
149                         if ( offline == null && t.getCause() instanceof RepositoryOfflineException )
150                         {
151                             offline = t;
152                         }
153                     }
154                     else
155                     {
156                         return t;
157                     }
158 
159                 }
160                 if ( offline != null )
161                 {
162                     return offline;
163                 }
164                 if ( notFound != null )
165                 {
166                     return notFound;
167                 }
168             }
169         }
170         return null;
171     }
172 
173 }