• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

devonfw / IDEasy / 7263768820

19 Dec 2023 03:13PM UTC coverage: 49.404% (+1.5%) from 47.873%
7263768820

Pull #159

github

web-flow
Merge e50749a62 into 1d60d9c17
Pull Request #159: #158: VersionRange with open boundaries

1127 of 2459 branches covered (0.0%)

Branch coverage included in aggregate %.

2812 of 5514 relevant lines covered (51.0%)

2.11 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

69.46
cli/src/main/java/com/devonfw/tools/ide/version/VersionRange.java
1
package com.devonfw.tools.ide.version;
2

3
/**
4
 * Container for a range of versions. The lower and upper bounds can be exclusive or inclusive. If a bound is null, it
5
 * means that this direction is unbounded. The boolean defining whether this bound is inclusive or exclusive is ignored
6
 * in this case.
7
 */
8
public final class VersionRange implements Comparable<VersionRange> {
9

10
  private final VersionIdentifier min;
11

12
  private final VersionIdentifier max;
13

14
  private final boolean leftIsExclusive;
15

16
  private final boolean rightIsExclusive;
17

18
  private static final String VERSION_SEPARATOR = ">";
19

20
  private static final String START_EXCLUDING_PREFIX = "(";
21

22
  private static final String START_INCLUDING_PREFIX = "[";
23

24
  private static final String END_EXCLUDING_SUFFIX = ")";
25

26
  private static final String END_INCLUDING_SUFFIX = "]";
27

28
  /**
29
   * The constructor.
30
   *
31
   * @param min the {@link #getMin() minimum}.
32
   * @param max the {@link #getMax() maximum}.
33
   */
34
  public VersionRange(VersionIdentifier min, VersionIdentifier max) {
35

36
    super();
×
37
    this.min = min;
×
38
    this.max = max;
×
39
    this.leftIsExclusive = false;
×
40
    this.rightIsExclusive = false;
×
41
  }
×
42

43
  /**
44
   * The constructor.
45
   *
46
   * @param min the {@link #getMin() minimum}.
47
   * @param max the {@link #getMax() maximum}.
48
   * @param boundaryType the {@link BoundaryType} defining whether the boundaries of the range are inclusive or
49
   *        exclusive.
50
   */
51
  public VersionRange(VersionIdentifier min, VersionIdentifier max, BoundaryType boundaryType) {
52

53
    super();
×
54
    this.min = min;
×
55
    this.max = max;
×
56
    this.leftIsExclusive = BoundaryType.LEFT_OPEN.equals(boundaryType) || BoundaryType.OPEN.equals(boundaryType);
×
57
    this.rightIsExclusive = BoundaryType.RIGHT_OPEN.equals(boundaryType) || BoundaryType.OPEN.equals(boundaryType);
×
58
  }
×
59

60
  /**
61
   * The constructor.
62
   *
63
   * @param min the {@link #getMin() minimum}.
64
   * @param max the {@link #getMax() maximum}.
65
   * @param leftIsExclusive - {@code true} if the {@link #getMin() minimum} is exclusive, {@code false} otherwise.
66
   * @param rightIsExclusive - {@code true} if the {@link #getMax() maximum} is exclusive, {@code false} otherwise.
67
   */
68
  public VersionRange(VersionIdentifier min, VersionIdentifier max, boolean leftIsExclusive, boolean rightIsExclusive) {
69

70
    super();
2✔
71
    this.min = min;
3✔
72
    this.max = max;
3✔
73
    this.leftIsExclusive = leftIsExclusive;
3✔
74
    this.rightIsExclusive = rightIsExclusive;
3✔
75
  }
1✔
76

77
  /**
78
   * @return the minimum {@link VersionIdentifier} or {@code null} for no lower bound.
79
   */
80
  public VersionIdentifier getMin() {
81

82
    return this.min;
3✔
83
  }
84

85
  /**
86
   * @return the maximum {@link VersionIdentifier} or {@code null} for no upper bound.
87
   */
88
  public VersionIdentifier getMax() {
89

90
    return this.max;
3✔
91
  }
92

93
  /**
94
   * @return {@code true} if the {@link #getMin() minimum} is exclusive, {@code false} otherwise.
95
   */
96
  public boolean isLeftExclusive() {
97

98
    return this.leftIsExclusive;
3✔
99
  }
100

101
  /**
102
   * @return {@code true} if the {@link #getMax() maximum} is exclusive, {@code false} otherwise.
103
   */
104
  public boolean isRightExclusive() {
105

106
    return this.rightIsExclusive;
3✔
107
  }
108

109
  /**
110
   * @return the {@link BoundaryType} defining whether the boundaries of the range are inclusive or exclusive.
111
   */
112
  public BoundaryType getBoundaryType() {
113

114
    if (this.leftIsExclusive && this.rightIsExclusive) {
×
115
      return BoundaryType.OPEN;
×
116
    } else if (this.leftIsExclusive) {
×
117
      return BoundaryType.LEFT_OPEN;
×
118
    } else if (this.rightIsExclusive) {
×
119
      return BoundaryType.RIGHT_OPEN;
×
120
    } else {
121
      return BoundaryType.CLOSED;
×
122
    }
123
  }
124

125
  /**
126
   * @param version the {@link VersionIdentifier} to check.
127
   * @return {@code true} if the given {@link VersionIdentifier} is contained in this {@link VersionRange},
128
   *         {@code false} otherwise.
129
   */
130
  public boolean contains(VersionIdentifier version) {
131

132
    if (this.min != null) {
3!
133
      if (this.min.equals(version)) {
5✔
134
        return !this.leftIsExclusive;
7✔
135
      }
136
      if (version.isLess(this.min)) {
5✔
137
        return false;
2✔
138
      }
139
    }
140
    if (this.max != null) {
3!
141
      if (this.max.equals(version)) {
5✔
142
        return !this.rightIsExclusive;
7✔
143
      }
144
      if (version.isGreater(this.max)) {
5✔
145
        return false;
2✔
146
      }
147
    }
148
    return true;
2✔
149
  }
150

151
  @Override
152
  public int compareTo(VersionRange o) {
153

154
    if (this.min == null) {
3!
155
      if (o == null) {
×
156
        return 1; // should never happen
×
157
      } else if (o.min == null) {
×
158
        return 0;
×
159
      }
160
      return -1;
×
161
    }
162
    int compareMins = this.min.compareTo(o.min);
6✔
163
    if (compareMins == 0) {
2✔
164
      return this.leftIsExclusive == o.leftIsExclusive ? 0 : this.leftIsExclusive ? 1 : -1;
14✔
165
    } else {
166
      return compareMins;
2✔
167
    }
168
  }
169

170
  @Override
171
  public boolean equals(Object obj) {
172

173
    if (this == obj)
3!
174
      return true;
×
175

176
    if (obj == null || getClass() != obj.getClass())
7!
177
      return false;
2✔
178

179
    VersionRange o = (VersionRange) obj;
3✔
180

181
    if (this.min == null && this.max == null) {
6✔
182
      return o.min == null && o.max == null;
10!
183
    }
184
    if (this.min == null) {
3✔
185
      return o.min == null && this.max.equals(o.max) && this.rightIsExclusive == o.rightIsExclusive;
18!
186
    }
187
    if (this.max == null) {
3✔
188
      return this.min.equals(o.min) && o.max == null && this.leftIsExclusive == o.leftIsExclusive;
18!
189
    }
190
    return this.min.equals(o.min) && this.leftIsExclusive == o.leftIsExclusive && this.max.equals(o.max)
26!
191
        && this.rightIsExclusive == o.rightIsExclusive;
192

193
  }
194

195
  @Override
196
  public String toString() {
197

198
    StringBuilder sb = new StringBuilder();
4✔
199
    sb.append(this.leftIsExclusive ? START_EXCLUDING_PREFIX : START_INCLUDING_PREFIX);
9✔
200
    if (this.min != null) {
3!
201
      sb.append(this.min);
5✔
202
    }
203
    sb.append(VERSION_SEPARATOR);
4✔
204
    if (this.max != null) {
3✔
205
      sb.append(this.max);
5✔
206
    }
207
    sb.append(this.rightIsExclusive ? END_EXCLUDING_SUFFIX : END_INCLUDING_SUFFIX);
9✔
208
    return sb.toString();
3✔
209
  }
210

211
  /**
212
   * @param value the {@link #toString() string representation} of a {@link VersionRange} to parse.
213
   * @return the parsed {@link VersionRange}.
214
   */
215
  public static VersionRange of(String value) {
216

217
    boolean leftIsExclusive = false;
2✔
218
    boolean rightIsExclusive = false;
2✔
219

220
    if (value.startsWith(START_EXCLUDING_PREFIX)) {
4✔
221
      leftIsExclusive = true;
2✔
222
      value = value.substring(START_EXCLUDING_PREFIX.length());
5✔
223
    }
224
    if (value.startsWith(START_INCLUDING_PREFIX)) {
4✔
225
      value = value.substring(START_INCLUDING_PREFIX.length());
5✔
226
    }
227
    if (value.endsWith(END_EXCLUDING_SUFFIX)) {
4✔
228
      rightIsExclusive = true;
2✔
229
      value = value.substring(0, value.length() - END_EXCLUDING_SUFFIX.length());
9✔
230
    }
231
    if (value.endsWith(END_INCLUDING_SUFFIX)) {
4✔
232
      value = value.substring(0, value.length() - END_EXCLUDING_SUFFIX.length());
9✔
233
    }
234

235
    int index = value.indexOf(VERSION_SEPARATOR);
4✔
236
    if (index == -1) {
3!
237
      return null; // log warning?
×
238
    }
239

240
    VersionIdentifier min = null;
2✔
241
    if (index > 0) {
2✔
242
      min = VersionIdentifier.of(value.substring(0, index));
6✔
243
    }
244
    VersionIdentifier max = null;
2✔
245
    String maxString = value.substring(index + 1);
6✔
246
    if (!maxString.isEmpty()) {
3✔
247
      max = VersionIdentifier.of(maxString);
3✔
248
    }
249
    return new VersionRange(min, max, leftIsExclusive, rightIsExclusive);
8✔
250
  }
251

252
  public static String getVersionSeparator() {
253

254
    return VERSION_SEPARATOR;
×
255
  }
256

257
  public static String getStartExcludingPrefix() {
258

259
    return START_EXCLUDING_PREFIX;
×
260
  }
261

262
  public static String getStartIncludingPrefix() {
263

264
    return START_INCLUDING_PREFIX;
×
265
  }
266

267
  public static String getEndExcludingSuffix() {
268

269
    return END_EXCLUDING_SUFFIX;
×
270
  }
271

272
  public static String getEndIncludingSuffix() {
273

274
    return END_INCLUDING_SUFFIX;
×
275
  }
276

277
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc