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