1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.aether.internal.test.util;
20
21 import java.util.Objects;
22
23 import org.eclipse.aether.version.InvalidVersionSpecificationException;
24 import org.eclipse.aether.version.Version;
25 import org.eclipse.aether.version.VersionRange;
26
27
28
29
30 final class TestVersionRange implements VersionRange {
31
32 private final Version lowerBound;
33
34 private final boolean lowerBoundInclusive;
35
36 private final Version upperBound;
37
38 private final boolean upperBoundInclusive;
39
40
41
42
43
44
45
46 TestVersionRange(String range) throws InvalidVersionSpecificationException {
47 String process = range;
48
49 if (range.startsWith("[")) {
50 lowerBoundInclusive = true;
51 } else if (range.startsWith("(")) {
52 lowerBoundInclusive = false;
53 } else {
54 throw new InvalidVersionSpecificationException(
55 range, "Invalid version range " + range + ", a range must start with either [ or (");
56 }
57
58 if (range.endsWith("]")) {
59 upperBoundInclusive = true;
60 } else if (range.endsWith(")")) {
61 upperBoundInclusive = false;
62 } else {
63 throw new InvalidVersionSpecificationException(
64 range, "Invalid version range " + range + ", a range must end with either [ or (");
65 }
66
67 process = process.substring(1, process.length() - 1);
68
69 int index = process.indexOf(",");
70
71 if (index < 0) {
72 if (!lowerBoundInclusive || !upperBoundInclusive) {
73 throw new InvalidVersionSpecificationException(
74 range, "Invalid version range " + range + ", single version must be surrounded by []");
75 }
76
77 lowerBound = new TestVersion(process.trim());
78 upperBound = new TestVersion(process.trim());
79 } else {
80 String parsedLowerBound = process.substring(0, index).trim();
81 String parsedUpperBound = process.substring(index + 1).trim();
82
83
84 if (parsedUpperBound.contains(",")) {
85 throw new InvalidVersionSpecificationException(
86 range, "Invalid version range " + range + ", bounds may not contain additional ','");
87 }
88
89 lowerBound = !parsedLowerBound.isEmpty() ? new TestVersion(parsedLowerBound) : null;
90 upperBound = !parsedUpperBound.isEmpty() ? new TestVersion(parsedUpperBound) : null;
91
92 if (upperBound != null && lowerBound != null) {
93 if (upperBound.compareTo(lowerBound) < 0) {
94 throw new InvalidVersionSpecificationException(
95 range,
96 "Invalid version range " + range + ", lower bound must not be greater than upper bound");
97 }
98 }
99 }
100 }
101
102 public Bound getLowerBound() {
103 return new Bound(lowerBound, lowerBoundInclusive);
104 }
105
106 public Bound getUpperBound() {
107 return new Bound(upperBound, upperBoundInclusive);
108 }
109
110 public boolean acceptsSnapshots() {
111 return isSnapshot(lowerBound) || isSnapshot(upperBound);
112 }
113
114 public boolean containsVersion(Version version) {
115 boolean snapshot = isSnapshot(version);
116
117 if (lowerBound != null) {
118 int comparison = lowerBound.compareTo(version);
119
120 if (snapshot && comparison == 0) {
121 return true;
122 }
123
124 if (comparison == 0 && !lowerBoundInclusive) {
125 return false;
126 }
127 if (comparison > 0) {
128 return false;
129 }
130 }
131
132 if (upperBound != null) {
133 int comparison = upperBound.compareTo(version);
134
135 if (snapshot && comparison == 0) {
136 return true;
137 }
138
139 if (comparison == 0 && !upperBoundInclusive) {
140 return false;
141 }
142 if (comparison < 0) {
143 return false;
144 }
145 }
146
147 if (lowerBound != null || upperBound != null) {
148 return !snapshot;
149 }
150
151 return true;
152 }
153
154 private boolean isSnapshot(Version version) {
155 return version != null && version.toString().endsWith("SNAPSHOT");
156 }
157
158 @Override
159 public boolean equals(Object obj) {
160 if (obj == this) {
161 return true;
162 } else if (obj == null || !getClass().equals(obj.getClass())) {
163 return false;
164 }
165
166 TestVersionRange that = (TestVersionRange) obj;
167
168 return upperBoundInclusive == that.upperBoundInclusive
169 && lowerBoundInclusive == that.lowerBoundInclusive
170 && Objects.equals(upperBound, that.upperBound)
171 && Objects.equals(lowerBound, that.lowerBound);
172 }
173
174 @Override
175 public int hashCode() {
176 int hash = 17;
177 hash = hash * 31 + hash(upperBound);
178 hash = hash * 31 + (upperBoundInclusive ? 1 : 0);
179 hash = hash * 31 + hash(lowerBound);
180 hash = hash * 31 + (lowerBoundInclusive ? 1 : 0);
181 return hash;
182 }
183
184 private static int hash(Object obj) {
185 return obj != null ? obj.hashCode() : 0;
186 }
187
188 @Override
189 public String toString() {
190 StringBuilder buffer = new StringBuilder(64);
191 buffer.append(lowerBoundInclusive ? '[' : '(');
192 if (lowerBound != null) {
193 buffer.append(lowerBound);
194 }
195 buffer.append(',');
196 if (upperBound != null) {
197 buffer.append(upperBound);
198 }
199 buffer.append(upperBoundInclusive ? ']' : ')');
200 return buffer.toString();
201 }
202 }