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