1 /* GENERATED SOURCE. DO NOT MODIFY. */ 2 // 2016 and later: Unicode, Inc. and others. 3 // License & terms of use: http://www.unicode.org/copyright.html#License 4 /* 5 ******************************************************************************* 6 * Copyright (C) 1996-2016, International Business Machines Corporation and 7 * others. All Rights Reserved. 8 ******************************************************************************* 9 */ 10 11 package android.icu.util; 12 13 import java.util.concurrent.ConcurrentHashMap; 14 15 /** 16 * Class to store version numbers of the form major.minor.milli.micro. 17 * @author synwee 18 */ 19 public final class VersionInfo implements Comparable<VersionInfo> 20 { 21 // public data members ------------------------------------------------- 22 23 /** 24 * Unicode 1.0 version 25 */ 26 public static final VersionInfo UNICODE_1_0; 27 /** 28 * Unicode 1.0.1 version 29 */ 30 public static final VersionInfo UNICODE_1_0_1; 31 /** 32 * Unicode 1.1.0 version 33 */ 34 public static final VersionInfo UNICODE_1_1_0; 35 /** 36 * Unicode 1.1.5 version 37 */ 38 public static final VersionInfo UNICODE_1_1_5; 39 /** 40 * Unicode 2.0 version 41 */ 42 public static final VersionInfo UNICODE_2_0; 43 /** 44 * Unicode 2.1.2 version 45 */ 46 public static final VersionInfo UNICODE_2_1_2; 47 /** 48 * Unicode 2.1.5 version 49 */ 50 public static final VersionInfo UNICODE_2_1_5; 51 /** 52 * Unicode 2.1.8 version 53 */ 54 public static final VersionInfo UNICODE_2_1_8; 55 /** 56 * Unicode 2.1.9 version 57 */ 58 public static final VersionInfo UNICODE_2_1_9; 59 /** 60 * Unicode 3.0 version 61 */ 62 public static final VersionInfo UNICODE_3_0; 63 /** 64 * Unicode 3.0.1 version 65 */ 66 public static final VersionInfo UNICODE_3_0_1; 67 /** 68 * Unicode 3.1.0 version 69 */ 70 public static final VersionInfo UNICODE_3_1_0; 71 /** 72 * Unicode 3.1.1 version 73 */ 74 public static final VersionInfo UNICODE_3_1_1; 75 /** 76 * Unicode 3.2 version 77 */ 78 public static final VersionInfo UNICODE_3_2; 79 80 /** 81 * Unicode 4.0 version 82 */ 83 public static final VersionInfo UNICODE_4_0; 84 85 /** 86 * Unicode 4.0.1 version 87 */ 88 public static final VersionInfo UNICODE_4_0_1; 89 90 /** 91 * Unicode 4.1 version 92 */ 93 public static final VersionInfo UNICODE_4_1; 94 95 /** 96 * Unicode 5.0 version 97 */ 98 public static final VersionInfo UNICODE_5_0; 99 100 /** 101 * Unicode 5.1 version 102 */ 103 public static final VersionInfo UNICODE_5_1; 104 105 /** 106 * Unicode 5.2 version 107 */ 108 public static final VersionInfo UNICODE_5_2; 109 110 /** 111 * Unicode 6.0 version 112 */ 113 public static final VersionInfo UNICODE_6_0; 114 115 /** 116 * Unicode 6.1 version 117 */ 118 public static final VersionInfo UNICODE_6_1; 119 120 /** 121 * Unicode 6.2 version 122 */ 123 public static final VersionInfo UNICODE_6_2; 124 125 /** 126 * Unicode 6.3 version 127 */ 128 public static final VersionInfo UNICODE_6_3; 129 130 /** 131 * Unicode 7.0 version 132 */ 133 public static final VersionInfo UNICODE_7_0; 134 135 /** 136 * Unicode 8.0 version 137 */ 138 public static final VersionInfo UNICODE_8_0; 139 140 /** 141 * Unicode 9.0 version 142 */ 143 public static final VersionInfo UNICODE_9_0; 144 145 /** 146 * ICU4J current release version 147 */ 148 public static final VersionInfo ICU_VERSION; 149 150 /** 151 * Data version string for ICU's internal data. 152 * Used for appending to data path (e.g. icudt43b) 153 * @deprecated This API is ICU internal only. 154 * @hide original deprecated declaration 155 * @hide draft / provisional / internal are hidden on Android 156 */ 157 @Deprecated 158 public static final String ICU_DATA_VERSION_PATH = "58b"; 159 160 /** 161 * Data version in ICU4J. 162 * @deprecated This API is ICU internal only. 163 * @hide original deprecated declaration 164 * @hide draft / provisional / internal are hidden on Android 165 */ 166 @Deprecated 167 public static final VersionInfo ICU_DATA_VERSION; 168 169 /** 170 * Collation runtime version (sort key generator, string comparisons). 171 * If the version is different, sort keys for the same string could be different. 172 * This value may change in subsequent releases of ICU. 173 */ 174 public static final VersionInfo UCOL_RUNTIME_VERSION; 175 176 /** 177 * Collation builder code version. 178 * When this is different, the same tailoring might result 179 * in assigning different collation elements to code points. 180 * This value may change in subsequent releases of ICU. 181 */ 182 public static final VersionInfo UCOL_BUILDER_VERSION; 183 184 /** 185 * Constant version 1. 186 * This was intended to be the version of collation tailorings, 187 * but instead the tailoring data carries a version number. 188 * @deprecated ICU 54 189 * @hide original deprecated declaration 190 */ 191 @Deprecated 192 public static final VersionInfo UCOL_TAILORINGS_VERSION; 193 194 195 // public methods ------------------------------------------------------ 196 197 /** 198 * Returns an instance of VersionInfo with the argument version. 199 * @param version version String in the format of "major.minor.milli.micro" 200 * or "major.minor.milli" or "major.minor" or "major", 201 * where major, minor, milli, micro are non-negative numbers 202 * <= 255. If the trailing version numbers are 203 * not specified they are taken as 0s. E.g. Version "3.1" is 204 * equivalent to "3.1.0.0". 205 * @return an instance of VersionInfo with the argument version. 206 * @exception IllegalArgumentException when the argument version 207 * is not in the right format 208 */ 209 public static VersionInfo getInstance(String version) 210 { 211 int length = version.length(); 212 int array[] = {0, 0, 0, 0}; 213 int count = 0; 214 int index = 0; 215 216 while (count < 4 && index < length) { 217 char c = version.charAt(index); 218 if (c == '.') { 219 count ++; 220 } 221 else { 222 c -= '0'; 223 if (c < 0 || c > 9) { 224 throw new IllegalArgumentException(INVALID_VERSION_NUMBER_); 225 } 226 array[count] *= 10; 227 array[count] += c; 228 } 229 index ++; 230 } 231 if (index != length) { 232 throw new IllegalArgumentException( 233 "Invalid version number: String '" + version + "' exceeds version format"); 234 } 235 for (int i = 0; i < 4; i ++) { 236 if (array[i] < 0 || array[i] > 255) { 237 throw new IllegalArgumentException(INVALID_VERSION_NUMBER_); 238 } 239 } 240 241 return getInstance(array[0], array[1], array[2], array[3]); 242 } 243 244 /** 245 * Returns an instance of VersionInfo with the argument version. 246 * @param major major version, non-negative number <= 255. 247 * @param minor minor version, non-negative number <= 255. 248 * @param milli milli version, non-negative number <= 255. 249 * @param micro micro version, non-negative number <= 255. 250 * @exception IllegalArgumentException when either arguments are negative or > 255 251 */ 252 public static VersionInfo getInstance(int major, int minor, int milli, 253 int micro) 254 { 255 // checks if it is in the hashmap 256 // else 257 if (major < 0 || major > 255 || minor < 0 || minor > 255 || 258 milli < 0 || milli > 255 || micro < 0 || micro > 255) { 259 throw new IllegalArgumentException(INVALID_VERSION_NUMBER_); 260 } 261 int version = getInt(major, minor, milli, micro); 262 Integer key = Integer.valueOf(version); 263 VersionInfo result = MAP_.get(key); 264 if (result == null) { 265 result = new VersionInfo(version); 266 VersionInfo tmpvi = MAP_.putIfAbsent(key, result); 267 if (tmpvi != null) { 268 result = tmpvi; 269 } 270 } 271 return result; 272 } 273 274 /** 275 * Returns an instance of VersionInfo with the argument version. 276 * Equivalent to getInstance(major, minor, milli, 0). 277 * @param major major version, non-negative number <= 255. 278 * @param minor minor version, non-negative number <= 255. 279 * @param milli milli version, non-negative number <= 255. 280 * @exception IllegalArgumentException when either arguments are 281 * negative or > 255 282 */ 283 public static VersionInfo getInstance(int major, int minor, int milli) 284 { 285 return getInstance(major, minor, milli, 0); 286 } 287 288 /** 289 * Returns an instance of VersionInfo with the argument version. 290 * Equivalent to getInstance(major, minor, 0, 0). 291 * @param major major version, non-negative number <= 255. 292 * @param minor minor version, non-negative number <= 255. 293 * @exception IllegalArgumentException when either arguments are 294 * negative or > 255 295 */ 296 public static VersionInfo getInstance(int major, int minor) 297 { 298 return getInstance(major, minor, 0, 0); 299 } 300 301 /** 302 * Returns an instance of VersionInfo with the argument version. 303 * Equivalent to getInstance(major, 0, 0, 0). 304 * @param major major version, non-negative number <= 255. 305 * @exception IllegalArgumentException when either arguments are 306 * negative or > 255 307 */ 308 public static VersionInfo getInstance(int major) 309 { 310 return getInstance(major, 0, 0, 0); 311 } 312 313 private static volatile VersionInfo javaVersion; 314 315 /** 316 * @deprecated This API is ICU internal only. 317 * @hide original deprecated declaration 318 * @hide draft / provisional / internal are hidden on Android 319 */ 320 @Deprecated 321 public static VersionInfo javaVersion() { 322 if (javaVersion == null) { 323 synchronized(VersionInfo.class) { 324 if (javaVersion == null) { 325 String s = System.getProperty("java.version"); 326 // clean string 327 // preserve only digits, separated by single '.' 328 // ignore over 4 digit sequences 329 // does not test < 255, very odd... 330 331 char[] chars = s.toCharArray(); 332 int r = 0, w = 0, count = 0; 333 boolean numeric = false; // ignore leading non-numerics 334 while (r < chars.length) { 335 char c = chars[r++]; 336 if (c < '0' || c > '9') { 337 if (numeric) { 338 if (count == 3) { 339 // only four digit strings allowed 340 break; 341 } 342 numeric = false; 343 chars[w++] = '.'; 344 ++count; 345 } 346 } else { 347 numeric = true; 348 chars[w++] = c; 349 } 350 } 351 while (w > 0 && chars[w-1] == '.') { 352 --w; 353 } 354 355 String vs = new String(chars, 0, w); 356 357 javaVersion = VersionInfo.getInstance(vs); 358 } 359 } 360 } 361 return javaVersion; 362 } 363 364 /** 365 * Returns the String representative of VersionInfo in the format of 366 * "major.minor.milli.micro" 367 * @return String representative of VersionInfo 368 */ 369 @Override 370 public String toString() 371 { 372 StringBuilder result = new StringBuilder(7); 373 result.append(getMajor()); 374 result.append('.'); 375 result.append(getMinor()); 376 result.append('.'); 377 result.append(getMilli()); 378 result.append('.'); 379 result.append(getMicro()); 380 return result.toString(); 381 } 382 383 /** 384 * Returns the major version number 385 * @return the major version number 386 */ 387 public int getMajor() 388 { 389 return (m_version_ >> 24) & LAST_BYTE_MASK_ ; 390 } 391 392 /** 393 * Returns the minor version number 394 * @return the minor version number 395 */ 396 public int getMinor() 397 { 398 return (m_version_ >> 16) & LAST_BYTE_MASK_ ; 399 } 400 401 /** 402 * Returns the milli version number 403 * @return the milli version number 404 */ 405 public int getMilli() 406 { 407 return (m_version_ >> 8) & LAST_BYTE_MASK_ ; 408 } 409 410 /** 411 * Returns the micro version number 412 * @return the micro version number 413 */ 414 public int getMicro() 415 { 416 return m_version_ & LAST_BYTE_MASK_ ; 417 } 418 419 /** 420 * Checks if this version information is equals to the argument version 421 * @param other object to be compared 422 * @return true if other is equals to this object's version information, 423 * false otherwise 424 */ 425 @Override 426 public boolean equals(Object other) 427 { 428 return other == this; 429 } 430 431 /** 432 * Returns the hash code value for this set. 433 * 434 * @return the hash code value for this set. 435 * @see java.lang.Object#hashCode() 436 */ 437 @Override 438 public int hashCode() { 439 return m_version_; 440 } 441 442 /** 443 * Compares other with this VersionInfo. 444 * @param other VersionInfo to be compared 445 * @return 0 if the argument is a VersionInfo object that has version 446 * information equals to this object. 447 * Less than 0 if the argument is a VersionInfo object that has 448 * version information greater than this object. 449 * Greater than 0 if the argument is a VersionInfo object that 450 * has version information less than this object. 451 */ 452 @Override 453 public int compareTo(VersionInfo other) 454 { 455 return m_version_ - other.m_version_; 456 } 457 458 // private data members ---------------------------------------------- 459 460 /** 461 * Unicode data version used by the current release. 462 * Defined here privately for printing by the main() method in this class. 463 * Should be the same as {@link android.icu.lang.UCharacter#getUnicodeVersion()} 464 * which gets the version number from a data file. 465 * We do not want VersionInfo to have an import dependency on UCharacter. 466 */ 467 private static final VersionInfo UNICODE_VERSION; 468 469 /** 470 * Version number stored as a byte for each of the major, minor, milli and 471 * micro numbers in the 32 bit int. 472 * Most significant for the major and the least significant contains the 473 * micro numbers. 474 */ 475 private int m_version_; 476 /** 477 * Map of singletons 478 */ 479 private static final ConcurrentHashMap<Integer, VersionInfo> MAP_ = new ConcurrentHashMap<Integer, VersionInfo>(); 480 /** 481 * Last byte mask 482 */ 483 private static final int LAST_BYTE_MASK_ = 0xFF; 484 /** 485 * Error statement string 486 */ 487 private static final String INVALID_VERSION_NUMBER_ = 488 "Invalid version number: Version number may be negative or greater than 255"; 489 490 // static declaration ------------------------------------------------ 491 492 /** 493 * Initialize versions only after MAP_ has been created 494 */ 495 static { 496 UNICODE_1_0 = getInstance(1, 0, 0, 0); 497 UNICODE_1_0_1 = getInstance(1, 0, 1, 0); 498 UNICODE_1_1_0 = getInstance(1, 1, 0, 0); 499 UNICODE_1_1_5 = getInstance(1, 1, 5, 0); 500 UNICODE_2_0 = getInstance(2, 0, 0, 0); 501 UNICODE_2_1_2 = getInstance(2, 1, 2, 0); 502 UNICODE_2_1_5 = getInstance(2, 1, 5, 0); 503 UNICODE_2_1_8 = getInstance(2, 1, 8, 0); 504 UNICODE_2_1_9 = getInstance(2, 1, 9, 0); 505 UNICODE_3_0 = getInstance(3, 0, 0, 0); 506 UNICODE_3_0_1 = getInstance(3, 0, 1, 0); 507 UNICODE_3_1_0 = getInstance(3, 1, 0, 0); 508 UNICODE_3_1_1 = getInstance(3, 1, 1, 0); 509 UNICODE_3_2 = getInstance(3, 2, 0, 0); 510 UNICODE_4_0 = getInstance(4, 0, 0, 0); 511 UNICODE_4_0_1 = getInstance(4, 0, 1, 0); 512 UNICODE_4_1 = getInstance(4, 1, 0, 0); 513 UNICODE_5_0 = getInstance(5, 0, 0, 0); 514 UNICODE_5_1 = getInstance(5, 1, 0, 0); 515 UNICODE_5_2 = getInstance(5, 2, 0, 0); 516 UNICODE_6_0 = getInstance(6, 0, 0, 0); 517 UNICODE_6_1 = getInstance(6, 1, 0, 0); 518 UNICODE_6_2 = getInstance(6, 2, 0, 0); 519 UNICODE_6_3 = getInstance(6, 3, 0, 0); 520 UNICODE_7_0 = getInstance(7, 0, 0, 0); 521 UNICODE_8_0 = getInstance(8, 0, 0, 0); 522 UNICODE_9_0 = getInstance(9, 0, 0, 0); 523 524 ICU_VERSION = getInstance(58, 2, 0, 0); 525 ICU_DATA_VERSION = getInstance(58, 2, 0, 0); 526 UNICODE_VERSION = UNICODE_9_0; 527 528 UCOL_RUNTIME_VERSION = getInstance(9); 529 UCOL_BUILDER_VERSION = getInstance(9); 530 UCOL_TAILORINGS_VERSION = getInstance(1); 531 } 532 533 // private constructor ----------------------------------------------- 534 535 /** 536 * Constructor with int 537 * @param compactversion a 32 bit int with each byte representing a number 538 */ 539 private VersionInfo(int compactversion) 540 { 541 m_version_ = compactversion; 542 } 543 544 /** 545 * Gets the int from the version numbers 546 * @param major non-negative version number 547 * @param minor non-negative version number 548 * @param milli non-negative version number 549 * @param micro non-negative version number 550 */ 551 private static int getInt(int major, int minor, int milli, int micro) 552 { 553 return (major << 24) | (minor << 16) | (milli << 8) | micro; 554 } 555 ///CLOVER:OFF 556 /** 557 * Main method prints out ICU version information 558 * @param args arguments (currently not used) 559 * @hide unsupported on Android 560 */ 561 public static void main(String[] args) { 562 String icuApiVer; 563 564 if (ICU_VERSION.getMajor() <= 4) { 565 if (ICU_VERSION.getMinor() % 2 != 0) { 566 // Development mile stone 567 int major = ICU_VERSION.getMajor(); 568 int minor = ICU_VERSION.getMinor() + 1; 569 if (minor >= 10) { 570 minor -= 10; 571 major++; 572 } 573 icuApiVer = "" + major + "." + minor + "M" + ICU_VERSION.getMilli(); 574 } else { 575 icuApiVer = ICU_VERSION.getVersionString(2, 2); 576 } 577 } else { 578 if (ICU_VERSION.getMinor() == 0) { 579 // Development mile stone 580 icuApiVer = "" + ICU_VERSION.getMajor() + "M" + ICU_VERSION.getMilli(); 581 } else { 582 icuApiVer = ICU_VERSION.getVersionString(2, 2); 583 } 584 } 585 586 587 System.out.println("International Components for Unicode for Java " + icuApiVer); 588 589 System.out.println(""); 590 System.out.println("Implementation Version: " + ICU_VERSION.getVersionString(2, 4)); 591 System.out.println("Unicode Data Version: " + UNICODE_VERSION.getVersionString(2, 4)); 592 System.out.println("CLDR Data Version: " + LocaleData.getCLDRVersion().getVersionString(2, 4)); 593 System.out.println("Time Zone Data Version: " + getTZDataVersion()); 594 } 595 596 /** 597 * Generate version string separated by dots with 598 * the specified digit width. Version digit 0 599 * after <code>minDigits</code> will be trimmed off. 600 * @param minDigits Minimum number of version digits 601 * @param maxDigits Maximum number of version digits 602 * @return A tailored version string 603 * @deprecated This API is ICU internal only. (For use in CLDR, etc.) 604 * @hide original deprecated declaration 605 * @hide draft / provisional / internal are hidden on Android 606 */ 607 @Deprecated 608 public String getVersionString(int minDigits, int maxDigits) { 609 if (minDigits < 1 || maxDigits < 1 610 || minDigits > 4 || maxDigits > 4 || minDigits > maxDigits) { 611 throw new IllegalArgumentException("Invalid min/maxDigits range"); 612 } 613 614 int[] digits = new int[4]; 615 digits[0] = getMajor(); 616 digits[1] = getMinor(); 617 digits[2] = getMilli(); 618 digits[3] = getMicro(); 619 620 int numDigits = maxDigits; 621 while (numDigits > minDigits) { 622 if (digits[numDigits - 1] != 0) { 623 break; 624 } 625 numDigits--; 626 } 627 628 StringBuilder verStr = new StringBuilder(7); 629 verStr.append(digits[0]); 630 for (int i = 1; i < numDigits; i++) { 631 verStr.append("."); 632 verStr.append(digits[i]); 633 } 634 635 return verStr.toString(); 636 } 637 ///CLOVER:ON 638 639 640 // Moved from TimeZone class 641 private static volatile String TZDATA_VERSION = null; 642 643 static String getTZDataVersion() { 644 if (TZDATA_VERSION == null) { 645 synchronized (VersionInfo.class) { 646 if (TZDATA_VERSION == null) { 647 UResourceBundle tzbundle = UResourceBundle.getBundleInstance("android/icu/impl/data/icudt" 648 + VersionInfo.ICU_DATA_VERSION_PATH, "zoneinfo64"); 649 TZDATA_VERSION = tzbundle.getString("TZVersion"); 650 } 651 } 652 } 653 return TZDATA_VERSION; 654 } 655 } 656