1 /* 2 * Copyright (c) 2018, 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 * @test 28 * @bug 4397357 6565620 6959267 7070436 7198195 8032446 8072600 29 * @summary Confirm normal case mappings are handled correctly. 30 * @run main/timeout=200 UnicodeCasingTest 31 */ 32 33 import java.io.BufferedReader; 34 import java.io.IOException; 35 import java.nio.file.Files; 36 import java.nio.file.Paths; 37 import java.util.ArrayList; 38 import java.util.Locale; 39 import java.util.HashMap; 40 import java.util.List; 41 import java.util.Map; 42 43 public class UnicodeCasingTest { 44 45 private static boolean err = false; 46 47 // Locales which are used for testing 48 private static List<Locale> locales = new ArrayList<>(); 49 static { 50 locales.add(new Locale("az", "")); 51 locales.addAll(java.util.Arrays.asList(Locale.getAvailableLocales())); 52 } 53 54 // Default locale 55 private static String defaultLang; 56 57 // List for Unicode characters whose mappings are included in 58 // SpecialCasing.txt and mappings in UnicodeData.txt isn't applicable. 59 private static Map<String, String> excludeList = new HashMap<>(); 60 61 public static void main(String[] args) { 62 UnicodeCasingTest specialCasingTest = new UnicodeCasingTest(); 63 specialCasingTest.test(); 64 } 65 66 private void test() { 67 Locale defaultLocale = Locale.getDefault(); 68 BufferedReader in = null; 69 try { 70 // First, we create exlude lists of characters whose mappings exist 71 // in SpecialCasing.txt and mapping rules in UnicodeData.txt aren't 72 // applicable. 73 in = Files.newBufferedReader(Paths.get(System.getProperty("test.src.path"), "..", "/Character/SpecialCasing.txt") 74 .toRealPath()); 75 String line; 76 while ((line = in.readLine()) != null) { 77 if (line.length() == 0 || line.charAt(0) == '#') { 78 continue; 79 } 80 updateExcludeList(line); 81 } 82 in.close(); 83 in = null; 84 int locale_num = locales.size(); 85 for (int l = 0; l < locale_num; l++) { 86 Locale locale = locales.get(l); 87 Locale.setDefault(locale); 88 defaultLang = locale.getLanguage(); 89 // System.out.println("Testing on " + locale + " locale...."); 90 System.err.println("Testing on " + locale + " locale...."); 91 in = Files.newBufferedReader(Paths.get(System.getProperty("test.src.path"), "..", "/Character/UnicodeData.txt") 92 .toRealPath()); 93 while ((line = in.readLine()) != null) { 94 if (line.length() == 0 || line.charAt(0) == '#') { 95 continue; 96 } 97 test(line); 98 } 99 in.close(); 100 in = null; 101 } 102 } 103 catch (IOException e) { 104 err = true; 105 e.printStackTrace(); 106 } 107 finally { 108 if (in != null) { 109 try { 110 in.close(); 111 } 112 catch (IOException e) { 113 } 114 } 115 116 Locale.setDefault(defaultLocale); 117 118 if (err) { 119 throw new RuntimeException("UnicodeCasingTest failed."); 120 } else { 121 System.out.println("*** UnicodeCasingTest passed."); 122 } 123 } 124 } 125 126 private void updateExcludeList(String line) { 127 int index = line.indexOf('#'); 128 if (index != -1) { 129 line = line.substring(0, index); 130 } 131 132 String lang = null; 133 String condition = null; 134 String[] fields = line.split("; "); 135 136 // If the given character is mapped to multiple characters under the 137 // normal condition, add it to the exclude list. 138 if (fields.length == 4) { 139 excludeList.put(fields[0], "all"); 140 } else if (fields.length == 5) { 141 if (fields[4].length() == 2) { /// locale 142 if (excludeList.get(fields[0]) == null) { 143 excludeList.put(fields[0], fields[4]); 144 } 145 } 146 } 147 } 148 149 private void test(String line) { 150 String[] fields = line.split(";", 15); 151 String orig = convert(fields[0]); 152 153 String lang = excludeList.get(fields[0]); 154 if (!"all".equals(lang) && !defaultLang.equals(lang)) { 155 if (fields[12].length() == 0) { 156 testUpperCase(orig, convert(fields[0])); 157 } else { 158 testUpperCase(orig, convert(fields[12])); 159 } 160 161 if (fields[13].length() == 0) { 162 testLowerCase(orig, convert(fields[0])); 163 } else { 164 testLowerCase(orig, convert(fields[13])); 165 } 166 } 167 } 168 169 private void testUpperCase(String orig, String expected) { 170 String got = orig.toUpperCase(); 171 172 // Ugly workaround for special mappings for az and tr locales.... 173 if (orig.equals("\u0069") && 174 (defaultLang.equals("az") || defaultLang.equals("tr"))) { 175 expected = "\u0130"; 176 } 177 178 if (!expected.equals(got)) { 179 err = true; 180 System.err.println("toUpperCase(" + 181 ") failed.\n\tOriginal: " + toString(orig) + 182 "\n\tGot: " + toString(got) + 183 "\n\tExpected: " + toString(expected)); 184 } 185 } 186 187 private void testLowerCase(String orig, String expected) { 188 String got = orig.toLowerCase(); 189 // Ugly workaround for special mappings for az and tr locales.... 190 if (orig.equals("\u0049") && 191 (defaultLang.equals("az") || defaultLang.equals("tr"))) { 192 expected = "\u0131"; 193 } 194 195 if (!expected.equals(got)) { 196 err = true; 197 System.err.println("toLowerCase(" + 198 ") failed.\n\tOriginal: " + toString(orig) + 199 "\n\tGot: " + toString(got) + 200 "\n\tExpected: " + toString(expected)); 201 } 202 } 203 204 StringBuilder sb = new StringBuilder(); 205 206 private String convert(String str) { 207 sb.setLength(0); 208 209 String[] tokens = str.split(" "); 210 for (String token : tokens) { 211 int j = Integer.parseInt(token, 16); 212 if (j < Character.MIN_SUPPLEMENTARY_CODE_POINT) { 213 sb.append((char)j); 214 } else { 215 sb.append(Character.toChars(j)); 216 } 217 } 218 219 return sb.toString(); 220 } 221 222 private String toString(String str) { 223 sb.setLength(0); 224 225 int len = str.length(); 226 for (int i = 0; i < len; i++) { 227 sb.append("0x").append(Integer.toHexString(str.charAt(i)).toUpperCase()).append(" "); 228 } 229 230 return sb.toString(); 231 } 232 233 }