1 package org.codehaus.plexus.languages.java.version;
2
3 import java.util.Objects;
4 import java.util.StringTokenizer;
5 import java.util.regex.Matcher;
6 import java.util.regex.Pattern;
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 public class JavaVersion implements Comparable<JavaVersion> {
36
37
38
39 public static final JavaVersion JAVA_SPECIFICATION_VERSION =
40 parse(System.getProperty("java.specification.version"));
41
42
43
44
45 public static final JavaVersion JAVA_VERSION = parse(System.getProperty("java.version"));
46
47 private static final Pattern startingDigits = Pattern.compile("(\\d+)(.*)");
48
49 private final String rawVersion;
50
51 private final boolean isMajor;
52
53 private JavaVersion(String rawVersion, boolean isMajor) {
54 this.rawVersion = rawVersion;
55 this.isMajor = isMajor;
56 }
57
58
59
60
61
62
63
64
65 public static JavaVersion parse(String s) {
66 return new JavaVersion(s, !s.startsWith("1."));
67 }
68
69 @Override
70 public int compareTo(JavaVersion other) {
71 String[] thisSegments = this.rawVersion.split("\\.");
72 String[] otherSegments = other.rawVersion.split("\\.");
73
74 int minSegments = Math.min(thisSegments.length, otherSegments.length);
75
76 for (int index = 0; index < minSegments; index++) {
77 Matcher thisMatcher = startingDigits.matcher(thisSegments[index]);
78
79 int thisValue;
80
81 if (thisMatcher.find()) {
82 thisValue = Integer.parseInt(thisMatcher.group(1));
83 } else {
84 thisValue = -1;
85 }
86
87 Matcher otherMatcher = startingDigits.matcher(otherSegments[index]);
88
89 int otherValue;
90
91 if (otherMatcher.find()) {
92 otherValue = Integer.parseInt(otherMatcher.group(1));
93 } else {
94 otherValue = -1;
95 }
96
97 int compareValue = Integer.compare(thisValue, otherValue);
98
99 if (compareValue != 0) {
100 return compareValue;
101 }
102
103 compareValue = suffixRate(thisMatcher.group(2)) - suffixRate(otherMatcher.group(2));
104 if (compareValue != 0) {
105 return compareValue;
106 }
107
108
109 compareValue = thisMatcher.group(2).compareTo(otherMatcher.group(2));
110
111 if (compareValue != 0) {
112 return compareValue;
113 }
114 }
115
116 return (thisSegments.length - otherSegments.length);
117 }
118
119 private int suffixRate(String suffix) {
120 if ("-ea".equals(suffix)) {
121 return -100;
122 } else if ("".equals(suffix)) {
123 return 0;
124 } else {
125 return 10;
126 }
127 }
128
129
130
131
132
133
134
135 public boolean isBefore(JavaVersion other) {
136 return this.compareTo(other) < 0;
137 }
138
139
140
141
142
143
144
145 public boolean isBefore(String other) {
146 return this.compareTo(parse(other)) < 0;
147 }
148
149
150
151
152
153
154
155 public boolean isAtLeast(JavaVersion other) {
156 return this.compareTo(other) >= 0;
157 }
158
159
160
161
162
163
164
165 public boolean isAtLeast(String other) {
166 return this.compareTo(parse(other)) >= 0;
167 }
168
169
170
171
172
173
174 public JavaVersion asMajor() {
175 if (!isMajor) {
176 return new JavaVersion(rawVersion.substring(2), true);
177 } else {
178 return this;
179 }
180 }
181
182
183
184
185
186
187 public String getValue() {
188 return rawVersion;
189 }
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206 public String getValue(int groups) {
207 StringBuilder value = new StringBuilder();
208 StringTokenizer tokenizer = new StringTokenizer(rawVersion, ".");
209
210 value.append(tokenizer.nextToken());
211 for (int group = 1; group < groups; group++) {
212 value.append('.');
213 if (tokenizer.hasMoreTokens()) {
214 value.append(tokenizer.nextToken());
215 } else {
216 value.append("0");
217 }
218 }
219 return value.toString();
220 }
221
222 @Override
223 public String toString() {
224 return rawVersion;
225 }
226
227 @Override
228 public int hashCode() {
229 return Objects.hashCode(rawVersion);
230 }
231
232 @Override
233 public boolean equals(Object obj) {
234 if (this == obj) {
235 return true;
236 }
237 if (obj == null) {
238 return false;
239 }
240 if (getClass() != obj.getClass()) {
241 return false;
242 }
243
244 JavaVersion other = (JavaVersion) obj;
245 if (isMajor != other.isMajor) {
246 final String thisOneDotVersion;
247 final String otherOneDotVersion;
248 if (isMajor) {
249 thisOneDotVersion = "1." + rawVersion;
250 otherOneDotVersion = other.rawVersion;
251 } else {
252 thisOneDotVersion = rawVersion;
253 otherOneDotVersion = "1." + other.rawVersion;
254 }
255
256 if (!Objects.equals(thisOneDotVersion, otherOneDotVersion)) {
257 return false;
258 }
259 } else if (!Objects.equals(rawVersion, other.rawVersion)) {
260 return false;
261 }
262 return true;
263 }
264 }