--- old/jdk/src/java.base/share/classes/jdk/Version.java Wed Feb 24 15:06:11 2016 +++ /dev/null Wed Feb 24 15:06:11 2016 @@ -1,609 +0,0 @@ -/* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk; - -import java.math.BigInteger; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -/** - * A representation of the JDK version-string which contains a version - * number optionally followed by pre-release and build information. - * - *

Version numbers

- * - * A version number, {@code $VNUM}, is a non-empty sequence of - * non-negative integer numerals, without leading or trailing zeroes, - * separated by period characters (U+002E); i.e., it matches the regular - * expression {@code ^[1-9][0-9]*(((\.0)*\.[1-9][0-9]*)*)*$}. The sequence may - * be of arbitrary length but the first three elements are assigned specific - * meanings, as follows: - * - *
- *     $MAJOR.$MINOR.$SECURITY
- * 
- * - * - * - *

The fourth and later elements of a version number are free for use by - * downstream consumers of the JDK code base. Such a consumer may, - * e.g., use the fourth element to identify patch releases which - * contain a small number of critical non-security fixes in addition to the - * security fixes in the corresponding security release.

- * - *

The version number does not include trailing zero elements; - * i.e., {@code $SECURITY} is omitted if it has the value zero, and - * {@code $MINOR} is omitted if both {@code $MINOR} and {@code $SECURITY} have - * the value zero.

- * - *

The sequence of numerals in a version number is compared to another - * such sequence in numerical, pointwise fashion; e.g., {@code 9.9.1} - * is less than {@code 9.10.0}. If one sequence is shorter than another then - * the missing elements of the shorter sequence are considered to be zero; - * e.g., {@code 9.1.2} is equal to {@code 9.1.2.0} but less than - * {@code 9.1.2.1}.

- * - *

Version strings

- * - *

A version string {@code $VSTR} consists of a version number - * {@code $VNUM}, as described above, optionally followed by pre-release and - * build information, in the format

- * - *
- *     $VNUM(-$PRE)?(\+($BUILD)?(-$OPT)?)?
- * 
- * - *

where:

- * - * - * - *

When comparing two version strings the value of {@code $OPT}, if - * present, may or may not be significant depending on the chosen comparison - * method. The comparison methods {@link #compareTo(Version) compareTo()} and - * {@link #compareToIgnoreOpt(Version) compareToIgnoreOpt{}} should be used - * consistently with the corresponding methods {@link #equals(Object) equals()} - * and {@link #equalsIgnoreOpt(Object) equalsIgnoreOpt()}.

- * - *

A short version string ({@code $SVSTR}), often useful in less - * formal contexts, is simply {@code $VNUM} optionally ended with {@code - * -$PRE}.

- * - * @since 9 - */ -public final class Version - implements Comparable -{ - private final List version; - private final Optional pre; - private final Optional build; - private final Optional optional; - - private static Version current; - - // $VNUM(-$PRE)?(\+($BUILD)?(\-$OPT)?)? - // RE limits the format of version strings - // ([1-9][0-9]*(?:(?:\.0)*\.[1-9][0-9]*)*)(?:-([a-zA-Z0-9]+))?(?:(\+)(0|[1-9][0-9]*)?)?(?:-([-a-zA-Z0-9.]+))? - - private static final String VNUM - = "(?[1-9][0-9]*(?:(?:\\.0)*\\.[1-9][0-9]*)*)"; - private static final String VNUM_GROUP = "VNUM"; - - private static final String PRE = "(?:-(?
[a-zA-Z0-9]+))?";
-    private static final String PRE_GROUP   = "PRE";
-
-    private static final String BUILD
-        = "(?:(?\\+)(?0|[1-9][0-9]*)?)?";
-    private static final String PLUS_GROUP  = "PLUS";
-    private static final String BUILD_GROUP = "BUILD";
-
-    private static final String OPT      = "(?:-(?[-a-zA-Z0-9.]+))?";
-    private static final String OPT_GROUP   = "OPT";
-
-    private static final String VSTR_FORMAT
-        = "^" + VNUM + PRE + BUILD + OPT + "$";
-    private static final Pattern VSTR_PATTERN = Pattern.compile(VSTR_FORMAT);
-
-    /**
-     * Constructs a valid JDK version string containing a
-     * version number followed by pre-release and build
-     * information.
-     *
-     * @param  s
-     *         A string to be interpreted as a version
-     *
-     * @throws  IllegalArgumentException
-     *          If the given string cannot be interpreted a valid version
-     *
-     * @throws  NullPointerException
-     *          If {@code s} is {@code null}
-     *
-     * @throws  NumberFormatException
-     *          If an element of the version number or the build number cannot
-     *          be represented as an {@link Integer}
-     */
-    private Version(String s) {
-        if (s == null)
-            throw new NullPointerException();
-
-        Matcher m = VSTR_PATTERN.matcher(s);
-        if (!m.matches())
-            throw new IllegalArgumentException("Invalid version string: '"
-                                               + s + "'");
-
-        // $VNUM is a dot-separated list of integers of arbitrary length
-        version
-            = Collections.unmodifiableList(
-                  Arrays.stream(m.group(VNUM_GROUP).split("\\."))
-                  .map(Integer::parseInt)
-                  .collect(Collectors.toList()));
-
-        pre = Optional.ofNullable(m.group(PRE_GROUP));
-
-        String b = m.group(BUILD_GROUP);
-        // $BUILD is an integer
-        build = (b == null)
-             ? Optional.empty()
-             : Optional.ofNullable(Integer.parseInt(b));
-
-        optional = Optional.ofNullable(m.group(OPT_GROUP));
-
-        // empty '+'
-        if ((m.group(PLUS_GROUP) != null) && !build.isPresent()) {
-            if (optional.isPresent()) {
-                if (pre.isPresent())
-                    throw new IllegalArgumentException("'+' found with"
-                        + " pre-release and optional components:'" + s + "'");
-            } else {
-                throw new IllegalArgumentException("'+' found with neither"
-                    + " build or optional components: '" + s + "'");
-            }
-        }
-    }
-
-    /**
-     * Parses the given string as a valid JDK version string containing a version number followed by pre-release and
-     * build information.
-     *
-     * @param  s
-     *         A string to interpret as a version
-     *
-     * @throws  IllegalArgumentException
-     *          If the given string cannot be interpreted a valid version
-     *
-     * @throws  NullPointerException
-     *          If the given string is {@code null}
-     *
-     * @throws  NumberFormatException
-     *          If an element of the version number or the build number cannot
-     *          be represented as an {@link Integer}
-     *
-     * @return  This version
-     */
-    public static Version parse(String s) {
-        return new Version(s);
-    }
-
-    /**
-     * Returns {@code System.getProperty("java.version")} as a Version.
-     *
-     * @throws  SecurityException
-     *          If a security manager exists and its {@link
-     *          SecurityManager#checkPropertyAccess(String)
-     *          checkPropertyAccess} method does not allow access to the
-     *          system property "java.version"
-     *
-     * @return  {@code System.getProperty("java.version")} as a Version
-     */
-    public static Version current() {
-        if (current == null) {
-            current = parse(AccessController.doPrivileged(
-                new PrivilegedAction<>() {
-                    public String run() {
-                        return System.getProperty("java.version");
-                    }
-                }));
-        }
-        return current;
-    }
-
-    /**
-     * Returns the major version number.
-     *
-     * @return  The major version number
-     */
-    public int major() {
-        return version.get(0);
-    }
-
-    /**
-     * Returns the minor version number or zero if it was
-     * not set.
-     *
-     * @return  The minor version number or zero if it was not set
-     */
-    public int minor() {
-        return (version.size() > 1 ? version.get(1) : 0);
-    }
-
-    /**
-     * Returns the security version number or zero if
-     * it was not set.
-     *
-     * @return  The security version number or zero if it was not set
-     */
-    public int security() {
-        return (version.size() > 2 ? version.get(2) : 0);
-    }
-
-    /**
-     * Returns an unmodifiable {@link java.util.List List} of the
-     * integer numerals contained in the version
-     * number.  The {@code List} always contains at least one
-     * element corresponding to the major version
-     * number.
-     *
-     * @return  An unmodifiable list of the integer numerals
-     *          contained in the version number
-     */
-    public List version() {
-        return version;
-    }
-
-    /**
-     * Returns the optional pre-release information.
-     *
-     * @return  The optional pre-release information as a String
-     */
-    public Optional pre() {
-        return pre;
-    }
-
-    /**
-     * Returns the build number.
-     *
-     * @return The optional build number.
-     */
-    public Optional build() {
-        return build;
-    }
-
-    /**
-     * Returns optional additional identifying build
-     * information.
-     *
-     * @return  Additional build information as a String
-     */
-    public Optional optional() {
-        return optional;
-    }
-
-    /**
-     * Compares this version to another.
-     *
-     * 

Each of the components in the version is - * compared in the follow order of precedence: version numbers, - * pre-release identifiers, build numbers, optional build information.

- * - *

Comparison begins by examining the sequence of version numbers. If - * one sequence is shorter than another, then the missing elements of the - * shorter sequence are considered to be zero.

- * - *

A version with a pre-release identifier is always considered to be - * less than a version without one. Pre-release identifiers are compared - * numerically when they consist only of digits, and lexicographically - * otherwise. Numeric identifiers are considered to be less than - * non-numeric identifiers.

- * - *

A version without a build number is always less than one with a - * build number; otherwise build numbers are compared numerically.

- * - *

The optional build information is compared lexicographically. - * During this comparison, a version with optional build information is - * considered to be greater than a version without one.

- * - *

A version is not comparable to any other type of object. - * - * @param ob - * The object to be compared - * - * @return A negative integer, zero, or a positive integer if this - * {@code Version} is less than, equal to, or greater than the - * given {@code Version} - * - * @throws NullPointerException - * If the given object is {@code null} - */ - @Override - public int compareTo(Version ob) { - return compare(ob, false); - } - - /** - * Compares this version to another disregarding optional build - * information. - * - *

Two versions are compared by examining the version string as - * described in {@link #compareTo(Version)} with the exception that the - * optional build information is always ignored.

- * - *

A version is not comparable to any other type of object. - * - * @param ob - * The object to be compared - * - * @return A negative integer, zero, or a positive integer if this - * {@code Version} is less than, equal to, or greater than the - * given {@code Version} - * - * @throws NullPointerException - * If the given object is {@code null} - */ - public int compareToIgnoreOpt(Version ob) { - return compare(ob, true); - } - - private int compare(Version ob, boolean ignoreOpt) { - if (ob == null) - throw new NullPointerException("Invalid argument"); - - int ret = compareVersion(ob); - if (ret != 0) - return ret; - - ret = comparePre(ob); - if (ret != 0) - return ret; - - ret = compareBuild(ob); - if (ret != 0) - return ret; - - if (!ignoreOpt) - return compareOpt(ob); - - return 0; - } - - private int compareVersion(Version ob) { - int size = version.size(); - int oSize = ob.version().size(); - int min = Math.min(size, oSize); - for (int i = 0; i < min; i++) { - Integer val = version.get(i); - Integer oVal = ob.version().get(i); - if (val != oVal) - return val - oVal; - } - if (size != oSize) - return size - oSize; - return 0; - } - - private int comparePre(Version ob) { - Optional oPre = ob.pre(); - if (!pre.isPresent()) { - if (oPre.isPresent()) - return 1; - } else { - if (!oPre.isPresent()) - return -1; - String val = pre.get(); - String oVal = oPre.get(); - if (val.matches("\\d+")) { - return (oVal.matches("\\d+") - ? (new BigInteger(val)).compareTo(new BigInteger(oVal)) - : -1); - } else { - return (oVal.matches("\\d+") - ? 1 - : val.compareTo(oVal)); - } - } - return 0; - } - - private int compareBuild(Version ob) { - Optional oBuild = ob.build(); - if (oBuild.isPresent()) { - return (build.isPresent() - ? build.get().compareTo(oBuild.get()) - : 1); - } else if (build.isPresent()) { - return -1; - } - return 0; - } - - private int compareOpt(Version ob) { - Optional oOpt = ob.optional(); - if (!optional.isPresent()) { - if (oOpt.isPresent()) - return -1; - } else { - if (!oOpt.isPresent()) - return 1; - return optional.get().compareTo(oOpt.get()); - } - return 0; - } - - /** - * Returns a string representation of this version. - * - * @return The version string - */ - @Override - public String toString() { - StringBuilder sb - = new StringBuilder(version.stream() - .map(Object::toString) - .collect(Collectors.joining("."))); - pre.ifPresent(v -> sb.append("-").append(v)); - - if (build.isPresent()) { - sb.append("+").append(build.get()); - if (optional.isPresent()) - sb.append("-").append(optional.get()); - } else { - if (optional.isPresent()) { - sb.append(pre.isPresent() ? "-" : "+-"); - sb.append(optional.get()); - } - } - - return sb.toString(); - } - - /** - * Determines whether this {@code Version} is equal to another object. - * - *

Two {@code Version}s are equal if and only if they represent the - * same version string. - * - *

This method satisfies the general contract of the {@link - * Object#equals(Object) Object.equals} method.

- * - * @param ob - * The object to which this {@code Version} is to be compared - * - * @return {@code true} if, and only if, the given object is a {@code - * Version} that is identical to this {@code Version} - * - */ - @Override - public boolean equals(Object ob) { - boolean ret = equalsIgnoreOpt(ob); - if (!ret) - return false; - - Version that = (Version)ob; - return (this.optional().equals(that.optional())); - } - - /** - * Determines whether this {@code Version} is equal to another - * disregarding optional build information. - * - *

Two {@code Version}s are equal if and only if they represent the - * same version string disregarding the optional build information. - * - * @param ob - * The object to which this {@code Version} is to be compared - * - * @return {@code true} if, and only if, the given object is a {@code - * Version} that is identical to this {@code Version} - * ignoring the optinal build information - * - */ - public boolean equalsIgnoreOpt(Object ob) { - if (this == ob) - return true; - if (!(ob instanceof Version)) - return false; - - Version that = (Version)ob; - return (this.version().equals(that.version()) - && this.pre().equals(that.pre()) - && this.build().equals(that.build())); - } - - /** - * Returns the hash code of this version. - * - *

This method satisfies the general contract of the {@link - * Object#hashCode Object.hashCode} method. - * - * @return The hashcode of this version - */ - @Override - public int hashCode() { - int h = 1; - int p = 17; - - h = p * h + version.hashCode(); - h = p * h + pre.hashCode(); - h = p * h + build.hashCode(); - h = p * h + optional.hashCode(); - - return h; - } -}