1 /*
2  * Copyright (c) 2005, 2011, 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 sun.text.normalizer;
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 
49     // public methods ------------------------------------------------------
50 
51     /**
52      * Returns an instance of VersionInfo with the argument version.
53      * @param version version String in the format of "major.minor.milli.micro"
54      *                or "major.minor.milli" or "major.minor" or "major",
55      *                where major, minor, milli, micro are non-negative numbers
56      *                {@literal <=} 255. If the trailing version numbers are
57      *                not specified they are taken as 0s. E.g. Version "3.1" is
58      *                equivalent to "3.1.0.0".
59      * @return an instance of VersionInfo with the argument version.
60      * @exception throws an IllegalArgumentException when the argument version
61      *                is not in the right format
62      * @stable ICU 2.6
63      */
getInstance(String version)64     public static VersionInfo getInstance(String version)
65     {
66         int length  = version.length();
67         int array[] = {0, 0, 0, 0};
68         int count   = 0;
69         int index   = 0;
70 
71         while (count < 4 && index < length) {
72             char c = version.charAt(index);
73             if (c == '.') {
74                 count ++;
75             }
76             else {
77                 c -= '0';
78                 if (c < 0 || c > 9) {
79                     throw new IllegalArgumentException(INVALID_VERSION_NUMBER_);
80                 }
81                 array[count] *= 10;
82                 array[count] += c;
83             }
84             index ++;
85         }
86         if (index != length) {
87             throw new IllegalArgumentException(
88                                                "Invalid version number: String '" + version + "' exceeds version format");
89         }
90         for (int i = 0; i < 4; i ++) {
91             if (array[i] < 0 || array[i] > 255) {
92                 throw new IllegalArgumentException(INVALID_VERSION_NUMBER_);
93             }
94         }
95 
96         return getInstance(array[0], array[1], array[2], array[3]);
97     }
98 
99     /**
100      * Returns an instance of VersionInfo with the argument version.
101      * @param major major version, non-negative number {@literal <=} 255.
102      * @param minor minor version, non-negative number {@literal <=} 255.
103      * @param milli milli version, non-negative number {@literal <=} 255.
104      * @param micro micro version, non-negative number {@literal <=} 255.
105      * @exception throws an IllegalArgumentException when either arguments are
106      *                                     negative or {@literal >} 255
107      * @stable ICU 2.6
108      */
getInstance(int major, int minor, int milli, int micro)109     public static VersionInfo getInstance(int major, int minor, int milli,
110                                           int micro)
111     {
112         // checks if it is in the hashmap
113         // else
114         if (major < 0 || major > 255 || minor < 0 || minor > 255 ||
115             milli < 0 || milli > 255 || micro < 0 || micro > 255) {
116             throw new IllegalArgumentException(INVALID_VERSION_NUMBER_);
117         }
118         int     version = getInt(major, minor, milli, micro);
119         Integer key     = Integer.valueOf(version);
120         Object  result  = MAP_.get(key);
121         if (result == null) {
122             result = new VersionInfo(version);
123             MAP_.put(key, result);
124         }
125         return (VersionInfo)result;
126     }
127 
128     /**
129      * Compares other with this VersionInfo.
130      * @param other VersionInfo to be compared
131      * @return 0 if the argument is a VersionInfo object that has version
132      *           information equals to this object.
133      *           Less than 0 if the argument is a VersionInfo object that has
134      *           version information greater than this object.
135      *           Greater than 0 if the argument is a VersionInfo object that
136      *           has version information less than this object.
137      * @stable ICU 2.6
138      */
compareTo(VersionInfo other)139     public int compareTo(VersionInfo other)
140     {
141         return m_version_ - other.m_version_;
142     }
143 
144     // private data members ----------------------------------------------
145 
146     /**
147      * Version number stored as a byte for each of the major, minor, milli and
148      * micro numbers in the 32 bit int.
149      * Most significant for the major and the least significant contains the
150      * micro numbers.
151      */
152     private int m_version_;
153     /**
154      * Map of singletons
155      */
156     private static final HashMap<Integer, Object> MAP_ = new HashMap<>();
157     /**
158      * Error statement string
159      */
160     private static final String INVALID_VERSION_NUMBER_ =
161         "Invalid version number: Version number may be negative or greater than 255";
162 
163     // private constructor -----------------------------------------------
164 
165     /**
166      * Constructor with int
167      * @param compactversion a 32 bit int with each byte representing a number
168      */
VersionInfo(int compactversion)169     private VersionInfo(int compactversion)
170     {
171         m_version_ = compactversion;
172     }
173 
174     /**
175      * Gets the int from the version numbers
176      * @param major non-negative version number
177      * @param minor non-negativeversion number
178      * @param milli non-negativeversion number
179      * @param micro non-negativeversion number
180      */
getInt(int major, int minor, int milli, int micro)181     private static int getInt(int major, int minor, int milli, int micro)
182     {
183         return (major << 24) | (minor << 16) | (milli << 8) | micro;
184     }
185 }
186