View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.artifact.resolver;
20  
21  import java.util.ArrayList;
22  import java.util.Collections;
23  import java.util.LinkedHashSet;
24  import java.util.List;
25  import java.util.Set;
26  import org.apache.maven.artifact.Artifact;
27  import org.apache.maven.artifact.repository.ArtifactRepository;
28  import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
29  
30  /**
31   * Specific problems during resolution that we want to account for:
32   * <ul>
33   *   <li>missing metadata</li>
34   *   <li>version range violations</li>
35   *   <li>version circular dependencies</li>
36   *   <li>missing artifacts</li>
37   *   <li>network/transfer errors</li>
38   *   <li>file system errors: permissions</li>
39   * </ul>
40   *
41   * @author Jason van Zyl
42   * TODO carlos: all these possible has*Exceptions and get*Exceptions methods make the clients too
43   *       complex requiring a long list of checks, need to create a parent/interface/encapsulation
44   *       for the types of exceptions
45   */
46  public class ArtifactResolutionResult {
47      private static final String LS = System.lineSeparator();
48  
49      private Artifact originatingArtifact;
50  
51      private List<Artifact> missingArtifacts;
52  
53      // Exceptions
54  
55      private List<Exception> exceptions;
56  
57      private List<Exception> versionRangeViolations;
58  
59      private List<ArtifactResolutionException> metadataResolutionExceptions;
60  
61      private List<CyclicDependencyException> circularDependencyExceptions;
62  
63      private List<ArtifactResolutionException> errorArtifactExceptions;
64  
65      // file system errors
66  
67      private List<ArtifactRepository> repositories;
68  
69      private Set<Artifact> artifacts;
70  
71      private Set<ResolutionNode> resolutionNodes;
72  
73      public Artifact getOriginatingArtifact() {
74          return originatingArtifact;
75      }
76  
77      public ArtifactResolutionResult setOriginatingArtifact(final Artifact originatingArtifact) {
78          this.originatingArtifact = originatingArtifact;
79  
80          return this;
81      }
82  
83      public void addArtifact(Artifact artifact) {
84          if (artifacts == null) {
85              artifacts = new LinkedHashSet<>();
86          }
87  
88          artifacts.add(artifact);
89      }
90  
91      public Set<Artifact> getArtifacts() {
92          if (artifacts == null) {
93              artifacts = new LinkedHashSet<>();
94          }
95  
96          return artifacts;
97      }
98  
99      public void setArtifacts(Set<Artifact> artifacts) {
100         this.artifacts = artifacts;
101     }
102 
103     public Set<ResolutionNode> getArtifactResolutionNodes() {
104         if (resolutionNodes == null) {
105             resolutionNodes = new LinkedHashSet<>();
106         }
107 
108         return resolutionNodes;
109     }
110 
111     public void setArtifactResolutionNodes(Set<ResolutionNode> resolutionNodes) {
112         this.resolutionNodes = resolutionNodes;
113     }
114 
115     public boolean hasMissingArtifacts() {
116         return missingArtifacts != null && !missingArtifacts.isEmpty();
117     }
118 
119     public List<Artifact> getMissingArtifacts() {
120         return missingArtifacts == null ? Collections.emptyList() : Collections.unmodifiableList(missingArtifacts);
121     }
122 
123     public ArtifactResolutionResult addMissingArtifact(Artifact artifact) {
124         missingArtifacts = initList(missingArtifacts);
125 
126         missingArtifacts.add(artifact);
127 
128         return this;
129     }
130 
131     public ArtifactResolutionResult setUnresolvedArtifacts(final List<Artifact> unresolvedArtifacts) {
132         this.missingArtifacts = unresolvedArtifacts;
133 
134         return this;
135     }
136 
137     public boolean isSuccess() {
138         return !(hasMissingArtifacts() || hasExceptions());
139     }
140 
141     // ------------------------------------------------------------------------
142     // Exceptions
143     // ------------------------------------------------------------------------
144 
145     public boolean hasExceptions() {
146         return exceptions != null && !exceptions.isEmpty();
147     }
148 
149     public List<Exception> getExceptions() {
150         return exceptions == null ? Collections.emptyList() : Collections.unmodifiableList(exceptions);
151     }
152 
153     // ------------------------------------------------------------------------
154     // Version Range Violations
155     // ------------------------------------------------------------------------
156 
157     public boolean hasVersionRangeViolations() {
158         return versionRangeViolations != null;
159     }
160 
161     /**
162      * TODO this needs to accept a {@link OverConstrainedVersionException} as returned by
163      *       {@link #getVersionRangeViolation(int)} but it's not used like that in
164      *       DefaultLegacyArtifactCollector
165      *
166      * @param e an exception
167      * @return {@code this}
168      */
169     public ArtifactResolutionResult addVersionRangeViolation(Exception e) {
170         versionRangeViolations = initList(versionRangeViolations);
171 
172         versionRangeViolations.add(e);
173 
174         exceptions = initList(exceptions);
175 
176         exceptions.add(e);
177 
178         return this;
179     }
180 
181     public OverConstrainedVersionException getVersionRangeViolation(int i) {
182         return (OverConstrainedVersionException) versionRangeViolations.get(i);
183     }
184 
185     public List<Exception> getVersionRangeViolations() {
186         return versionRangeViolations == null
187                 ? Collections.emptyList()
188                 : Collections.unmodifiableList(versionRangeViolations);
189     }
190 
191     // ------------------------------------------------------------------------
192     // Metadata Resolution Exceptions: ArtifactResolutionExceptions
193     // ------------------------------------------------------------------------
194 
195     public boolean hasMetadataResolutionExceptions() {
196         return metadataResolutionExceptions != null;
197     }
198 
199     public ArtifactResolutionResult addMetadataResolutionException(ArtifactResolutionException e) {
200         metadataResolutionExceptions = initList(metadataResolutionExceptions);
201 
202         metadataResolutionExceptions.add(e);
203 
204         exceptions = initList(exceptions);
205 
206         exceptions.add(e);
207 
208         return this;
209     }
210 
211     public ArtifactResolutionException getMetadataResolutionException(int i) {
212         return metadataResolutionExceptions.get(i);
213     }
214 
215     public List<ArtifactResolutionException> getMetadataResolutionExceptions() {
216         return metadataResolutionExceptions == null
217                 ? Collections.emptyList()
218                 : Collections.unmodifiableList(metadataResolutionExceptions);
219     }
220 
221     // ------------------------------------------------------------------------
222     // ErrorArtifactExceptions: ArtifactResolutionExceptions
223     // ------------------------------------------------------------------------
224 
225     public boolean hasErrorArtifactExceptions() {
226         return errorArtifactExceptions != null;
227     }
228 
229     public ArtifactResolutionResult addErrorArtifactException(ArtifactResolutionException e) {
230         errorArtifactExceptions = initList(errorArtifactExceptions);
231 
232         errorArtifactExceptions.add(e);
233 
234         exceptions = initList(exceptions);
235 
236         exceptions.add(e);
237 
238         return this;
239     }
240 
241     public List<ArtifactResolutionException> getErrorArtifactExceptions() {
242         if (errorArtifactExceptions == null) {
243             return Collections.emptyList();
244         }
245 
246         return Collections.unmodifiableList(errorArtifactExceptions);
247     }
248 
249     // ------------------------------------------------------------------------
250     // Circular Dependency Exceptions
251     // ------------------------------------------------------------------------
252 
253     public boolean hasCircularDependencyExceptions() {
254         return circularDependencyExceptions != null;
255     }
256 
257     public ArtifactResolutionResult addCircularDependencyException(CyclicDependencyException e) {
258         circularDependencyExceptions = initList(circularDependencyExceptions);
259 
260         circularDependencyExceptions.add(e);
261 
262         exceptions = initList(exceptions);
263 
264         exceptions.add(e);
265 
266         return this;
267     }
268 
269     public CyclicDependencyException getCircularDependencyException(int i) {
270         return circularDependencyExceptions.get(i);
271     }
272 
273     public List<CyclicDependencyException> getCircularDependencyExceptions() {
274         if (circularDependencyExceptions == null) {
275             return Collections.emptyList();
276         }
277 
278         return Collections.unmodifiableList(circularDependencyExceptions);
279     }
280 
281     // ------------------------------------------------------------------------
282     // Repositories
283     // ------------------------------------------------------------------------
284 
285     public List<ArtifactRepository> getRepositories() {
286         if (repositories == null) {
287             return Collections.emptyList();
288         }
289 
290         return Collections.unmodifiableList(repositories);
291     }
292 
293     public ArtifactResolutionResult setRepositories(final List<ArtifactRepository> repositories) {
294         this.repositories = repositories;
295 
296         return this;
297     }
298 
299     //
300     // Internal
301     //
302 
303     private <T> List<T> initList(final List<T> l) {
304         if (l == null) {
305             return new ArrayList<>();
306         }
307         return l;
308     }
309 
310     public String toString() {
311         StringBuilder sb = new StringBuilder();
312 
313         if (artifacts != null) {
314             int i = 1;
315             sb.append("---------").append(LS);
316             sb.append(artifacts.size()).append(LS);
317             for (Artifact a : artifacts) {
318                 sb.append(i).append(' ').append(a).append(LS);
319                 i++;
320             }
321             sb.append("---------");
322         }
323 
324         return sb.toString();
325     }
326 }