1 /*
   2  * Copyright (c) 2003, 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 package build.tools.generatebreakiteratordata;
  27 
  28 import java.util.Enumeration;
  29 import java.util.ListResourceBundle;
  30 import java.util.Locale;
  31 import java.util.ResourceBundle;
  32 
  33 /**
  34  * Generates datafile for BreakIterator.
  35  */
  36 public class GenerateBreakIteratorData {
  37 
  38     /**
  39      * Directory where generated data files are put in.
  40      */
  41     private static String outputDir = "" ;
  42 
  43     /**
  44      * Unicode data file
  45      */
  46     private static String unicodeData = "UnicodeData.txt";
  47 
  48     /**
  49      * Locale data
  50      */
  51     private static String language = "";
  52     private static String country = "";
  53     private static String valiant = "";
  54     private static String localeName = "";  /* _language_country_valiant */
  55 
  56 
  57     public static void main(String[] args) {
  58         /* Parse command-line options */
  59         processArgs(args);
  60 
  61         /* Make categoryMap from Unicode data */
  62         CharacterCategory.makeCategoryMap(unicodeData);
  63 
  64         /* Generate files */
  65         try {
  66             generateFiles();
  67         } catch (Exception e) {
  68             e.printStackTrace();
  69             System.exit(1);
  70         }
  71     }
  72 
  73     private static String localizedBundleName(String pkg, String clazz) {
  74         if (language.length() > 0) {
  75             return pkg + ".ext." + clazz + '_' + language;
  76         } else {
  77             return pkg + '.' + clazz;
  78         }
  79     }
  80 
  81     /**
  82      * Generate data files whose names are included in
  83      * sun.text.resources.BreakIteratorInfo+<localeName>
  84      */
  85     private static void generateFiles() throws Exception {
  86         String[] classNames;
  87         ResourceBundle rules, info;
  88 
  89         info = (ResourceBundle) Class.forName(
  90             localizedBundleName("sun.text.resources", "BreakIteratorInfo")).getDeclaredConstructor().newInstance();
  91 
  92         classNames = info.getStringArray("BreakIteratorClasses");
  93 
  94         rules = (ResourceBundle) Class.forName(
  95             localizedBundleName("sun.text.resources", "BreakIteratorRules")).getDeclaredConstructor().newInstance();
  96 
  97         if (info.containsKey("CharacterData")) {
  98             generateDataFile(info.getString("CharacterData"),
  99                              rules.getString("CharacterBreakRules"),
 100                              classNames[0]);
 101         }
 102         if (info.containsKey("WordData")) {
 103             generateDataFile(info.getString("WordData"),
 104                              rules.getString("WordBreakRules"),
 105                              classNames[1]);
 106         }
 107         if (info.containsKey("LineData")) {
 108             generateDataFile(info.getString("LineData"),
 109                              rules.getString("LineBreakRules"),
 110                              classNames[2]);
 111         }
 112         if (info.containsKey("SentenceData")) {
 113             generateDataFile(info.getString("SentenceData"),
 114                              rules.getString("SentenceBreakRules"),
 115                              classNames[3]);
 116         }
 117     }
 118 
 119     /**
 120      * Generate a data file for break-iterator
 121      */
 122     private static void generateDataFile(String datafile, String rule, String builder) {
 123         RuleBasedBreakIteratorBuilder bld;
 124         if (builder.equals("RuleBasedBreakIterator")) {
 125             bld = new RuleBasedBreakIteratorBuilder(rule);
 126         } else if (builder.equals("DictionaryBasedBreakIterator")) {
 127             bld = new DictionaryBasedBreakIteratorBuilder(rule);
 128         } else {
 129             throw new IllegalArgumentException("Invalid break iterator class \"" + builder + "\"");
 130         }
 131 
 132         bld.makeFile(datafile);
 133     }
 134 
 135     /**
 136      * Parses the specified arguments and sets up the variables.
 137      */
 138     private static void processArgs(String[] args) {
 139         for (int i = 0; i < args.length; i++) {
 140             String arg = args[i];
 141             if (arg.equals("-o")) {
 142                 outputDir = args[++i];
 143             } else if (arg.equals("-spec")) {
 144                 unicodeData = args[++i];
 145             } else if (arg.equals("-language")) {
 146                 language = args[++i];
 147             } else if (arg.equals("-country")) {
 148                 country = args[++i];
 149             } else if (arg.equals("-valiant")) {
 150                 valiant = args[++i];
 151             } else {
 152                 usage();
 153             }
 154         }
 155 
 156         // Set locale name
 157         localeName = getLocaleName();
 158     }
 159 
 160     /**
 161      * Make locale name ("_language_country_valiant")
 162      */
 163     private static String getLocaleName() {
 164         if (language.equals("")) {
 165             if (!country.equals("") || !valiant.equals("")) {
 166                 language = "en";
 167             } else {
 168                 return "";
 169             }
 170         }
 171 
 172         StringBuffer sb = new StringBuffer();
 173         sb.append('_');
 174         sb.append(language);
 175         if (!country.equals("") || !valiant.equals("")) {
 176             sb.append('_');
 177             sb.append(country);
 178             if (!valiant.equals("")) {
 179                 sb.append('_');
 180                 sb.append(valiant);
 181             }
 182         }
 183 
 184         return sb.toString();
 185     }
 186 
 187     /**
 188      * Usage: Displayed when an invalid command-line option is specified.
 189      */
 190     private static void usage() {
 191         System.err.println("Usage: GenerateBreakIteratorData [options]\n" +
 192         "    -o outputDir                 output directory name\n" +
 193         "    -spec specname               unicode text filename\n" +
 194         "  and locale data:\n" +
 195         "    -lang language               target language name\n" +
 196         "    -country country             target country name\n" +
 197         "    -valiant valiant             target valiant name\n"
 198         );
 199     }
 200 
 201     /**
 202      * Return the path of output directory
 203      */
 204     static String getOutputDirectory() {
 205         return outputDir;
 206     }
 207 }