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