| /* |
| ******************************************************************************* |
| * Copyright (C) 1996-2010, International Business Machines Corporation and * |
| * others. All Rights Reserved. * |
| ******************************************************************************* |
| */ |
| |
| package com.ibm.icu.util; |
| |
| import java.util.HashMap; |
| |
| /** |
| * Class to store version numbers of the form major.minor.milli.micro. |
| * @author synwee |
| * @stable ICU 2.6 |
| */ |
| public final class VersionInfo implements Comparable<VersionInfo> |
| { |
| // public data members ------------------------------------------------- |
| |
| /** |
| * Unicode 1.0 version |
| * @stable ICU 2.6 |
| */ |
| public static final VersionInfo UNICODE_1_0; |
| /** |
| * Unicode 1.0.1 version |
| * @stable ICU 2.6 |
| */ |
| public static final VersionInfo UNICODE_1_0_1; |
| /** |
| * Unicode 1.1.0 version |
| * @stable ICU 2.6 |
| */ |
| public static final VersionInfo UNICODE_1_1_0; |
| /** |
| * Unicode 1.1.5 version |
| * @stable ICU 2.6 |
| */ |
| public static final VersionInfo UNICODE_1_1_5; |
| /** |
| * Unicode 2.0 version |
| * @stable ICU 2.6 |
| */ |
| public static final VersionInfo UNICODE_2_0; |
| /** |
| * Unicode 2.1.2 version |
| * @stable ICU 2.6 |
| */ |
| public static final VersionInfo UNICODE_2_1_2; |
| /** |
| * Unicode 2.1.5 version |
| * @stable ICU 2.6 |
| */ |
| public static final VersionInfo UNICODE_2_1_5; |
| /** |
| * Unicode 2.1.8 version |
| * @stable ICU 2.6 |
| */ |
| public static final VersionInfo UNICODE_2_1_8; |
| /** |
| * Unicode 2.1.9 version |
| * @stable ICU 2.6 |
| */ |
| public static final VersionInfo UNICODE_2_1_9; |
| /** |
| * Unicode 3.0 version |
| * @stable ICU 2.6 |
| */ |
| public static final VersionInfo UNICODE_3_0; |
| /** |
| * Unicode 3.0.1 version |
| * @stable ICU 2.6 |
| */ |
| public static final VersionInfo UNICODE_3_0_1; |
| /** |
| * Unicode 3.1.0 version |
| * @stable ICU 2.6 |
| */ |
| public static final VersionInfo UNICODE_3_1_0; |
| /** |
| * Unicode 3.1.1 version |
| * @stable ICU 2.6 |
| */ |
| public static final VersionInfo UNICODE_3_1_1; |
| /** |
| * Unicode 3.2 version |
| * @stable ICU 2.6 |
| */ |
| public static final VersionInfo UNICODE_3_2; |
| |
| /** |
| * Unicode 4.0 version |
| * @stable ICU 2.6 |
| */ |
| public static final VersionInfo UNICODE_4_0; |
| |
| /** |
| * Unicode 4.0.1 version |
| * @stable ICU 3.4 |
| */ |
| public static final VersionInfo UNICODE_4_0_1; |
| |
| /** |
| * Unicode 4.1 version |
| * @stable ICU 3.4 |
| */ |
| public static final VersionInfo UNICODE_4_1; |
| |
| /** |
| * Unicode 5.0 version |
| * @stable ICU 3.4 |
| */ |
| public static final VersionInfo UNICODE_5_0; |
| |
| /** |
| * Unicode 5.1 version |
| * @stable ICU 4.2 |
| */ |
| public static final VersionInfo UNICODE_5_1; |
| |
| /** |
| * Unicode 5.2 version |
| * @stable ICU 4.4 |
| */ |
| public static final VersionInfo UNICODE_5_2; |
| |
| /** |
| * ICU4J current release version |
| * @stable ICU 2.8 |
| */ |
| public static final VersionInfo ICU_VERSION; |
| |
| /** |
| * Data version string for ICU's internal data. |
| * Used for appending to data path (e.g. icudt43b) |
| * @internal |
| * @deprecated This API is ICU internal only. |
| */ |
| public static final String ICU_DATA_VERSION_PATH = "45b"; |
| |
| /** |
| * Data version in ICU4J. |
| * @internal |
| * @deprecated This API is ICU internal only. |
| */ |
| public static final VersionInfo ICU_DATA_VERSION; |
| |
| /** |
| * ICU4J collator runtime version |
| * @stable ICU 2.8 |
| */ |
| public static final VersionInfo UCOL_RUNTIME_VERSION; |
| |
| /** |
| * ICU4J collator builder version |
| * @stable ICU 2.8 |
| */ |
| public static final VersionInfo UCOL_BUILDER_VERSION; |
| |
| /** |
| * ICU4J collator tailorings version |
| * @stable ICU 2.8 |
| */ |
| public static final VersionInfo UCOL_TAILORINGS_VERSION; |
| |
| |
| // public methods ------------------------------------------------------ |
| |
| /** |
| * Returns an instance of VersionInfo with the argument version. |
| * @param version version String in the format of "major.minor.milli.micro" |
| * or "major.minor.milli" or "major.minor" or "major", |
| * where major, minor, milli, micro are non-negative numbers |
| * <= 255. If the trailing version numbers are |
| * not specified they are taken as 0s. E.g. Version "3.1" is |
| * equivalent to "3.1.0.0". |
| * @return an instance of VersionInfo with the argument version. |
| * @exception IllegalArgumentException when the argument version |
| * is not in the right format |
| * @stable ICU 2.6 |
| */ |
| public static VersionInfo getInstance(String version) |
| { |
| int length = version.length(); |
| int array[] = {0, 0, 0, 0}; |
| int count = 0; |
| int index = 0; |
| |
| while (count < 4 && index < length) { |
| char c = version.charAt(index); |
| if (c == '.') { |
| count ++; |
| } |
| else { |
| c -= '0'; |
| if (c < 0 || c > 9) { |
| throw new IllegalArgumentException(INVALID_VERSION_NUMBER_); |
| } |
| array[count] *= 10; |
| array[count] += c; |
| } |
| index ++; |
| } |
| if (index != length) { |
| throw new IllegalArgumentException( |
| "Invalid version number: String '" + version + "' exceeds version format"); |
| } |
| for (int i = 0; i < 4; i ++) { |
| if (array[i] < 0 || array[i] > 255) { |
| throw new IllegalArgumentException(INVALID_VERSION_NUMBER_); |
| } |
| } |
| |
| return getInstance(array[0], array[1], array[2], array[3]); |
| } |
| |
| /** |
| * Returns an instance of VersionInfo with the argument version. |
| * @param major major version, non-negative number <= 255. |
| * @param minor minor version, non-negative number <= 255. |
| * @param milli milli version, non-negative number <= 255. |
| * @param micro micro version, non-negative number <= 255. |
| * @exception IllegalArgumentException when either arguments are negative or > 255 |
| * @stable ICU 2.6 |
| */ |
| public static VersionInfo getInstance(int major, int minor, int milli, |
| int micro) |
| { |
| // checks if it is in the hashmap |
| // else |
| if (major < 0 || major > 255 || minor < 0 || minor > 255 || |
| milli < 0 || milli > 255 || micro < 0 || micro > 255) { |
| throw new IllegalArgumentException(INVALID_VERSION_NUMBER_); |
| } |
| int version = getInt(major, minor, milli, micro); |
| Integer key = new Integer(version); |
| VersionInfo result = MAP_.get(key); |
| if (result == null) { |
| result = new VersionInfo(version); |
| MAP_.put(key, result); |
| } |
| return result; |
| } |
| |
| /** |
| * Returns an instance of VersionInfo with the argument version. |
| * Equivalent to getInstance(major, minor, milli, 0). |
| * @param major major version, non-negative number <= 255. |
| * @param minor minor version, non-negative number <= 255. |
| * @param milli milli version, non-negative number <= 255. |
| * @exception IllegalArgumentException when either arguments are |
| * negative or > 255 |
| * @stable ICU 2.6 |
| */ |
| public static VersionInfo getInstance(int major, int minor, int milli) |
| { |
| return getInstance(major, minor, milli, 0); |
| } |
| |
| /** |
| * Returns an instance of VersionInfo with the argument version. |
| * Equivalent to getInstance(major, minor, 0, 0). |
| * @param major major version, non-negative number <= 255. |
| * @param minor minor version, non-negative number <= 255. |
| * @exception IllegalArgumentException when either arguments are |
| * negative or > 255 |
| * @stable ICU 2.6 |
| */ |
| public static VersionInfo getInstance(int major, int minor) |
| { |
| return getInstance(major, minor, 0, 0); |
| } |
| |
| /** |
| * Returns an instance of VersionInfo with the argument version. |
| * Equivalent to getInstance(major, 0, 0, 0). |
| * @param major major version, non-negative number <= 255. |
| * @exception IllegalArgumentException when either arguments are |
| * negative or > 255 |
| * @stable ICU 2.6 |
| */ |
| public static VersionInfo getInstance(int major) |
| { |
| return getInstance(major, 0, 0, 0); |
| } |
| |
| private static VersionInfo javaVersion; |
| |
| /** |
| * @internal |
| * @deprecated This API is ICU internal only. |
| */ |
| public static VersionInfo javaVersion() { |
| if (javaVersion == null) { |
| String s = System.getProperty("java.version"); |
| // clean string |
| // preserve only digits, separated by single '.' |
| // ignore over 4 digit sequences |
| // does not test < 255, very odd... |
| |
| char[] chars = s.toCharArray(); |
| int r = 0, w = 0, count = 0; |
| boolean numeric = false; // ignore leading non-numerics |
| while (r < chars.length) { |
| char c = chars[r++]; |
| if (c < '0' || c > '9') { |
| if (numeric) { |
| if (count == 3) { |
| // only four digit strings allowed |
| break; |
| } |
| numeric = false; |
| chars[w++] = '.'; |
| ++count; |
| } |
| } else { |
| numeric = true; |
| chars[w++] = c; |
| } |
| } |
| while (w > 0 && chars[w-1] == '.') { |
| --w; |
| } |
| |
| String vs = new String(chars, 0, w); |
| |
| javaVersion = VersionInfo.getInstance(vs); |
| } |
| return javaVersion; |
| } |
| |
| /** |
| * Returns the String representative of VersionInfo in the format of |
| * "major.minor.milli.micro" |
| * @return String representative of VersionInfo |
| * @stable ICU 2.6 |
| */ |
| public String toString() |
| { |
| StringBuilder result = new StringBuilder(7); |
| result.append(getMajor()); |
| result.append('.'); |
| result.append(getMinor()); |
| result.append('.'); |
| result.append(getMilli()); |
| result.append('.'); |
| result.append(getMicro()); |
| return result.toString(); |
| } |
| |
| /** |
| * Returns the major version number |
| * @return the major version number |
| * @stable ICU 2.6 |
| */ |
| public int getMajor() |
| { |
| return (m_version_ >> 24) & LAST_BYTE_MASK_ ; |
| } |
| |
| /** |
| * Returns the minor version number |
| * @return the minor version number |
| * @stable ICU 2.6 |
| */ |
| public int getMinor() |
| { |
| return (m_version_ >> 16) & LAST_BYTE_MASK_ ; |
| } |
| |
| /** |
| * Returns the milli version number |
| * @return the milli version number |
| * @stable ICU 2.6 |
| */ |
| public int getMilli() |
| { |
| return (m_version_ >> 8) & LAST_BYTE_MASK_ ; |
| } |
| |
| /** |
| * Returns the micro version number |
| * @return the micro version number |
| * @stable ICU 2.6 |
| */ |
| public int getMicro() |
| { |
| return m_version_ & LAST_BYTE_MASK_ ; |
| } |
| |
| /** |
| * Checks if this version information is equals to the argument version |
| * @param other object to be compared |
| * @return true if other is equals to this object's version information, |
| * false otherwise |
| * @stable ICU 2.6 |
| */ |
| public boolean equals(Object other) |
| { |
| return other == this; |
| } |
| |
| /** |
| * Compares other with this VersionInfo. |
| * @param other VersionInfo to be compared |
| * @return 0 if the argument is a VersionInfo object that has version |
| * information equals to this object. |
| * Less than 0 if the argument is a VersionInfo object that has |
| * version information greater than this object. |
| * Greater than 0 if the argument is a VersionInfo object that |
| * has version information less than this object. |
| * @stable ICU 2.6 |
| */ |
| public int compareTo(VersionInfo other) |
| { |
| return m_version_ - other.m_version_; |
| } |
| |
| // private data members ---------------------------------------------- |
| |
| /** |
| * Unicode data version used by the current release |
| */ |
| private static final VersionInfo UNICODE_VERSION; |
| |
| /** |
| * Version number stored as a byte for each of the major, minor, milli and |
| * micro numbers in the 32 bit int. |
| * Most significant for the major and the least significant contains the |
| * micro numbers. |
| */ |
| private int m_version_; |
| /** |
| * Map of singletons |
| */ |
| private static final HashMap<Integer, VersionInfo> MAP_ = new HashMap<Integer, VersionInfo>(); |
| /** |
| * Last byte mask |
| */ |
| private static final int LAST_BYTE_MASK_ = 0xFF; |
| /** |
| * Error statement string |
| */ |
| private static final String INVALID_VERSION_NUMBER_ = |
| "Invalid version number: Version number may be negative or greater than 255"; |
| |
| // static declaration ------------------------------------------------ |
| |
| /** |
| * Initialize versions only after MAP_ has been created |
| */ |
| static { |
| UNICODE_1_0 = getInstance(1, 0, 0, 0); |
| UNICODE_1_0_1 = getInstance(1, 0, 1, 0); |
| UNICODE_1_1_0 = getInstance(1, 1, 0, 0); |
| UNICODE_1_1_5 = getInstance(1, 1, 5, 0); |
| UNICODE_2_0 = getInstance(2, 0, 0, 0); |
| UNICODE_2_1_2 = getInstance(2, 1, 2, 0); |
| UNICODE_2_1_5 = getInstance(2, 1, 5, 0); |
| UNICODE_2_1_8 = getInstance(2, 1, 8, 0); |
| UNICODE_2_1_9 = getInstance(2, 1, 9, 0); |
| UNICODE_3_0 = getInstance(3, 0, 0, 0); |
| UNICODE_3_0_1 = getInstance(3, 0, 1, 0); |
| UNICODE_3_1_0 = getInstance(3, 1, 0, 0); |
| UNICODE_3_1_1 = getInstance(3, 1, 1, 0); |
| UNICODE_3_2 = getInstance(3, 2, 0, 0); |
| UNICODE_4_0 = getInstance(4, 0, 0, 0); |
| UNICODE_4_0_1 = getInstance(4, 0, 1, 0); |
| UNICODE_4_1 = getInstance(4, 1, 0, 0); |
| UNICODE_5_0 = getInstance(5, 0, 0, 0); |
| UNICODE_5_1 = getInstance(5, 1, 0, 0); |
| UNICODE_5_2 = getInstance(5, 2, 0, 0); |
| |
| ICU_VERSION = getInstance(4, 5, 1, 0); |
| ICU_DATA_VERSION = getInstance(4, 5, 0, 0); |
| UNICODE_VERSION = UNICODE_5_2; |
| |
| UCOL_RUNTIME_VERSION = getInstance(6); |
| UCOL_BUILDER_VERSION = getInstance(7); |
| UCOL_TAILORINGS_VERSION = getInstance(1); |
| } |
| |
| // private constructor ----------------------------------------------- |
| |
| /** |
| * Constructor with int |
| * @param compactversion a 32 bit int with each byte representing a number |
| */ |
| private VersionInfo(int compactversion) |
| { |
| m_version_ = compactversion; |
| } |
| |
| /** |
| * Gets the int from the version numbers |
| * @param major non-negative version number |
| * @param minor non-negativeversion number |
| * @param milli non-negativeversion number |
| * @param micro non-negativeversion number |
| */ |
| private static int getInt(int major, int minor, int milli, int micro) |
| { |
| return (major << 24) | (minor << 16) | (milli << 8) | micro; |
| } |
| |
| /** |
| * Main method prints out ICU version information |
| * @param args arguments (currently not used) |
| * @draft ICU 4.6 |
| * @provisional This API might change or be removed in a future release. |
| */ |
| public static void main(String[] args) { |
| String icuApiVer; |
| |
| if (ICU_VERSION.getMinor() % 2 != 0) { |
| // Development mile stone |
| int major = ICU_VERSION.getMajor(); |
| int minor = ICU_VERSION.getMinor() + 1; |
| if (minor >= 10) { |
| minor -= 10; |
| major++; |
| } |
| icuApiVer = "" + major + "." + minor + "M" + ICU_VERSION.getMilli(); |
| } else { |
| icuApiVer = ICU_VERSION.getVersionString(2, 2); |
| } |
| |
| System.out.println("International Component for Unicode for Java " + icuApiVer); |
| |
| System.out.println(""); |
| System.out.println("Implementation Version: " + ICU_VERSION.getVersionString(2, 4)); |
| System.out.println("Unicode Data Version: " + UNICODE_VERSION.getVersionString(2, 4)); |
| System.out.println("CLDR Data Version: " + LocaleData.getCLDRVersion().getVersionString(2, 4)); |
| System.out.println("Time Zone Data Version: " + TimeZone.getTZDataVersion()); |
| } |
| |
| /** |
| * Generate version string separated by dots with |
| * the specified digit width. Version digit 0 |
| * after <code>minDigits</code> will be trimmed off. |
| * @param minDigits Minimum number of version digits |
| * @param maxDigits Maximum number of version digits |
| * @return A tailored version string |
| */ |
| private String getVersionString(int minDigits, int maxDigits) { |
| if (minDigits < 1 || maxDigits < 1 |
| || minDigits > 4 || maxDigits > 4 || minDigits > maxDigits) { |
| throw new IllegalArgumentException("Invalid min/maxDigits range"); |
| } |
| |
| int[] digits = new int[4]; |
| digits[0] = getMajor(); |
| digits[1] = getMinor(); |
| digits[2] = getMilli(); |
| digits[3] = getMicro(); |
| |
| int numDigits = maxDigits; |
| while (numDigits > minDigits) { |
| if (digits[numDigits - 1] != 0) { |
| break; |
| } |
| numDigits--; |
| } |
| |
| StringBuilder verStr = new StringBuilder(7); |
| verStr.append(digits[0]); |
| for (int i = 1; i < numDigits; i++) { |
| verStr.append("."); |
| verStr.append(digits[i]); |
| } |
| |
| return verStr.toString(); |
| } |
| } |