View Javadoc
1   /*******************************************************************************
2    * Copyright (c) 2010, 2014 Sonatype, Inc.
3    * All rights reserved. This program and the accompanying materials
4    * are made available under the terms of the Eclipse Public License v1.0
5    * which accompanies this distribution, and is available at
6    * http://www.eclipse.org/legal/epl-v10.html
7    *
8    * Contributors:
9    *    Sonatype, Inc. - initial API and implementation
10   *******************************************************************************/
11  package org.eclipse.aether.collection;
12  
13  import java.util.Collection;
14  import java.util.Collections;
15  import java.util.Iterator;
16  import java.util.LinkedHashSet;
17  import java.util.List;
18  
19  import org.eclipse.aether.RepositoryException;
20  import org.eclipse.aether.artifact.Artifact;
21  import org.eclipse.aether.graph.DependencyNode;
22  import org.eclipse.aether.version.VersionConstraint;
23  
24  /**
25   * Thrown in case of an unsolvable conflict between different version constraints for a dependency.
26   */
27  public class UnsolvableVersionConflictException
28      extends RepositoryException
29  {
30  
31      private final transient Collection<String> versions;
32  
33      private final transient Collection<? extends List<? extends DependencyNode>> paths;
34  
35      /**
36       * Creates a new exception with the specified paths to conflicting nodes in the dependency graph.
37       * 
38       * @param paths The paths to the dependency nodes that participate in the version conflict, may be {@code null}.
39       */
40      public UnsolvableVersionConflictException( Collection<? extends List<? extends DependencyNode>> paths )
41      {
42          super( "Could not resolve version conflict among " + toPaths( paths ) );
43          if ( paths == null )
44          {
45              this.paths = Collections.emptyList();
46              this.versions = Collections.emptyList();
47          }
48          else
49          {
50              this.paths = paths;
51              this.versions = new LinkedHashSet<String>();
52              for ( List<? extends DependencyNode> path : paths )
53              {
54                  VersionConstraint constraint = path.get( path.size() - 1 ).getVersionConstraint();
55                  if ( constraint != null && constraint.getRange() != null )
56                  {
57                      versions.add( constraint.toString() );
58                  }
59              }
60          }
61      }
62  
63      private static String toPaths( Collection<? extends List<? extends DependencyNode>> paths )
64      {
65          String result = "";
66  
67          if ( paths != null )
68          {
69              Collection<String> strings = new LinkedHashSet<String>();
70  
71              for ( List<? extends DependencyNode> path : paths )
72              {
73                  strings.add( toPath( path ) );
74              }
75  
76              result = strings.toString();
77          }
78  
79          return result;
80      }
81  
82      private static String toPath( List<? extends DependencyNode> path )
83      {
84          StringBuilder buffer = new StringBuilder( 256 );
85  
86          for ( Iterator<? extends DependencyNode> it = path.iterator(); it.hasNext(); )
87          {
88              DependencyNode node = it.next();
89              if ( node.getDependency() == null )
90              {
91                  continue;
92              }
93  
94              Artifact artifact = node.getDependency().getArtifact();
95              buffer.append( artifact.getGroupId() );
96              buffer.append( ':' ).append( artifact.getArtifactId() );
97              buffer.append( ':' ).append( artifact.getExtension() );
98              if ( artifact.getClassifier().length() > 0 )
99              {
100                 buffer.append( ':' ).append( artifact.getClassifier() );
101             }
102             buffer.append( ':' ).append( node.getVersionConstraint() );
103 
104             if ( it.hasNext() )
105             {
106                 buffer.append( " -> " );
107             }
108         }
109 
110         return buffer.toString();
111     }
112 
113     /**
114      * Gets the paths leading to the conflicting dependencies.
115      * 
116      * @return The (read-only) paths leading to the conflicting dependencies, never {@code null}.
117      */
118     public Collection<? extends List<? extends DependencyNode>> getPaths()
119     {
120         return paths;
121     }
122 
123     /**
124      * Gets the conflicting version constraints of the dependency.
125      * 
126      * @return The (read-only) conflicting version constraints, never {@code null}.
127      */
128     public Collection<String> getVersions()
129     {
130         return versions;
131     }
132 
133 }