< prev index next >

jdk/src/java.base/share/classes/java/lang/Runtime.java

Print this page


   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&nbsp;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&nbsp;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 }
< prev index next >