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