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