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