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