4
4
import com .fasterxml .jackson .annotation .JsonValue ;
5
5
6
6
/**
7
- * Container for a range of versions.
7
+ * Container for a range of versions. The lower and upper bounds can be exclusive or inclusive. If a bound is null, it
8
+ * means that this direction is unbounded. The boolean defining whether this bound is inclusive or exclusive is ignored
9
+ * in this case.
8
10
*/
9
11
public final class VersionRange implements Comparable <VersionRange > {
10
12
11
13
private final VersionIdentifier min ;
12
14
13
15
private final VersionIdentifier max ;
14
16
17
+ private final boolean leftIsExclusive ;
18
+
19
+ private final boolean rightIsExclusive ;
20
+
15
21
/**
16
22
* The constructor.
17
23
*
@@ -24,6 +30,42 @@ public VersionRange(VersionIdentifier min, VersionIdentifier max) {
24
30
super ();
25
31
this .min = min ;
26
32
this .max = max ;
33
+ this .leftIsExclusive = false ;
34
+ this .rightIsExclusive = false ;
35
+ }
36
+
37
+ /**
38
+ * The constructor.
39
+ *
40
+ * @param min the {@link #getMin() minimum}.
41
+ * @param max the {@link #getMax() maximum}.
42
+ * @param boundaryType the {@link BoundaryType} defining whether the boundaries of the range are inclusive or
43
+ * exclusive.
44
+ */
45
+ public VersionRange (VersionIdentifier min , VersionIdentifier max , BoundaryType boundaryType ) {
46
+
47
+ super ();
48
+ this .min = min ;
49
+ this .max = max ;
50
+ this .leftIsExclusive = BoundaryType .LEFT_OPEN .equals (boundaryType ) || BoundaryType .OPEN .equals (boundaryType );
51
+ this .rightIsExclusive = BoundaryType .RIGHT_OPEN .equals (boundaryType ) || BoundaryType .OPEN .equals (boundaryType );
52
+ }
53
+
54
+ /**
55
+ * The constructor.
56
+ *
57
+ * @param min the {@link #getMin() minimum}.
58
+ * @param max the {@link #getMax() maximum}.
59
+ * @param leftIsExclusive - {@code true} if the {@link #getMin() minimum} is exclusive, {@code false} otherwise.
60
+ * @param rightIsExclusive - {@code true} if the {@link #getMax() maximum} is exclusive, {@code false} otherwise.
61
+ */
62
+ public VersionRange (VersionIdentifier min , VersionIdentifier max , boolean leftIsExclusive , boolean rightIsExclusive ) {
63
+
64
+ super ();
65
+ this .min = min ;
66
+ this .max = max ;
67
+ this .leftIsExclusive = leftIsExclusive ;
68
+ this .rightIsExclusive = rightIsExclusive ;
27
69
}
28
70
29
71
/**
@@ -44,6 +86,38 @@ public VersionIdentifier getMax() {
44
86
return this .max ;
45
87
}
46
88
89
+ /**
90
+ * @return {@code true} if the {@link #getMin() minimum} is exclusive, {@code false} otherwise.
91
+ */
92
+ public boolean isLeftExclusive () {
93
+
94
+ return this .leftIsExclusive ;
95
+ }
96
+
97
+ /**
98
+ * @return {@code true} if the {@link #getMax() maximum} is exclusive, {@code false} otherwise.
99
+ */
100
+ public boolean isRightExclusive () {
101
+
102
+ return this .rightIsExclusive ;
103
+ }
104
+
105
+ /**
106
+ * @return the {@link BoundaryType} defining whether the boundaries of the range are inclusive or exclusive.
107
+ */
108
+ public BoundaryType getBoundaryType () {
109
+
110
+ if (this .leftIsExclusive && this .rightIsExclusive ) {
111
+ return BoundaryType .OPEN ;
112
+ } else if (this .leftIsExclusive ) {
113
+ return BoundaryType .LEFT_OPEN ;
114
+ } else if (this .rightIsExclusive ) {
115
+ return BoundaryType .RIGHT_OPEN ;
116
+ } else {
117
+ return BoundaryType .CLOSED ;
118
+ }
119
+ }
120
+
47
121
/**
48
122
* @param version the {@link VersionIdentifier} to check.
49
123
* @return {@code true} if the given {@link VersionIdentifier} is contained in this {@link VersionRange},
@@ -52,11 +126,17 @@ public VersionIdentifier getMax() {
52
126
public boolean contains (VersionIdentifier version ) {
53
127
54
128
if (this .min != null ) {
129
+ if (this .min .equals (version )) {
130
+ return !this .leftIsExclusive ;
131
+ }
55
132
if (version .isLess (this .min )) {
56
133
return false ;
57
134
}
58
135
}
59
136
if (this .max != null ) {
137
+ if (this .max .equals (version )) {
138
+ return !this .rightIsExclusive ;
139
+ }
60
140
if (version .isGreater (this .max )) {
61
141
return false ;
62
142
}
@@ -75,7 +155,37 @@ public int compareTo(VersionRange o) {
75
155
}
76
156
return -1 ;
77
157
}
78
- return this .min .compareTo (o .min );
158
+ int compareMins = this .min .compareTo (o .min );
159
+ if (compareMins == 0 ) {
160
+ return this .leftIsExclusive == o .leftIsExclusive ? 0 : this .leftIsExclusive ? 1 : -1 ;
161
+ } else {
162
+ return compareMins ;
163
+ }
164
+ }
165
+
166
+ @ Override
167
+ public boolean equals (Object obj ) {
168
+
169
+ if (this == obj )
170
+ return true ;
171
+
172
+ if (obj == null || getClass () != obj .getClass ())
173
+ return false ;
174
+
175
+ VersionRange o = (VersionRange ) obj ;
176
+
177
+ if (this .min == null && this .max == null ) {
178
+ return o .min == null && o .max == null ;
179
+ }
180
+ if (this .min == null ) {
181
+ return o .min == null && this .max .equals (o .max ) && this .rightIsExclusive == o .rightIsExclusive ;
182
+ }
183
+ if (this .max == null ) {
184
+ return this .min .equals (o .min ) && o .max == null && this .leftIsExclusive == o .leftIsExclusive ;
185
+ }
186
+ return this .min .equals (o .min ) && this .leftIsExclusive == o .leftIsExclusive && this .max .equals (o .max )
187
+ && this .rightIsExclusive == o .rightIsExclusive ;
188
+
79
189
}
80
190
81
191
@ Override
@@ -107,13 +217,15 @@ public boolean equals(Object obj) {
107
217
public String toString () {
108
218
109
219
StringBuilder sb = new StringBuilder ();
220
+ sb .append (this .leftIsExclusive ? '(' : '[' );
110
221
if (this .min != null ) {
111
222
sb .append (this .min );
112
223
}
113
224
sb .append ('>' );
114
225
if (this .max != null ) {
115
226
sb .append (this .max );
116
227
}
228
+ sb .append (this .rightIsExclusive ? ')' : ']' );
117
229
return sb .toString ();
118
230
}
119
231
@@ -124,10 +236,29 @@ public String toString() {
124
236
@ JsonCreator
125
237
public static VersionRange of (String value ) {
126
238
239
+ boolean leftIsExclusive = false ;
240
+ boolean rightIsExclusive = false ;
241
+
242
+ if (value .startsWith ("(" )) {
243
+ leftIsExclusive = true ;
244
+ value = value .substring (1 );
245
+ }
246
+ if (value .startsWith ("[" )) {
247
+ value = value .substring (1 );
248
+ }
249
+ if (value .endsWith (")" )) {
250
+ rightIsExclusive = true ;
251
+ value = value .substring (0 , value .length () - 1 );
252
+ }
253
+ if (value .endsWith ("]" )) {
254
+ value = value .substring (0 , value .length () - 1 );
255
+ }
256
+
127
257
int index = value .indexOf ('>' );
128
258
if (index == -1 ) {
129
259
return null ; // log warning?
130
260
}
261
+
131
262
VersionIdentifier min = null ;
132
263
if (index > 0 ) {
133
264
min = VersionIdentifier .of (value .substring (0 , index ));
@@ -137,7 +268,7 @@ public static VersionRange of(String value) {
137
268
if (!maxString .isEmpty ()) {
138
269
max = VersionIdentifier .of (maxString );
139
270
}
140
- return new VersionRange (min , max );
271
+ return new VersionRange (min , max , leftIsExclusive , rightIsExclusive );
141
272
}
142
273
143
274
}
0 commit comments