1 /*
   2  * Copyright (c) 2015, 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.charsetmapping;
  27 
  28 import java.io.*;
  29 import java.util.Locale;
  30 import java.util.ArrayList;
  31 import java.util.LinkedHashMap;
  32 import java.util.Scanner;
  33 
  34 public class SPI {
  35 
  36     public static void genClass(String type,
  37                                 LinkedHashMap<String, Charset> charsets,
  38                                 String srcDir, String dstDir, String template,
  39                                 String os)
  40         throws Exception
  41     {
  42         try (Scanner s = new Scanner(new File(template));
  43              PrintStream out = new PrintStream(new FileOutputStream(
  44                  new File(dstDir, new File(
  45                      template.replace(".template", "")).getName()))); ) {
  46             if (type.startsWith("extcs")) {           // ExtendedCharsets.java
  47                 while (s.hasNextLine()) {
  48                     String line = s.nextLine();
  49                     if (line.indexOf("_CHARSETS_DEF_LIST_") == -1) {
  50                         out.println(line);
  51                     } else {
  52                         charsets.values()
  53                                 .stream()
  54                                 .filter(cs -> cs.pkgName.equals("sun.nio.cs.ext") &&
  55                                               !cs.isInternal &&
  56                                               (cs.os == null || cs.os.equals(os)))
  57                                 .forEach( cs -> {
  58                             out.printf("        charset(\"%s\", \"%s\",%n", cs.csName, cs.clzName);
  59                             out.printf("                new String[] {%n");
  60                             for (String alias : cs.aliases) {
  61                                 out.printf("                    \"%s\",%n", alias);
  62                             }
  63                             out.printf("                });%n%n");
  64                         });
  65                     }
  66                 }
  67             } else if (type.startsWith("stdcs")) {    // StandardCharsets.java
  68                  ArrayList<String> aliasKeys = new ArrayList<>();
  69                  ArrayList<String> aliasValues = new ArrayList<>();
  70                  ArrayList<String> clzKeys = new ArrayList<>();
  71                  ArrayList<String> clzValues = new ArrayList<>();
  72                  charsets.values()
  73                          .stream()
  74                          .filter(cs -> cs.pkgName.equals("sun.nio.cs") &&
  75                                        !cs.isInternal)
  76                          .forEach( cs -> {
  77                      String csname = cs.csName.toLowerCase(Locale.ENGLISH);
  78                      clzKeys.add(csname);
  79                      clzValues.add("\"" + cs.clzName + "\"");
  80                      if (cs.aliases != null) {
  81                          csname = "\"" + csname + "\"";
  82                          for (String alias : cs.aliases) {
  83                              aliasKeys.add(alias.toLowerCase(Locale.ENGLISH));
  84                              aliasValues.add(csname);
  85                          }
  86                      }
  87                  });
  88                  while (s.hasNextLine()) {
  89                      String line = s.nextLine();
  90                      if (line.indexOf("_INCLUDE_ALIASES_TABLES_") != -1) {
  91                          charsets.values()
  92                                  .stream()
  93                                  .filter(cs -> cs.pkgName.equals("sun.nio.cs"))
  94                                  .forEach( cs -> {
  95                              if (cs.aliases == null || cs.aliases.length == 0) {
  96                                  out.printf("    static final String[] aliases_%s = null;%n%n",
  97                                             cs.clzName);
  98                              } else {
  99                                  // non-final for SJIS and MS932 to support sun.nio.cs.map
 100                                  if (cs.clzName.equals("SJIS") || cs.clzName.equals("MS932")) {
 101                                      out.printf("    static String[] aliases_%s = new String[] {%n",
 102                                                 cs.clzName);
 103                                  } else {
 104                                      out.printf("    static final String[] aliases_%s = new String[] {%n",
 105                                                 cs.clzName);
 106                                  }
 107                                  for (String alias : cs.aliases) {
 108                                      out.printf("        \"%s\",%n", alias);
 109                                  }
 110                                  out.printf("    };%n%n");
 111                              }
 112                          });
 113                          Charset cs = charsets.get("SJIS");
 114                          if (cs == null || cs.pkgName.equals("sun.nio.cs.ext")) {
 115                               // StandardCharsets.java has explicit reference
 116                               // to aliases_SJIS/MS932. If we don't have these
 117                               // two in std, just put a pair of dummy fields to
 118                               // make the compiler happy.
 119                               out.printf("    static String[] aliases_SJIS = null;%n%n");
 120                               out.printf("    static String[] aliases_MS932 = null;%n%n");
 121                          }
 122                      } else if (line.indexOf("_INCLUDE_ALIASES_MAP_") != -1) {
 123                          Hasher.genClass(out, aliasKeys, aliasValues,
 124                                          null, "Aliases", "String",
 125                                          11, 3, true, false, false);
 126                      } else if (line.indexOf("_INCLUDE_CLASSES_MAP_") != -1) {
 127                          Hasher.genClass(out, clzKeys, clzValues,
 128                                          null, "Classes", "String",
 129                                          11, 3, true, false, false);
 130                      } else if (line.indexOf("_INCLUDE_CACHE_MAP_") != -1) {
 131                          Hasher.genClass(out, clzKeys, clzValues,
 132                                          null, "Cache", "Charset",
 133                                          11, 3, true, true, false);
 134                      } else {
 135                          out.println(line);
 136                      }
 137                 }
 138             } else {
 139                 throw new RuntimeException("Unknown type:" + type);
 140             }
 141         }
 142 
 143     }
 144 }