1 package org.sonatype.aether.graph;
2
3
4
5
6
7
8
9
10
11 import java.util.AbstractSet;
12 import java.util.Collection;
13 import java.util.Collections;
14 import java.util.Iterator;
15 import java.util.LinkedHashSet;
16 import java.util.NoSuchElementException;
17 import java.util.Set;
18
19 import org.sonatype.aether.artifact.Artifact;
20
21
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
143 public boolean isOptional()
144 {
145 return optional;
146 }
147
148
149
150
151
152
153
154 public Dependency setOptional( boolean optional )
155 {
156 if ( this.optional == optional )
157 {
158 return this;
159 }
160 return new Dependency( artifact, scope, exclusions, optional );
161 }
162
163
164
165
166
167
168
169 public Collection<Exclusion> getExclusions()
170 {
171 return exclusions;
172 }
173
174
175
176
177
178
179
180 public Dependency setExclusions( Collection<Exclusion> exclusions )
181 {
182 if ( hasEquivalentExclusions( exclusions ) )
183 {
184 return this;
185 }
186 return new Dependency( artifact, scope, optional, exclusions );
187 }
188
189 private boolean hasEquivalentExclusions( Collection<Exclusion> exclusions )
190 {
191 if ( exclusions == null || exclusions.isEmpty() )
192 {
193 return this.exclusions.isEmpty();
194 }
195 if ( exclusions instanceof Set )
196 {
197 return this.exclusions.equals( exclusions );
198 }
199 return exclusions.size() >= this.exclusions.size() && this.exclusions.containsAll( exclusions )
200 && exclusions.containsAll( this.exclusions );
201 }
202
203 @Override
204 public String toString()
205 {
206 return String.valueOf( getArtifact() ) + " (" + getScope() + ( isOptional() ? "?" : "" ) + ")";
207 }
208
209 @Override
210 public boolean equals( Object obj )
211 {
212 if ( obj == this )
213 {
214 return true;
215 }
216 else if ( obj == null || !getClass().equals( obj.getClass() ) )
217 {
218 return false;
219 }
220
221 Dependency that = (Dependency) obj;
222
223 return artifact.equals( that.artifact ) && scope.equals( that.scope ) && optional == that.optional
224 && exclusions.equals( that.exclusions );
225 }
226
227 @Override
228 public int hashCode()
229 {
230 int hash = 17;
231 hash = hash * 31 + artifact.hashCode();
232 hash = hash * 31 + scope.hashCode();
233 hash = hash * 31 + ( optional ? 1 : 0 );
234 hash = hash * 31 + exclusions.size();
235 return hash;
236 }
237
238 private static class Exclusions
239 extends AbstractSet<Exclusion>
240 {
241
242 private final Exclusion[] exclusions;
243
244 public static Set<Exclusion> copy( Collection<Exclusion> exclusions )
245 {
246 if ( exclusions == null || exclusions.isEmpty() )
247 {
248 return Collections.emptySet();
249 }
250 return new Exclusions( exclusions );
251 }
252
253 private Exclusions( Collection<Exclusion> exclusions )
254 {
255 if ( exclusions.size() > 1 && !( exclusions instanceof Set ) )
256 {
257 exclusions = new LinkedHashSet<Exclusion>( exclusions );
258 }
259 this.exclusions = exclusions.toArray( new Exclusion[exclusions.size()] );
260 }
261
262 @Override
263 public Iterator<Exclusion> iterator()
264 {
265 return new Iterator<Exclusion>()
266 {
267
268 private int cursor = 0;
269
270 public boolean hasNext()
271 {
272 return cursor < exclusions.length;
273 }
274
275 public Exclusion next()
276 {
277 try
278 {
279 Exclusion exclusion = exclusions[cursor];
280 cursor++;
281 return exclusion;
282 }
283 catch ( IndexOutOfBoundsException e )
284 {
285 throw new NoSuchElementException();
286 }
287 }
288
289 public void remove()
290 {
291 throw new UnsupportedOperationException();
292 }
293
294 };
295 }
296
297 @Override
298 public int size()
299 {
300 return exclusions.length;
301 }
302
303 }
304
305 }