• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 package org.apache.commons.lang3;
18 
19 import org.apache.commons.lang3.math.NumberUtils;
20 
21 /**
22  * An enum representing all the versions of the Java specification.
23  * This is intended to mirror available values from the
24  * <em>java.specification.version</em> System property.
25  *
26  * @since 3.0
27  */
28 public enum JavaVersion {
29 
30     /**
31      * The Java version reported by Android. This is not an official Java version number.
32      */
33     JAVA_0_9(1.5f, "0.9"),
34 
35     /**
36      * Java 1.1.
37      */
38     JAVA_1_1(1.1f, "1.1"),
39 
40     /**
41      * Java 1.2.
42      */
43     JAVA_1_2(1.2f, "1.2"),
44 
45     /**
46      * Java 1.3.
47      */
48     JAVA_1_3(1.3f, "1.3"),
49 
50     /**
51      * Java 1.4.
52      */
53     JAVA_1_4(1.4f, "1.4"),
54 
55     /**
56      * Java 1.5.
57      */
58     JAVA_1_5(1.5f, "1.5"),
59 
60     /**
61      * Java 1.6.
62      */
63     JAVA_1_6(1.6f, "1.6"),
64 
65     /**
66      * Java 1.7.
67      */
68     JAVA_1_7(1.7f, "1.7"),
69 
70     /**
71      * Java 1.8.
72      */
73     JAVA_1_8(1.8f, "1.8"),
74 
75     /**
76      * Java 1.9.
77      *
78      * @deprecated As of release 3.5, replaced by {@link #JAVA_9}
79      */
80     @Deprecated
81     JAVA_1_9(9.0f, "9"),
82 
83     /**
84      * Java 9.
85      *
86      * @since 3.5
87      */
88     JAVA_9(9.0f, "9"),
89 
90     /**
91      * Java 10.
92      *
93      * @since 3.7
94      */
95     JAVA_10(10.0f, "10"),
96 
97     /**
98      * Java 11.
99      *
100      * @since 3.8
101      */
102     JAVA_11(11.0f, "11"),
103 
104     /**
105      * Java 12.
106      *
107      * @since 3.9
108      */
109     JAVA_12(12.0f, "12"),
110 
111     /**
112      * Java 13.
113      *
114      * @since 3.9
115      */
116     JAVA_13(13.0f, "13"),
117 
118     /**
119      * Java 14.
120      *
121      * @since 3.11
122      */
123     JAVA_14(14.0f, "14"),
124 
125     /**
126      * Java 15.
127      *
128      * @since 3.11
129      */
130     JAVA_15(15.0f, "15"),
131 
132     /**
133      * Java 16.
134      *
135      * @since 3.11
136      */
137     JAVA_16(16.0f, "16"),
138 
139     /**
140      * Java 17.
141      *
142      * @since 3.12.0
143      */
144     JAVA_17(17.0f, "17"),
145 
146     /**
147      * Java 18.
148      *
149      * @since 3.13.0
150      */
151     JAVA_18(18.0f, "18"),
152 
153     /**
154      * The most recent java version. Mainly introduced to avoid to break when a new version of Java is used.
155      */
156     JAVA_RECENT(maxVersion(), Float.toString(maxVersion()));
157 
158     /**
159      * The float value.
160      */
161     private final float value;
162 
163     /**
164      * The standard name.
165      */
166     private final String name;
167 
168     /**
169      * Constructor.
170      *
171      * @param value  the float value
172      * @param name  the standard name, not null
173      */
JavaVersion(final float value, final String name)174     JavaVersion(final float value, final String name) {
175         this.value = value;
176         this.name = name;
177     }
178 
179     /**
180      * Whether this version of Java is at least the version of Java passed in.
181      *
182      * <p>For example:<br>
183      *  {@code myVersion.atLeast(JavaVersion.JAVA_1_4)}</p>
184      *
185      * @param requiredVersion  the version to check against, not null
186      * @return true if this version is equal to or greater than the specified version
187      */
atLeast(final JavaVersion requiredVersion)188     public boolean atLeast(final JavaVersion requiredVersion) {
189         return this.value >= requiredVersion.value;
190     }
191 
192     /**
193      * Whether this version of Java is at most the version of Java passed in.
194      *
195      * <p>For example:<br>
196      *  {@code myVersion.atMost(JavaVersion.JAVA_1_4)}</p>
197      *
198      * @param requiredVersion  the version to check against, not null
199      * @return true if this version is equal to or greater than the specified version
200      * @since 3.9
201      */
atMost(final JavaVersion requiredVersion)202     public boolean atMost(final JavaVersion requiredVersion) {
203         return this.value <= requiredVersion.value;
204     }
205 
206     /**
207      * Transforms the given string with a Java version number to the
208      * corresponding constant of this enumeration class. This method is used
209      * internally.
210      *
211      * @param versionStr the Java version as string
212      * @return the corresponding enumeration constant or <b>null</b> if the
213      * version is unknown
214      */
215     // helper for static importing
getJavaVersion(final String versionStr)216     static JavaVersion getJavaVersion(final String versionStr) {
217         return get(versionStr);
218     }
219 
220     /**
221      * Transforms the given string with a Java version number to the
222      * corresponding constant of this enumeration class. This method is used
223      * internally.
224      *
225      * @param versionStr the Java version as string
226      * @return the corresponding enumeration constant or <b>null</b> if the
227      * version is unknown
228      */
get(final String versionStr)229     static JavaVersion get(final String versionStr) {
230         if (versionStr == null) {
231             return null;
232         }
233         switch (versionStr) {
234         case "0.9":
235             return JAVA_0_9;
236         case "1.1":
237             return JAVA_1_1;
238         case "1.2":
239             return JAVA_1_2;
240         case "1.3":
241             return JAVA_1_3;
242         case "1.4":
243             return JAVA_1_4;
244         case "1.5":
245             return JAVA_1_5;
246         case "1.6":
247             return JAVA_1_6;
248         case "1.7":
249             return JAVA_1_7;
250         case "1.8":
251             return JAVA_1_8;
252         case "9":
253             return JAVA_9;
254         case "10":
255             return JAVA_10;
256         case "11":
257             return JAVA_11;
258         case "12":
259             return JAVA_12;
260         case "13":
261             return JAVA_13;
262         case "14":
263             return JAVA_14;
264         case "15":
265             return JAVA_15;
266         case "16":
267             return JAVA_16;
268         case "17":
269             return JAVA_17;
270         case "18":
271             return JAVA_18;
272         default:
273             final float v = toFloatVersion(versionStr);
274             if ((v - 1.) < 1.) { // then we need to check decimals > .9
275                 final int firstComma = Math.max(versionStr.indexOf('.'), versionStr.indexOf(','));
276                 final int end = Math.max(versionStr.length(), versionStr.indexOf(',', firstComma));
277                 if (Float.parseFloat(versionStr.substring(firstComma + 1, end)) > .9f) {
278                     return JAVA_RECENT;
279                 }
280             } else if (v > 10) {
281                 return JAVA_RECENT;
282             }
283             return null;
284         }
285     }
286 
287     /**
288      * The string value is overridden to return the standard name.
289      *
290      * <p>For example, {@code "1.5"}.</p>
291      *
292      * @return the name, not null
293      */
294     @Override
toString()295     public String toString() {
296         return name;
297     }
298 
299     /**
300      * Gets the Java Version from the system or 99.0 if the {@code java.specification.version} system property is not set.
301      *
302      * @return the value of {@code java.specification.version} system property or 99.0 if it is not set.
303      */
maxVersion()304     private static float maxVersion() {
305         final float v = toFloatVersion(System.getProperty("java.specification.version", "99.0"));
306         return v > 0 ? v : 99f;
307     }
308 
309     /**
310      * Parses a float value from a String.
311      *
312      * @param value the String to parse.
313      * @return the float value represented by the string or -1 if the given String can not be parsed.
314      */
toFloatVersion(final String value)315     private static float toFloatVersion(final String value) {
316         final int defaultReturnValue = -1;
317         if (!value.contains(".")) {
318             return NumberUtils.toFloat(value, defaultReturnValue);
319         }
320         final String[] toParse = value.split("\\.");
321         if (toParse.length >= 2) {
322             return NumberUtils.toFloat(toParse[0] + '.' + toParse[1], defaultReturnValue);
323         }
324         return defaultReturnValue;
325     }
326 }
327