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