1 package org.eclipse.aether.graph;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.AbstractSet;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.Iterator;
26 import java.util.LinkedHashSet;
27 import java.util.NoSuchElementException;
28 import static java.util.Objects.requireNonNull;
29
30 import java.util.Objects;
31 import java.util.Set;
32
33 import org.eclipse.aether.artifact.Artifact;
34
35
36
37
38
39 public final class Dependency
40 {
41
42 private final Artifact artifact;
43
44 private final String scope;
45
46 private final Boolean optional;
47
48 private final Set<Exclusion> exclusions;
49
50
51
52
53
54
55
56 public Dependency( Artifact artifact, String scope )
57 {
58 this( artifact, scope, false );
59 }
60
61
62
63
64
65
66
67
68 public Dependency( Artifact artifact, String scope, Boolean optional )
69 {
70 this( artifact, scope, optional, null );
71 }
72
73
74
75
76
77
78
79
80
81 public Dependency( Artifact artifact, String scope, Boolean optional, Collection<Exclusion> exclusions )
82 {
83 this( artifact, scope, Exclusions.copy( exclusions ), optional );
84 }
85
86 private Dependency( Artifact artifact, String scope, Set<Exclusion> exclusions, Boolean optional )
87 {
88
89 this.artifact = requireNonNull( artifact, "artifact cannot be null" );
90 this.scope = ( scope != null ) ? scope : "";
91 this.optional = optional;
92 this.exclusions = exclusions;
93 }
94
95
96
97
98
99
100 public Artifact getArtifact()
101 {
102 return artifact;
103 }
104
105
106
107
108
109
110
111 public Dependency setArtifact( Artifact artifact )
112 {
113 if ( this.artifact.equals( artifact ) )
114 {
115 return this;
116 }
117 return new Dependency( artifact, scope, exclusions, optional );
118 }
119
120
121
122
123
124
125 public String getScope()
126 {
127 return scope;
128 }
129
130
131
132
133
134
135
136 public Dependency setScope( String scope )
137 {
138 if ( this.scope.equals( scope ) || ( scope == null && this.scope.isEmpty() ) )
139 {
140 return this;
141 }
142 return new Dependency( artifact, scope, exclusions, optional );
143 }
144
145
146
147
148
149
150 public boolean isOptional()
151 {
152 return Boolean.TRUE.equals( optional );
153 }
154
155
156
157
158
159
160
161 public Boolean getOptional()
162 {
163 return optional;
164 }
165
166
167
168
169
170
171
172
173 public Dependency setOptional( Boolean optional )
174 {
175 if ( Objects.equals( this.optional, optional ) )
176 {
177 return this;
178 }
179 return new Dependency( artifact, scope, exclusions, optional );
180 }
181
182
183
184
185
186
187
188 public Collection<Exclusion> getExclusions()
189 {
190 return exclusions;
191 }
192
193
194
195
196
197
198
199 public Dependency setExclusions( Collection<Exclusion> exclusions )
200 {
201 if ( hasEquivalentExclusions( exclusions ) )
202 {
203 return this;
204 }
205 return new Dependency( artifact, scope, optional, exclusions );
206 }
207
208 private boolean hasEquivalentExclusions( Collection<Exclusion> exclusions )
209 {
210 if ( exclusions == null || exclusions.isEmpty() )
211 {
212 return this.exclusions.isEmpty();
213 }
214 if ( exclusions instanceof Set )
215 {
216 return this.exclusions.equals( exclusions );
217 }
218 return exclusions.size() >= this.exclusions.size() && this.exclusions.containsAll( exclusions )
219 && exclusions.containsAll( this.exclusions );
220 }
221
222 @Override
223 public String toString()
224 {
225 return getArtifact() + " (" + getScope() + ( isOptional() ? "?" : "" ) + ")";
226 }
227
228 @Override
229 public boolean equals( Object obj )
230 {
231 if ( obj == this )
232 {
233 return true;
234 }
235 else if ( obj == null || !getClass().equals( obj.getClass() ) )
236 {
237 return false;
238 }
239
240 Dependency that = (Dependency) obj;
241
242 return Objects.equals( artifact, that.artifact ) && Objects.equals( scope, that.scope )
243 && Objects.equals( optional, that.optional ) && Objects.equals( exclusions, that.exclusions );
244 }
245
246 @Override
247 public int hashCode()
248 {
249 int hash = 17;
250 hash = hash * 31 + artifact.hashCode();
251 hash = hash * 31 + scope.hashCode();
252 hash = hash * 31 + ( optional != null ? optional.hashCode() : 0 );
253 hash = hash * 31 + exclusions.size();
254 return hash;
255 }
256
257 private static class Exclusions
258 extends AbstractSet<Exclusion>
259 {
260
261 private final Exclusion[] exclusions;
262
263 public static Set<Exclusion> copy( Collection<Exclusion> exclusions )
264 {
265 if ( exclusions == null || exclusions.isEmpty() )
266 {
267 return Collections.emptySet();
268 }
269 return new Exclusions( exclusions );
270 }
271
272 private Exclusions( Collection<Exclusion> exclusions )
273 {
274 if ( exclusions.size() > 1 && !( exclusions instanceof Set ) )
275 {
276 exclusions = new LinkedHashSet<>( exclusions );
277 }
278 this.exclusions = exclusions.toArray( new Exclusion[0] );
279 }
280
281 @Override
282 public Iterator<Exclusion> iterator()
283 {
284 return new Iterator<Exclusion>()
285 {
286
287 private int cursor = 0;
288
289 public boolean hasNext()
290 {
291 return cursor < exclusions.length;
292 }
293
294 public Exclusion next()
295 {
296 try
297 {
298 Exclusion exclusion = exclusions[cursor];
299 cursor++;
300 return exclusion;
301 }
302 catch ( IndexOutOfBoundsException e )
303 {
304 throw new NoSuchElementException();
305 }
306 }
307
308 public void remove()
309 {
310 throw new UnsupportedOperationException();
311 }
312
313 };
314 }
315
316 @Override
317 public int size()
318 {
319 return exclusions.length;
320 }
321
322 }
323
324 }