1 /* 2 * Copyright (c) 2005, 2020, 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 ******************************************************************************* 27 * (C) Copyright IBM Corp. and others, 1996-2009 - All Rights Reserved * 28 * * 29 * The original version of this source code and documentation is copyrighted * 30 * and owned by IBM, These materials are provided under terms of a License * 31 * Agreement between IBM and Sun. This technology is protected by multiple * 32 * US and International patents. This notice and attribution to IBM may not * 33 * to removed. * 34 ******************************************************************************* 35 */ 36 37 package jdk.internal.icu.util; 38 39 import java.util.HashMap; 40 41 /** 42 * Class to store version numbers of the form major.minor.milli.micro. 43 * @author synwee 44 * @stable ICU 2.6 45 */ 46 public final class VersionInfo 47 { 48 // public data members ------------------------------------------------- 49 50 /** 51 * Data version string for ICU's internal data. 52 * Used for appending to data path (e.g. icudt43b) 53 * @internal 54 * @deprecated This API is ICU internal only. 55 */ 56 @Deprecated 57 public static final String ICU_DATA_VERSION_PATH = "64b"; 58 59 // public methods ------------------------------------------------------ 60 61 /** 62 * Returns an instance of VersionInfo with the argument version. 63 * @param version version String in the format of "major.minor.milli.micro" 64 * or "major.minor.milli" or "major.minor" or "major", 65 * where major, minor, milli, micro are non-negative numbers 66 * {@literal <=} 255. If the trailing version numbers are 67 * not specified they are taken as 0s. E.g. Version "3.1" is 68 * equivalent to "3.1.0.0". 69 * @return an instance of VersionInfo with the argument version. 70 * @exception throws an IllegalArgumentException when the argument version 71 * is not in the right format 72 * @stable ICU 2.6 73 */ 74 public static VersionInfo getInstance(String version) 75 { 76 int length = version.length(); 77 int array[] = {0, 0, 0, 0}; 78 int count = 0; 79 int index = 0; 80 81 while (count < 4 && index < length) { 82 char c = version.charAt(index); 83 if (c == '.') { 84 count ++; 85 } 86 else { 87 c -= '0'; 88 if (c < 0 || c > 9) { 89 throw new IllegalArgumentException(INVALID_VERSION_NUMBER_); 90 } 91 array[count] *= 10; 92 array[count] += c; 93 } 94 index ++; 95 } 96 if (index != length) { 97 throw new IllegalArgumentException( 98 "Invalid version number: String '" + version + "' exceeds version format"); 99 } 100 for (int i = 0; i < 4; i ++) { 101 if (array[i] < 0 || array[i] > 255) { 102 throw new IllegalArgumentException(INVALID_VERSION_NUMBER_); 103 } 104 } 105 106 return getInstance(array[0], array[1], array[2], array[3]); 107 } 108 109 /** 110 * Returns an instance of VersionInfo with the argument version. 111 * @param major major version, non-negative number {@literal <=} 255. 112 * @param minor minor version, non-negative number {@literal <=} 255. 113 * @param milli milli version, non-negative number {@literal <=} 255. 114 * @param micro micro version, non-negative number {@literal <=} 255. 115 * @exception throws an IllegalArgumentException when either arguments are 116 * negative or {@literal >} 255 117 * @stable ICU 2.6 118 */ 119 public static VersionInfo getInstance(int major, int minor, int milli, 120 int micro) 121 { 122 // checks if it is in the hashmap 123 // else 124 if (major < 0 || major > 255 || minor < 0 || minor > 255 || 125 milli < 0 || milli > 255 || micro < 0 || micro > 255) { 126 throw new IllegalArgumentException(INVALID_VERSION_NUMBER_); 127 } 128 int version = getInt(major, minor, milli, micro); 129 Integer key = Integer.valueOf(version); 130 Object result = MAP_.get(key); 131 if (result == null) { 132 result = new VersionInfo(version); 133 MAP_.put(key, result); 134 } 135 return (VersionInfo)result; 136 } 137 138 /** 139 * Compares other with this VersionInfo. 140 * @param other VersionInfo to be compared 141 * @return 0 if the argument is a VersionInfo object that has version 142 * information equal to this object. 143 * Less than 0 if the argument is a VersionInfo object that has 144 * version information greater than this object. 145 * Greater than 0 if the argument is a VersionInfo object that 146 * has version information less than this object. 147 * @stable ICU 2.6 148 */ 149 public int compareTo(VersionInfo other) 150 { 151 return m_version_ - other.m_version_; 152 } 153 154 // private data members ---------------------------------------------- 155 156 /** 157 * Version number stored as a byte for each of the major, minor, milli and 158 * micro numbers in the 32 bit int. 159 * Most significant for the major and the least significant contains the 160 * micro numbers. 161 */ 162 private int m_version_; 163 /** 164 * Map of singletons 165 */ 166 private static final HashMap<Integer, Object> MAP_ = new HashMap<>(); 167 /** 168 * Error statement string 169 */ 170 private static final String INVALID_VERSION_NUMBER_ = 171 "Invalid version number: Version number may be negative or greater than 255"; 172 173 // private constructor ----------------------------------------------- 174 175 /** 176 * Constructor with int 177 * @param compactversion a 32 bit int with each byte representing a number 178 */ 179 private VersionInfo(int compactversion) 180 { 181 m_version_ = compactversion; 182 } 183 184 /** 185 * Gets the int from the version numbers 186 * @param major non-negative version number 187 * @param minor non-negativeversion number 188 * @param milli non-negativeversion number 189 * @param micro non-negativeversion number 190 */ 191 private static int getInt(int major, int minor, int milli, int micro) 192 { 193 return (major << 24) | (minor << 16) | (milli << 8) | micro; 194 } 195 }