1 package org.eclipse.aether.util.graph.selector;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.Arrays;
23 import java.util.Collection;
24 import java.util.Comparator;
25 import java.util.TreeSet;
26
27 import org.eclipse.aether.artifact.Artifact;
28 import org.eclipse.aether.collection.DependencyCollectionContext;
29 import org.eclipse.aether.collection.DependencySelector;
30 import org.eclipse.aether.graph.Dependency;
31 import org.eclipse.aether.graph.Exclusion;
32
33 import static java.util.Objects.requireNonNull;
34
35
36
37
38
39
40 public final class ExclusionDependencySelector
41 implements DependencySelector
42 {
43
44
45 private final Exclusion[] exclusions;
46
47 private int hashCode;
48
49
50
51
52 public ExclusionDependencySelector()
53 {
54 this.exclusions = new Exclusion[0];
55 }
56
57
58
59
60
61
62 public ExclusionDependencySelector( Collection<Exclusion> exclusions )
63 {
64 if ( exclusions != null && !exclusions.isEmpty() )
65 {
66 TreeSet<Exclusion> sorted = new TreeSet<>( ExclusionComparator.INSTANCE );
67 sorted.addAll( exclusions );
68 this.exclusions = sorted.toArray( new Exclusion[0] );
69 }
70 else
71 {
72 this.exclusions = new Exclusion[0];
73 }
74 }
75
76 private ExclusionDependencySelector( Exclusion[] exclusions )
77 {
78 this.exclusions = exclusions;
79 }
80
81 public boolean selectDependency( Dependency dependency )
82 {
83 requireNonNull( dependency, "dependency cannot be null" );
84 Artifact artifact = dependency.getArtifact();
85 for ( Exclusion exclusion : exclusions )
86 {
87 if ( matches( exclusion, artifact ) )
88 {
89 return false;
90 }
91 }
92 return true;
93 }
94
95 private boolean matches( Exclusion exclusion, Artifact artifact )
96 {
97 if ( !matches( exclusion.getArtifactId(), artifact.getArtifactId() ) )
98 {
99 return false;
100 }
101 if ( !matches( exclusion.getGroupId(), artifact.getGroupId() ) )
102 {
103 return false;
104 }
105 if ( !matches( exclusion.getExtension(), artifact.getExtension() ) )
106 {
107 return false;
108 }
109 if ( !matches( exclusion.getClassifier(), artifact.getClassifier() ) )
110 {
111 return false;
112 }
113 return true;
114 }
115
116 private boolean matches( String pattern, String value )
117 {
118 return "*".equals( pattern ) || pattern.equals( value );
119 }
120
121 public DependencySelector deriveChildSelector( DependencyCollectionContext context )
122 {
123 requireNonNull( context, "context cannot be null" );
124 Dependency dependency = context.getDependency();
125 Collection<Exclusion> exclusions = ( dependency != null ) ? dependency.getExclusions() : null;
126 if ( exclusions == null || exclusions.isEmpty() )
127 {
128 return this;
129 }
130
131 Exclusion[] merged = this.exclusions;
132 int count = merged.length;
133 for ( Exclusion exclusion : exclusions )
134 {
135 int index = Arrays.binarySearch( merged, exclusion, ExclusionComparator.INSTANCE );
136 if ( index < 0 )
137 {
138 index = -( index + 1 );
139 if ( count >= merged.length )
140 {
141 Exclusion[] tmp = new Exclusion[merged.length + exclusions.size()];
142 System.arraycopy( merged, 0, tmp, 0, index );
143 tmp[index] = exclusion;
144 System.arraycopy( merged, index, tmp, index + 1, count - index );
145 merged = tmp;
146 }
147 else
148 {
149 System.arraycopy( merged, index, merged, index + 1, count - index );
150 merged[index] = exclusion;
151 }
152 count++;
153 }
154 }
155 if ( merged == this.exclusions )
156 {
157 return this;
158 }
159 if ( merged.length != count )
160 {
161 Exclusion[] tmp = new Exclusion[count];
162 System.arraycopy( merged, 0, tmp, 0, count );
163 merged = tmp;
164 }
165
166 return new ExclusionDependencySelector( merged );
167 }
168
169 @Override
170 public boolean equals( Object obj )
171 {
172 if ( this == obj )
173 {
174 return true;
175 }
176 else if ( null == obj || !getClass().equals( obj.getClass() ) )
177 {
178 return false;
179 }
180
181 ExclusionDependencySelector that = (ExclusionDependencySelector) obj;
182 return Arrays.equals( exclusions, that.exclusions );
183 }
184
185 @Override
186 public int hashCode()
187 {
188 if ( hashCode == 0 )
189 {
190 int hash = getClass().hashCode();
191 hash = hash * 31 + Arrays.hashCode( exclusions );
192 hashCode = hash;
193 }
194 return hashCode;
195 }
196
197 @Override
198 public String toString()
199 {
200 StringBuilder builder = new StringBuilder().append( this.getClass().getSimpleName() ).append( '(' );
201 for ( int i = 0; i < this.exclusions.length; i++ )
202 {
203 builder.append( this.exclusions[i] );
204 if ( i < this.exclusions.length - 1 )
205 {
206 builder.append( ", " );
207 }
208 }
209 return builder.append( ')' ).toString();
210 }
211
212 private static class ExclusionComparator
213 implements Comparator<Exclusion>
214 {
215
216 static final ExclusionComparator INSTANCE = new ExclusionComparator();
217
218 public int compare( Exclusion e1, Exclusion e2 )
219 {
220 if ( e1 == null )
221 {
222 return ( e2 == null ) ? 0 : 1;
223 }
224 else if ( e2 == null )
225 {
226 return -1;
227 }
228 int rel = e1.getArtifactId().compareTo( e2.getArtifactId() );
229 if ( rel == 0 )
230 {
231 rel = e1.getGroupId().compareTo( e2.getGroupId() );
232 if ( rel == 0 )
233 {
234 rel = e1.getExtension().compareTo( e2.getExtension() );
235 if ( rel == 0 )
236 {
237 rel = e1.getClassifier().compareTo( e2.getClassifier() );
238 }
239 }
240 }
241 return rel;
242 }
243
244 }
245
246 }