1 package org.eclipse.aether.util.filter;
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.HashSet;
25 import java.util.List;
26 import java.util.Objects;
27 import java.util.Set;
28
29 import org.eclipse.aether.artifact.Artifact;
30 import org.eclipse.aether.graph.Dependency;
31 import org.eclipse.aether.graph.DependencyFilter;
32 import org.eclipse.aether.graph.DependencyNode;
33 import org.eclipse.aether.version.InvalidVersionSpecificationException;
34 import org.eclipse.aether.version.Version;
35 import org.eclipse.aether.version.VersionRange;
36 import org.eclipse.aether.version.VersionScheme;
37
38 import static java.util.Objects.requireNonNull;
39
40
41
42 class AbstractPatternDependencyFilter
43 implements DependencyFilter
44 {
45
46 private final Set<String> patterns = new HashSet<>();
47
48 private final VersionScheme versionScheme;
49
50
51
52
53
54
55 AbstractPatternDependencyFilter( final String... patterns )
56 {
57 this( null, patterns );
58 }
59
60
61
62
63
64
65
66
67 AbstractPatternDependencyFilter( final VersionScheme versionScheme, final String... patterns )
68 {
69 this( versionScheme, patterns == null ? null : Arrays.asList( patterns ) );
70 }
71
72
73
74
75
76
77 AbstractPatternDependencyFilter( final Collection<String> patterns )
78 {
79 this( null, patterns );
80 }
81
82
83
84
85
86
87
88
89 AbstractPatternDependencyFilter( final VersionScheme versionScheme, final Collection<String> patterns )
90 {
91 if ( patterns != null )
92 {
93 this.patterns.addAll( patterns );
94 }
95 this.versionScheme = versionScheme;
96 }
97
98 public boolean accept( final DependencyNode node, List<DependencyNode> parents )
99 {
100 requireNonNull( node, "node cannot be null" );
101 requireNonNull( parents, "parents cannot be null" );
102 final Dependency dependency = node.getDependency();
103 if ( dependency == null )
104 {
105 return true;
106 }
107 return accept( dependency.getArtifact() );
108 }
109
110 protected boolean accept( final Artifact artifact )
111 {
112 for ( final String pattern : patterns )
113 {
114 final boolean matched = accept( artifact, pattern );
115 if ( matched )
116 {
117 return true;
118 }
119 }
120 return false;
121 }
122
123 private boolean accept( final Artifact artifact, final String pattern )
124 {
125 final String[] tokens =
126 new String[] { artifact.getGroupId(), artifact.getArtifactId(), artifact.getExtension(),
127 artifact.getBaseVersion() };
128
129 final String[] patternTokens = pattern.split( ":" );
130
131
132 boolean matched = ( patternTokens.length <= tokens.length );
133
134 for ( int i = 0; matched && i < patternTokens.length; i++ )
135 {
136 matched = matches( tokens[i], patternTokens[i] );
137 }
138
139 return matched;
140 }
141
142 private boolean matches( final String token, final String pattern )
143 {
144 boolean matches;
145
146
147 if ( "*".equals( pattern ) || pattern.length() == 0 )
148 {
149 matches = true;
150 }
151
152 else if ( pattern.startsWith( "*" ) && pattern.endsWith( "*" ) )
153 {
154 final String contains = pattern.substring( 1, pattern.length() - 1 );
155
156 matches = ( token.contains( contains ) );
157 }
158
159 else if ( pattern.startsWith( "*" ) )
160 {
161 final String suffix = pattern.substring( 1 );
162
163 matches = token.endsWith( suffix );
164 }
165
166 else if ( pattern.endsWith( "*" ) )
167 {
168 final String prefix = pattern.substring( 0, pattern.length() - 1 );
169
170 matches = token.startsWith( prefix );
171 }
172
173 else if ( pattern.startsWith( "[" ) || pattern.startsWith( "(" ) )
174 {
175 matches = isVersionIncludedInRange( token, pattern );
176 }
177
178 else
179 {
180 matches = token.equals( pattern );
181 }
182
183 return matches;
184 }
185
186 private boolean isVersionIncludedInRange( final String version, final String range )
187 {
188 if ( versionScheme == null )
189 {
190 return false;
191 }
192 else
193 {
194 try
195 {
196 final Version parsedVersion = versionScheme.parseVersion( version );
197 final VersionRange parsedRange = versionScheme.parseVersionRange( range );
198
199 return parsedRange.containsVersion( parsedVersion );
200 }
201 catch ( final InvalidVersionSpecificationException e )
202 {
203 return false;
204 }
205 }
206 }
207
208 @Override
209 public boolean equals( final Object obj )
210 {
211 if ( this == obj )
212 {
213 return true;
214 }
215
216 if ( obj == null || !getClass().equals( obj.getClass() ) )
217 {
218 return false;
219 }
220
221 final AbstractPatternDependencyFilter that = (AbstractPatternDependencyFilter) obj;
222
223 return Objects.equals( this.patterns, that.patterns )
224 && Objects.equals( this.versionScheme, that.versionScheme );
225 }
226
227 @Override
228 public int hashCode()
229 {
230 int hash = 17;
231 hash = hash * 31 + patterns.hashCode();
232 hash = hash * 31 + ( ( versionScheme == null ) ? 0 : versionScheme.hashCode() );
233 return hash;
234 }
235
236 }