test/jdk/java/lang/Character/CheckBlocks.java
changeset 50230 cae567ae015d
parent 50229 6b29ef846c5c
child 50231 10b14c9ee78d
equal deleted inserted replaced
50229:6b29ef846c5c 50230:cae567ae015d
     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 }