1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  package org.apache.maven.artifact.resolver;
20  
21  import java.util.ArrayList;
22  import java.util.Collections;
23  import java.util.Iterator;
24  import java.util.LinkedList;
25  import java.util.List;
26  import java.util.Set;
27  
28  import org.apache.maven.artifact.Artifact;
29  import org.apache.maven.artifact.repository.ArtifactRepository;
30  import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
31  import org.apache.maven.artifact.versioning.ArtifactVersion;
32  import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
33  
34  
35  
36  
37  public class ResolutionNode {
38      private Artifact artifact;
39  
40      private List<ResolutionNode> children;
41  
42      private final List<Object> parents;
43  
44      private final int depth;
45  
46      private final ResolutionNode parent;
47  
48      private final List<ArtifactRepository> remoteRepositories;
49  
50      private boolean active = true;
51  
52      private List<Artifact> trail;
53  
54      public ResolutionNode(Artifact artifact, List<ArtifactRepository> remoteRepositories) {
55          this.artifact = artifact;
56          this.remoteRepositories = remoteRepositories;
57          depth = 0;
58          parents = Collections.emptyList();
59          parent = null;
60      }
61  
62      public ResolutionNode(Artifact artifact, List<ArtifactRepository> remoteRepositories, ResolutionNode parent) {
63          this.artifact = artifact;
64          this.remoteRepositories = remoteRepositories;
65          depth = parent.depth + 1;
66          parents = new ArrayList<>();
67          parents.addAll(parent.parents);
68          parents.add(parent.getKey());
69          this.parent = parent;
70      }
71  
72      public Artifact getArtifact() {
73          return artifact;
74      }
75  
76      public Object getKey() {
77          return artifact.getDependencyConflictId();
78      }
79  
80      public void addDependencies(
81              Set<Artifact> artifacts, List<ArtifactRepository> remoteRepositories, ArtifactFilter filter)
82              throws CyclicDependencyException, OverConstrainedVersionException {
83          if (artifacts != null && !artifacts.isEmpty()) {
84              children = new ArrayList<>(artifacts.size());
85  
86              for (Artifact a : artifacts) {
87                  if (parents.contains(a.getDependencyConflictId())) {
88                      a.setDependencyTrail(getDependencyTrail());
89  
90                      throw new CyclicDependencyException("A dependency has introduced a cycle", a);
91                  }
92  
93                  children.add(new ResolutionNode(a, remoteRepositories, this));
94              }
95              children = Collections.unmodifiableList(children);
96          } else {
97              children = Collections.emptyList();
98          }
99          trail = null;
100     }
101 
102     
103 
104 
105 
106     public List<String> getDependencyTrail() throws OverConstrainedVersionException {
107         List<Artifact> trial = getTrail();
108 
109         List<String> ret = new ArrayList<>(trial.size());
110 
111         for (Artifact artifact : trial) {
112             ret.add(artifact.getId());
113         }
114 
115         return ret;
116     }
117 
118     private List<Artifact> getTrail() throws OverConstrainedVersionException {
119         if (trail == null) {
120             List<Artifact> ids = new LinkedList<>();
121             ResolutionNode node = this;
122             while (node != null) {
123                 Artifact artifact = node.getArtifact();
124                 if (artifact.getVersion() == null) {
125                     
126                     ArtifactVersion selected = artifact.getSelectedVersion();
127                     
128                     
129                     if (selected != null) {
130                         artifact.selectVersion(selected.toString());
131                     } else {
132                         throw new OverConstrainedVersionException(
133                                 "Unable to get a selected Version for " + artifact.getArtifactId(), artifact);
134                     }
135                 }
136 
137                 ids.add(0, artifact);
138                 node = node.parent;
139             }
140             trail = ids;
141         }
142         return trail;
143     }
144 
145     public boolean isResolved() {
146         return children != null;
147     }
148 
149     
150 
151 
152 
153 
154     public boolean isChildOfRootNode() {
155         return parent != null && parent.parent == null;
156     }
157 
158     public Iterator<ResolutionNode> getChildrenIterator() {
159         return children.iterator();
160     }
161 
162     public int getDepth() {
163         return depth;
164     }
165 
166     public List<ArtifactRepository> getRemoteRepositories() {
167         return remoteRepositories;
168     }
169 
170     public boolean isActive() {
171         return active;
172     }
173 
174     public void enable() {
175         active = true;
176 
177         
178         if (children != null) {
179             for (ResolutionNode node : children) {
180                 node.enable();
181             }
182         }
183     }
184 
185     public void disable() {
186         active = false;
187         if (children != null) {
188             for (ResolutionNode node : children) {
189                 node.disable();
190             }
191         }
192     }
193 
194     public boolean filterTrail(ArtifactFilter filter) throws OverConstrainedVersionException {
195         boolean success = true;
196         if (filter != null) {
197             for (Artifact artifact : getTrail()) {
198                 if (!filter.include(artifact)) {
199                     success = false;
200                 }
201             }
202         }
203         return success;
204     }
205 
206     @Override
207     public String toString() {
208         return artifact.toString() + " (" + depth + "; " + (active ? "enabled" : "disabled") + ")";
209     }
210 
211     public void setArtifact(Artifact artifact) {
212         this.artifact = artifact;
213     }
214 }