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