1 /*
2 * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.lang;
27
28 import java.io.*;
29 import java.util.StringTokenizer;
30 import jdk.internal.reflect.CallerSensitive;
31 import jdk.internal.reflect.Reflection;
32
33 /**
34 * Every Java application has a single instance of class
35 * {@code Runtime} that allows the application to interface with
36 * the environment in which the application is running. The current
37 * runtime can be obtained from the {@code getRuntime} method.
38 * <p>
39 * An application cannot create its own instance of this class.
40 *
41 * @author unascribed
42 * @see java.lang.Runtime#getRuntime()
43 * @since 1.0
44 */
45
46 public class Runtime {
47 private static final Runtime currentRuntime = new Runtime();
48
49 /**
50 * Returns the runtime object associated with the current Java application.
51 * Most of the methods of class {@code Runtime} are instance
52 * methods and must be invoked with respect to the current runtime object.
53 *
54 * @return the {@code Runtime} object associated with the current
55 * Java application.
56 */
57 public static Runtime getRuntime() {
58 return currentRuntime;
59 }
60
61 /** Don't let anyone else instantiate this class */
62 private Runtime() {}
63
64 /**
65 * Terminates the currently running Java virtual machine by initiating its
66 * shutdown sequence. This method never returns normally. The argument
67 * serves as a status code; by convention, a nonzero status code indicates
68 * abnormal termination.
900 * as the result.
901 *
902 * @deprecated As of JDK 1.1, the preferred way to translate a
903 * Unicode character stream into a byte stream in the local encoding is via
904 * the {@code OutputStreamWriter}, {@code BufferedWriter}, and
905 * {@code PrintWriter} classes.
906 * This method is subject to removal in a future version of Java SE.
907 *
908 * @param out OutputStream to localize
909 * @return a localized output stream
910 * @see java.io.OutputStream
911 * @see java.io.BufferedWriter#BufferedWriter(java.io.Writer)
912 * @see java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream)
913 * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream)
914 */
915 @Deprecated(since="1.1", forRemoval=true)
916 public OutputStream getLocalizedOutputStream(OutputStream out) {
917 return out;
918 }
919
920 }
|
1 /*
2 * Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.lang;
27
28 import java.io.*;
29 import java.math.BigInteger;
30 import java.util.AbstractList;
31 import java.util.Arrays;
32 import java.util.ArrayList;
33 import java.util.regex.Matcher;
34 import java.util.regex.Pattern;
35 import java.util.stream.Collectors;
36 import java.util.Collections;
37 import java.util.List;
38 import java.util.Optional;
39 import java.util.RandomAccess;
40 import java.util.StringTokenizer;
41 import jdk.internal.reflect.CallerSensitive;
42 import jdk.internal.reflect.Reflection;
43 import sun.security.action.GetPropertyAction;
44
45 /**
46 * Every Java application has a single instance of class
47 * {@code Runtime} that allows the application to interface with
48 * the environment in which the application is running. The current
49 * runtime can be obtained from the {@code getRuntime} method.
50 * <p>
51 * An application cannot create its own instance of this class.
52 *
53 * @author unascribed
54 * @see java.lang.Runtime#getRuntime()
55 * @since 1.0
56 */
57
58 public class Runtime {
59 private static final Runtime currentRuntime = new Runtime();
60
61 private static Version version;
62
63 /**
64 * Returns the runtime object associated with the current Java application.
65 * Most of the methods of class {@code Runtime} are instance
66 * methods and must be invoked with respect to the current runtime object.
67 *
68 * @return the {@code Runtime} object associated with the current
69 * Java application.
70 */
71 public static Runtime getRuntime() {
72 return currentRuntime;
73 }
74
75 /** Don't let anyone else instantiate this class */
76 private Runtime() {}
77
78 /**
79 * Terminates the currently running Java virtual machine by initiating its
80 * shutdown sequence. This method never returns normally. The argument
81 * serves as a status code; by convention, a nonzero status code indicates
82 * abnormal termination.
914 * as the result.
915 *
916 * @deprecated As of JDK 1.1, the preferred way to translate a
917 * Unicode character stream into a byte stream in the local encoding is via
918 * the {@code OutputStreamWriter}, {@code BufferedWriter}, and
919 * {@code PrintWriter} classes.
920 * This method is subject to removal in a future version of Java SE.
921 *
922 * @param out OutputStream to localize
923 * @return a localized output stream
924 * @see java.io.OutputStream
925 * @see java.io.BufferedWriter#BufferedWriter(java.io.Writer)
926 * @see java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream)
927 * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream)
928 */
929 @Deprecated(since="1.1", forRemoval=true)
930 public OutputStream getLocalizedOutputStream(OutputStream out) {
931 return out;
932 }
933
934 /**
935 * Returns the version of the Java Runtime Environment as a {@link
936 * Runtime.Version}.
937 *
938 * @return the {@link Runtime.Version} of the Java Runtime Environment
939 *
940 * @since 9
941 */
942 public static Version version() {
943 if (version == null) {
944 version = Version.parse(
945 GetPropertyAction.privilegedGetProperty("java.runtime.version"));
946 }
947 return version;
948 }
949
950 /**
951 * A representation of a version string for an implemenation of the
952 * Java SE Platform. A version string contains a version number
953 * optionally followed by pre-release and build information.
954 *
955 * <h2><a name="verNum">Version numbers</a></h2>
956 *
957 * <p> A <em>version number</em>, {@code $VNUM}, is a non-empty sequence
958 * of elements separated by period characters (U+002E). An element is
959 * either zero, or a unsigned integer numeral without leading zeros. The
960 * final element in a version number must not be zero. The format is:
961 * </p>
962 *
963 * <blockquote><pre>
964 * ^[1-9][0-9]*(((\.0)*\.[1-9][0-9]*)*)*$
965 * </pre></blockquote>
966 *
967 * <p> The sequence may be of arbitrary length but the first three
968 * elements are assigned specific meanings, as follows:</p>
969 *
970 * <blockquote><pre>
971 * $MAJOR.$MINOR.$SECURITY
972 * </pre></blockquote>
973 *
974 * <ul>
975 *
976 * <li><p> <a name="major">{@code $MAJOR}</a> --- The major version
977 * number, incremented for a major release that contains significant new
978 * features as specified in a new edition of the Java SE Platform
979 * Specification, <em>e.g.</em>, <a
980 * href="https://jcp.org/en/jsr/detail?id=337">JSR 337</a> for
981 * Java SE 8. Features may be removed in a major release, given
982 * advance notice at least one major release ahead of time, and
983 * incompatible changes may be made when justified. The {@code $MAJOR}
984 * version number of JDK 8 is {@code 8}; the {@code $MAJOR} version
985 * number of JDK 9 is {@code 9}. When {@code $MAJOR} is incremented,
986 * all subsequent elements are removed. </p></li>
987 *
988 * <li><p> <a name="minor">{@code $MINOR}</a> --- The minor version
989 * number, incremented for a minor update release that may contain
990 * compatible bug fixes, revisions to standard APIs mandated by a <a
991 * href="https://jcp.org/en/procedures/jcp2#5.3">Maintenance Release</a>
992 * of the relevant Platform Specification, and implementation features
993 * outside the scope of that Specification such as new JDK-specific APIs,
994 * additional service providers, new garbage collectors, and ports to new
995 * hardware architectures. </p></li>
996 *
997 * <li><p> <a name="security">{@code $SECURITY}</a> --- The security
998 * level, incremented for a security update release that contains critical
999 * fixes including those necessary to improve security. {@code $SECURITY}
1000 * is <strong>not</strong> reset when {@code $MINOR} is incremented. A
1001 * higher value of {@code $SECURITY} for a given {@code $MAJOR} value,
1002 * therefore, always indicates a more secure release, regardless of the
1003 * value of {@code $MINOR}. </p></li>
1004 *
1005 * </ul>
1006 *
1007 * <p> The fourth and later elements of a version number are free for use
1008 * by downstream consumers of this code base. Such a consumer may,
1009 * <em>e.g.</em>, use the fourth element to identify patch releases which
1010 * contain a small number of critical non-security fixes in addition to
1011 * the security fixes in the corresponding security release. </p>
1012 *
1013 * <p> The version number does not include trailing zero elements;
1014 * <em>i.e.</em>, {@code $SECURITY} is omitted if it has the value zero,
1015 * and {@code $MINOR} is omitted if both {@code $MINOR} and {@code
1016 * $SECURITY} have the value zero. </p>
1017 *
1018 * <p> The sequence of numerals in a version number is compared to another
1019 * such sequence in numerical, pointwise fashion; <em>e.g.</em>, {@code
1020 * 9.9.1} is less than {@code 9.10.3}. If one sequence is shorter than
1021 * another then the missing elements of the shorter sequence are
1022 * considered to be less than the corresponding elements of the longer
1023 * sequence; <em>e.g.</em>, {@code 9.1.2} is less than {@code 9.1.2.1}.
1024 * </p>
1025 *
1026 * <h2><a name="verStr">Version strings</a></h2>
1027 *
1028 * <p> A <em>version string</em>, {@code $VSTR}, consists of a version
1029 * number {@code $VNUM}, as described above, optionally followed by
1030 * pre-release and build information, in the format </p>
1031 *
1032 * <blockquote><pre>
1033 * $VNUM(-$PRE)?(\+($BUILD)?(-$OPT)?)?
1034 * </pre></blockquote>
1035 *
1036 * <p> where: </p>
1037 *
1038 * <ul>
1039 *
1040 * <li><p> <a name="pre">{@code $PRE}</a>, matching {@code ([a-zA-Z0-9]+)}
1041 * --- A pre-release identifier. Typically {@code ea}, for a
1042 * potentially unstable early-access release under active development,
1043 * or {@code internal}, for an internal developer build.
1044 *
1045 * <li><p> <a name="build">{@code $BUILD}</a>, matching {@code
1046 * (0|[1-9][0-9]*)} --- The build number, incremented for each promoted
1047 * build. {@code $BUILD} is reset to {@code 1} when any portion of {@code
1048 * $VNUM} is incremented. </p>
1049 *
1050 * <li><p> <a name="opt">{@code $OPT}</a>, matching {@code
1051 * ([-a-zA-Z0-9\.]+)} --- Additional build information, if desired. In
1052 * the case of an {@code internal} build this will often contain the date
1053 * and time of the build. </p>
1054 *
1055 * </ul>
1056 *
1057 * <p> A version number {@code 10-ea} matches {@code $VNUM = "10"} and
1058 * {@code $PRE = "ea"}. The version number {@code 10+-ea} matches
1059 * {@code $VNUM = "10"} and {@code $OPT = "ea"}. </p>
1060 *
1061 * <p> When comparing two version strings, the value of {@code $OPT}, if
1062 * present, may or may not be significant depending on the chosen
1063 * comparison method. The comparison methods {@link #compareTo(Version)
1064 * compareTo()} and {@link #compareToIgnoreOpt(Version)
1065 * compareToIgnoreOpt()} should be used consistently with the
1066 * corresponding methods {@link #equals(Object) equals()} and {@link
1067 * #equalsIgnoreOpt(Object) equalsIgnoreOpt()}. </p>
1068 *
1069 * <p> A <em>short version string</em>, {@code $SVSTR}, often useful in
1070 * less formal contexts, is a version number optionally followed by a
1071 * pre-release identifier:
1072 *
1073 * <blockquote><pre>
1074 * $VNUM(-$PRE)?
1075 * </pre></blockquote>
1076 *
1077 * @since 9
1078 */
1079 public static class Version
1080 implements Comparable<Version>
1081 {
1082 private final List<Integer> version;
1083 private final Optional<String> pre;
1084 private final Optional<Integer> build;
1085 private final Optional<String> optional;
1086
1087
1088 // $VNUM(-$PRE)?(\+($BUILD)?(\-$OPT)?)?
1089 // RE limits the format of version strings
1090 // ([1-9][0-9]*(?:(?:\.0)*\.[1-9][0-9]*)*)(?:-([a-zA-Z0-9]+))?(?:(\+)(0|[1-9][0-9]*)?)?(?:-([-a-zA-Z0-9.]+))?
1091
1092 private static final String VNUM
1093 = "(?<VNUM>[1-9][0-9]*(?:(?:\\.0)*\\.[1-9][0-9]*)*)";
1094 private static final String VNUM_GROUP = "VNUM";
1095
1096 private static final String PRE = "(?:-(?<PRE>[a-zA-Z0-9]+))?";
1097 private static final String PRE_GROUP = "PRE";
1098
1099 private static final String BUILD
1100 = "(?:(?<PLUS>\\+)(?<BUILD>0|[1-9][0-9]*)?)?";
1101 private static final String PLUS_GROUP = "PLUS";
1102 private static final String BUILD_GROUP = "BUILD";
1103
1104 private static final String OPT = "(?:-(?<OPT>[-a-zA-Z0-9.]+))?";
1105 private static final String OPT_GROUP = "OPT";
1106
1107 private static final String VSTR_FORMAT
1108 = "^" + VNUM + PRE + BUILD + OPT + "$";
1109 private static final Pattern VSTR_PATTERN = Pattern.compile(VSTR_FORMAT);
1110
1111 /**
1112 * Constructs a valid <a href="verStr">version string</a> containing
1113 * a <a href="#verNum">version number</a> followed by pre-release and
1114 * build information.
1115 *
1116 * @param s
1117 * A string to be interpreted as a version
1118 *
1119 * @throws IllegalArgumentException
1120 * If the given string cannot be interpreted as a valid
1121 * version
1122 *
1123 * @throws NullPointerException
1124 * If {@code s} is {@code null}
1125 *
1126 * @throws NumberFormatException
1127 * If an element of the version number or the build number
1128 * cannot be represented as an {@link Integer}
1129 */
1130 private Version(String s) {
1131 if (s == null)
1132 throw new NullPointerException();
1133
1134 Matcher m = VSTR_PATTERN.matcher(s);
1135 if (!m.matches())
1136 throw new IllegalArgumentException("Invalid version string: '"
1137 + s + "'");
1138
1139 // $VNUM is a dot-separated list of integers of arbitrary length
1140 List<Integer> list = new ArrayList<>();
1141 for (String i : m.group(VNUM_GROUP).split("\\."))
1142 list.add(Integer.parseInt(i));
1143 version = Collections.unmodifiableList(list);
1144
1145 pre = Optional.ofNullable(m.group(PRE_GROUP));
1146
1147 String b = m.group(BUILD_GROUP);
1148 // $BUILD is an integer
1149 build = (b == null)
1150 ? Optional.<Integer>empty()
1151 : Optional.ofNullable(Integer.parseInt(b));
1152
1153 optional = Optional.ofNullable(m.group(OPT_GROUP));
1154
1155 // empty '+'
1156 if ((m.group(PLUS_GROUP) != null) && !build.isPresent()) {
1157 if (optional.isPresent()) {
1158 if (pre.isPresent())
1159 throw new IllegalArgumentException("'+' found with"
1160 + " pre-release and optional components:'" + s
1161 + "'");
1162 } else {
1163 throw new IllegalArgumentException("'+' found with neither"
1164 + " build or optional components: '" + s + "'");
1165 }
1166 }
1167 }
1168
1169 /**
1170 * Parses the given string as a valid <a
1171 * href="#verStr">version string</a> containing a <a
1172 * href="#verNum">version number</a> followed by pre-release and
1173 * build information.
1174 *
1175 * @param s
1176 * A string to interpret as a version
1177 *
1178 * @throws IllegalArgumentException
1179 * If the given string cannot be interpreted as a valid
1180 * version
1181 *
1182 * @throws NullPointerException
1183 * If the given string is {@code null}
1184 *
1185 * @throws NumberFormatException
1186 * If an element of the version number or the build number
1187 * cannot be represented as an {@link Integer}
1188 *
1189 * @return This version
1190 */
1191 public static Version parse(String s) {
1192 return new Version(s);
1193 }
1194
1195 /**
1196 * Returns the <a href="#major">major</a> version number.
1197 *
1198 * @return The major version number
1199 */
1200 public int major() {
1201 return version.get(0);
1202 }
1203
1204 /**
1205 * Returns the <a href="#minor">minor</a> version number or zero if it
1206 * was not set.
1207 *
1208 * @return The minor version number or zero if it was not set
1209 */
1210 public int minor() {
1211 return (version.size() > 1 ? version.get(1) : 0);
1212 }
1213
1214 /**
1215 * Returns the <a href="#security">security</a> version number or zero
1216 * if it was not set.
1217 *
1218 * @return The security version number or zero if it was not set
1219 */
1220 public int security() {
1221 return (version.size() > 2 ? version.get(2) : 0);
1222 }
1223
1224 /**
1225 * Returns an unmodifiable {@link java.util.List List} of the
1226 * integer numerals contained in the <a href="#verNum">version
1227 * number</a>. The {@code List} always contains at least one
1228 * element corresponding to the <a href="#major">major version
1229 * number</a>.
1230 *
1231 * @return An unmodifiable list of the integer numerals
1232 * contained in the version number
1233 */
1234 public List<Integer> version() {
1235 return version;
1236 }
1237
1238 /**
1239 * Returns the optional <a href="#pre">pre-release</a> information.
1240 *
1241 * @return The optional pre-release information as a String
1242 */
1243 public Optional<String> pre() {
1244 return pre;
1245 }
1246
1247 /**
1248 * Returns the <a href="#build">build number</a>.
1249 *
1250 * @return The optional build number.
1251 */
1252 public Optional<Integer> build() {
1253 return build;
1254 }
1255
1256 /**
1257 * Returns <a href="#opt">optional</a> additional identifying build
1258 * information.
1259 *
1260 * @return Additional build information as a String
1261 */
1262 public Optional<String> optional() {
1263 return optional;
1264 }
1265
1266 /**
1267 * Compares this version to another.
1268 *
1269 * <p> Each of the components in the <a href="#verStr">version</a> is
1270 * compared in the follow order of precedence: version numbers,
1271 * pre-release identifiers, build numbers, optional build information.
1272 * </p>
1273 *
1274 * <p> Comparison begins by examining the sequence of version numbers.
1275 * If one sequence is shorter than another, then the missing elements
1276 * of the shorter sequence are considered to be less than the
1277 * corresponding elements of the longer sequence. </p>
1278 *
1279 * <p> A version with a pre-release identifier is always considered to
1280 * be less than a version without one. Pre-release identifiers are
1281 * compared numerically when they consist only of digits, and
1282 * lexicographically otherwise. Numeric identifiers are considered to
1283 * be less than non-numeric identifiers. </p>
1284 *
1285 * <p> A version without a build number is always less than one with a
1286 * build number; otherwise build numbers are compared numerically. </p>
1287 *
1288 * <p> The optional build information is compared lexicographically.
1289 * During this comparison, a version with optional build information is
1290 * considered to be greater than a version without one. </p>
1291 *
1292 * <p> A version is not comparable to any other type of object.
1293 *
1294 * @param ob
1295 * The object to be compared
1296 *
1297 * @return A negative integer, zero, or a positive integer if this
1298 * {@code Version} is less than, equal to, or greater than the
1299 * given {@code Version}
1300 *
1301 * @throws NullPointerException
1302 * If the given object is {@code null}
1303 */
1304 @Override
1305 public int compareTo(Version ob) {
1306 return compare(ob, false);
1307 }
1308
1309 /**
1310 * Compares this version to another disregarding optional build
1311 * information.
1312 *
1313 * <p> Two versions are compared by examining the version string as
1314 * described in {@link #compareTo(Version)} with the exception that the
1315 * optional build information is always ignored. </p>
1316 *
1317 * <p> A version is not comparable to any other type of object.
1318 *
1319 * @param ob
1320 * The object to be compared
1321 *
1322 * @return A negative integer, zero, or a positive integer if this
1323 * {@code Version} is less than, equal to, or greater than the
1324 * given {@code Version}
1325 *
1326 * @throws NullPointerException
1327 * If the given object is {@code null}
1328 */
1329 public int compareToIgnoreOpt(Version ob) {
1330 return compare(ob, true);
1331 }
1332
1333 private int compare(Version ob, boolean ignoreOpt) {
1334 if (ob == null)
1335 throw new NullPointerException("Invalid argument");
1336
1337 int ret = compareVersion(ob);
1338 if (ret != 0)
1339 return ret;
1340
1341 ret = comparePre(ob);
1342 if (ret != 0)
1343 return ret;
1344
1345 ret = compareBuild(ob);
1346 if (ret != 0)
1347 return ret;
1348
1349 if (!ignoreOpt)
1350 return compareOpt(ob);
1351
1352 return 0;
1353 }
1354
1355 private int compareVersion(Version ob) {
1356 int size = version.size();
1357 int oSize = ob.version().size();
1358 int min = Math.min(size, oSize);
1359 for (int i = 0; i < min; i++) {
1360 Integer val = version.get(i);
1361 Integer oVal = ob.version().get(i);
1362 if (val != oVal)
1363 return val - oVal;
1364 }
1365 if (size != oSize)
1366 return size - oSize;
1367 return 0;
1368 }
1369
1370 private int comparePre(Version ob) {
1371 Optional<String> oPre = ob.pre();
1372 if (!pre.isPresent()) {
1373 if (oPre.isPresent())
1374 return 1;
1375 } else {
1376 if (!oPre.isPresent())
1377 return -1;
1378 String val = pre.get();
1379 String oVal = oPre.get();
1380 if (val.matches("\\d+")) {
1381 return (oVal.matches("\\d+")
1382 ? (new BigInteger(val)).compareTo(new BigInteger(oVal))
1383 : -1);
1384 } else {
1385 return (oVal.matches("\\d+")
1386 ? 1
1387 : val.compareTo(oVal));
1388 }
1389 }
1390 return 0;
1391 }
1392
1393 private int compareBuild(Version ob) {
1394 Optional<Integer> oBuild = ob.build();
1395 if (oBuild.isPresent()) {
1396 return (build.isPresent()
1397 ? build.get().compareTo(oBuild.get())
1398 : 1);
1399 } else if (build.isPresent()) {
1400 return -1;
1401 }
1402 return 0;
1403 }
1404
1405 private int compareOpt(Version ob) {
1406 Optional<String> oOpt = ob.optional();
1407 if (!optional.isPresent()) {
1408 if (oOpt.isPresent())
1409 return -1;
1410 } else {
1411 if (!oOpt.isPresent())
1412 return 1;
1413 return optional.get().compareTo(oOpt.get());
1414 }
1415 return 0;
1416 }
1417
1418 /**
1419 * Returns a string representation of this version.
1420 *
1421 * @return The version string
1422 */
1423 @Override
1424 public String toString() {
1425 StringBuilder sb
1426 = new StringBuilder(version.stream()
1427 .map(Object::toString)
1428 .collect(Collectors.joining(".")));
1429
1430 pre.ifPresent(v -> sb.append("-").append(v));
1431
1432 if (build.isPresent()) {
1433 sb.append("+").append(build.get());
1434 if (optional.isPresent())
1435 sb.append("-").append(optional.get());
1436 } else {
1437 if (optional.isPresent()) {
1438 sb.append(pre.isPresent() ? "-" : "+-");
1439 sb.append(optional.get());
1440 }
1441 }
1442
1443 return sb.toString();
1444 }
1445
1446 /**
1447 * Determines whether this {@code Version} is equal to another object.
1448 *
1449 * <p> Two {@code Version}s are equal if and only if they represent the
1450 * same version string.
1451 *
1452 * <p> This method satisfies the general contract of the {@link
1453 * Object#equals(Object) Object.equals} method. </p>
1454 *
1455 * @param ob
1456 * The object to which this {@code Version} is to be compared
1457 *
1458 * @return {@code true} if, and only if, the given object is a {@code
1459 * Version} that is identical to this {@code Version}
1460 *
1461 */
1462 @Override
1463 public boolean equals(Object ob) {
1464 boolean ret = equalsIgnoreOpt(ob);
1465 if (!ret)
1466 return false;
1467
1468 Version that = (Version)ob;
1469 return (this.optional().equals(that.optional()));
1470 }
1471
1472 /**
1473 * Determines whether this {@code Version} is equal to another
1474 * disregarding optional build information.
1475 *
1476 * <p> Two {@code Version}s are equal if and only if they represent the
1477 * same version string disregarding the optional build information.
1478 *
1479 * @param ob
1480 * The object to which this {@code Version} is to be compared
1481 *
1482 * @return {@code true} if, and only if, the given object is a {@code
1483 * Version} that is identical to this {@code Version}
1484 * ignoring the optinal build information
1485 *
1486 */
1487 public boolean equalsIgnoreOpt(Object ob) {
1488 if (this == ob)
1489 return true;
1490 if (!(ob instanceof Version))
1491 return false;
1492
1493 Version that = (Version)ob;
1494 return (this.version().equals(that.version())
1495 && this.pre().equals(that.pre())
1496 && this.build().equals(that.build()));
1497 }
1498
1499 /**
1500 * Returns the hash code of this version.
1501 *
1502 * <p> This method satisfies the general contract of the {@link
1503 * Object#hashCode Object.hashCode} method.
1504 *
1505 * @return The hashcode of this version
1506 */
1507 @Override
1508 public int hashCode() {
1509 int h = 1;
1510 int p = 17;
1511
1512 h = p * h + version.hashCode();
1513 h = p * h + pre.hashCode();
1514 h = p * h + build.hashCode();
1515 h = p * h + optional.hashCode();
1516
1517 return h;
1518 }
1519 }
1520
1521 }
|