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 4830803 4886934 6565620 6959267 7070436 7198195 8032446 8072600 29 * @summary Check that the UnicodeBlock forName() method works as expected and block ranges are correct for all Unicode characters. 30 * @run main CheckBlocks 31 * @author John O'Conner 32 */ 33 34 import java.io.*; 35 import java.util.*; 36 import java.lang.Character.UnicodeBlock; 37 38 39 public class CheckBlocks { 40 41 static boolean err = false; 42 static Class<?> character; 43 44 public static void main(String[] args) throws Exception { 45 generateBlockList(); 46 47 try { 48 character = Class.forName("java.lang.Character$UnicodeBlock"); 49 } catch (ClassNotFoundException e) { 50 throw new RuntimeException("Class.forName(\"Character\") failed."); 51 } 52 53 for (Block blk : blocks) { 54 test4830803_1(blk); 55 test4830803_2(); 56 test4886934(blk); 57 } 58 59 if (err) { 60 throw new RuntimeException("Failed"); 61 } else { 62 System.out.println("Passed"); 63 } 64 } 65 66 /** 67 * Check that the UnicodeBlock forName() method works as expected. 68 */ 69 private static void test4830803_1(Block blk) throws Exception { 70 71 /* 72 * Try 3 forms of block name in the forName() method. Each form should 73 * produce the same expected block. 74 */ 75 String blkName = blk.getName(); 76 77 // For backward compatibility 78 if (blkName.equals("COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS")) { 79 blkName = "COMBINING_MARKS_FOR_SYMBOLS"; 80 System.out.println("*** COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS is replaced with COMBINING_MARKS_FOR_SYMBOLS for backward compatibility."); 81 } else if (blkName.equals("GREEK_AND_COPTIC")) { 82 blkName = "GREEK"; 83 System.out.println("*** GREEK_AND_COPTIC is replaced with GREEK for backward compatibility."); 84 } else if (blkName.equals("CYRILLIC_SUPPLEMENT")) { 85 blkName = "CYRILLIC_SUPPLEMENTARY"; 86 System.out.println("*** CYRILLIC_SUPPLEMENT is replaced with CYRILLIC_SUPPLEMENTARY for backward compatibility."); 87 } 88 89 String expectedBlock = null; 90 try { 91 expectedBlock = character.getField(blkName).getName(); 92 } catch (NoSuchFieldException | SecurityException e) { 93 System.err.println("Error: " + blkName + " was not found."); 94 err = true; 95 return; 96 } 97 98 String canonicalBlockName = blk.getOriginalName(); 99 String idBlockName = expectedBlock; 100 String regexBlockName = toRegExString(canonicalBlockName); 101 102 if (regexBlockName == null) { 103 System.err.println("Error: Block name which was processed with regex was null."); 104 err = true; 105 return; 106 } 107 108 if (!expectedBlock.equals(UnicodeBlock.forName(canonicalBlockName).toString())) { 109 System.err.println("Error #1: UnicodeBlock.forName(\"" + 110 canonicalBlockName + "\") returned wrong value.\n\tGot: " + 111 UnicodeBlock.forName(canonicalBlockName) + 112 "\n\tExpected: " + expectedBlock); 113 err = true; 114 } 115 116 if (!expectedBlock.equals(UnicodeBlock.forName(idBlockName).toString())) { 117 System.err.println("Error #2: UnicodeBlock.forName(\"" + 118 idBlockName + "\") returned wrong value.\n\tGot: " + 119 UnicodeBlock.forName(idBlockName) + 120 "\n\tExpected: " + expectedBlock); 121 err = true; 122 } 123 124 if (!expectedBlock.equals(UnicodeBlock.forName(regexBlockName).toString())) { 125 System.err.println("Error #3: UnicodeBlock.forName(\"" + 126 regexBlockName + "\") returned wrong value.\n\tGot: " + 127 UnicodeBlock.forName(regexBlockName) + 128 "\n\tExpected: " + expectedBlock); 129 err = true; 130 } 131 } 132 133 /** 134 * now try a bad block name. This should produce an IAE. 135 */ 136 private static void test4830803_2() { 137 boolean threwExpected = false; 138 139 try { 140 UnicodeBlock block = UnicodeBlock.forName("notdefined"); 141 } 142 catch(IllegalArgumentException e) { 143 threwExpected = true; 144 } 145 146 if (threwExpected == false) { 147 System.err.println("Error: UnicodeBlock.forName(\"notdefined\") should throw IllegalArgumentException."); 148 err = true; 149 } 150 } 151 152 /** 153 * Convert the argument to a block name form used by the regex package. 154 * That is, remove all spaces. 155 */ 156 private static String toRegExString(String str) { 157 String[] tokens = null; 158 StringBuilder retStr = new StringBuilder(); 159 try { 160 tokens = str.split(" "); 161 } 162 catch(java.util.regex.PatternSyntaxException e) { 163 return null; 164 } 165 for(int x=0; x < tokens.length; ++x) { 166 retStr.append(tokens[x]); 167 } 168 return retStr.toString(); 169 } 170 171 private static void test4886934(Block blk) { 172 String blkName = blk.getName(); 173 String blkOrigName = blk.getOriginalName(); 174 int ch = blk.getBegin(); 175 UnicodeBlock block = UnicodeBlock.of(ch); 176 177 if (block == null) { 178 System.err.println("Error: The block for " + blkName + 179 " is missing. Please check java.lang.Character.UnicodeBlock."); 180 err = true; 181 return; 182 } 183 184 // For backward compatibility 185 if (blkName.equals("COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS")) { 186 blkName = "COMBINING_MARKS_FOR_SYMBOLS"; 187 System.out.println("*** COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS is replaced with COMBINING_MARKS_FOR_SYMBOLS for backward compatibility."); 188 } else if (blkName.equals("GREEK_AND_COPTIC")) { 189 blkName = "GREEK"; 190 System.out.println("*** GREEK_AND_COPTIC is replaced with GREEK for backward compatibility."); 191 } else if (blkName.equals("CYRILLIC_SUPPLEMENT")) { 192 blkName = "CYRILLIC_SUPPLEMENTARY"; 193 System.out.println("*** CYRILLIC_SUPPLEMENT is replaced with CYRILLIC_SUPPLEMENTARY for backward compatibility."); 194 } 195 196 String blockName = block.toString(); 197 if (!blockName.equals(blkName)) { 198 System.err.println("Error: Begin-of-block character(0x" + 199 Integer.toHexString(ch).toUpperCase() + 200 ") should be in \"" + blkName + "\" block " + 201 "(Block name is \"" + blkOrigName + "\")" + 202 " but found in \"" + blockName + "\" block."); 203 err = true; 204 } 205 206 block = UnicodeBlock.of(++ch); 207 blockName = block.toString(); 208 if (!blockName.equals(blkName)) { 209 System.err.println("Error: Character(0x" + 210 Integer.toHexString(ch).toUpperCase() + 211 ") should be in \"" + blkName + "\" block " + 212 "(Block name is \"" + blkOrigName + "\")" + 213 " but found in \"" + blockName + "\" block."); 214 err = true; 215 } 216 217 ch = blk.getEnd(); 218 block = UnicodeBlock.of(ch); 219 blockName = block.toString(); 220 if (!blockName.equals(blkName)) { 221 System.err.println("Error: End-of-block Character(0x" + 222 Integer.toHexString(ch).toUpperCase() + 223 ") should be in \"" + blkName + "\" block " + 224 "(Block name is \"" + blkOrigName + "\")" + 225 " but found in \"" + blockName + "\" block."); 226 err = true; 227 } 228 } 229 230 // List of all Unicode blocks, their start, and end codepoints. 231 public static HashSet<Block> blocks = new HashSet<>(); 232 233 private static void generateBlockList() throws Exception { 234 BufferedReader f = new BufferedReader(new FileReader(new File(System.getProperty("test.src", "."), "Blocks.txt"))); 235 236 String line; 237 while ((line = f.readLine()) != null) { 238 if (line.length() == 0 || line.charAt(0) == '#') { 239 continue; 240 } 241 242 int index1 = line.indexOf('.'); 243 int begin = Integer.parseInt(line.substring(0, index1), 16); 244 int index2 = line.indexOf(';'); 245 int end = Integer.parseInt(line.substring(index1+2, index2), 16); 246 String name = line.substring(index2+1).trim(); 247 248 System.out.println(" Adding a Block(" + 249 Integer.toHexString(begin) + ", " + Integer.toHexString(end) + 250 ", " + name + ")"); 251 blocks.add(new Block(begin, end, name)); 252 } 253 f.close(); 254 } 255 } 256 257 class Block { 258 259 public Block() { 260 blockBegin = 0; 261 blockEnd = 0; 262 blockName = null; 263 } 264 265 public Block(int begin, int end, String name) { 266 blockBegin = begin; 267 blockEnd = end; 268 blockName = name.replaceAll("[ -]", "_").toUpperCase(Locale.ENGLISH); 269 originalBlockName = name; 270 } 271 272 public int getBegin() { 273 return blockBegin; 274 } 275 276 public int getEnd() { 277 return blockEnd; 278 } 279 280 public String getName() { 281 return blockName; 282 } 283 284 public String getOriginalName() { 285 return originalBlockName; 286 } 287 288 @Override 289 public boolean equals(Object obj) { 290 if (obj == null) return false; 291 if (!(obj instanceof Block)) return false; 292 293 Block other = (Block)obj; 294 return other.blockBegin == blockBegin && 295 other.blockEnd == blockEnd && 296 other.blockName.equals(blockName) && 297 other.originalBlockName.equals(originalBlockName); 298 } 299 int blockBegin, blockEnd; 300 String blockName, originalBlockName; 301 }