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 }