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
26package build.tools.charsetmapping;
27
28import java.io.*;
29import java.util.Locale;
30import java.util.ArrayList;
31import java.util.LinkedHashMap;
32import java.util.Scanner;
33
34public 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 String[] aliases_%s() { return null; }%n%n",
97                                            cs.clzName);
98                             } else {
99                                 boolean methodEnd = true;
100                                 // non-final for SJIS and MS932 to support sun.nio.cs.map
101                                 if (cs.clzName.equals("SJIS") || cs.clzName.equals("MS932")) {
102                                     out.printf("    static String[] aliases_%s() { return aliases_%s; }%n%n",
103                                                cs.clzName, cs.clzName);
104                                     out.printf("    static String[] aliases_%s = new String[] {%n",
105                                                cs.clzName);
106                                     methodEnd = false;
107                                 } else {
108                                     out.printf("    static String[] aliases_%s() { return new String[] {%n",
109                                                cs.clzName);
110                                 }
111                                 for (String alias : cs.aliases) {
112                                     out.printf("            \"%s\",%n", alias);
113                                 }
114                                 out.printf("        };%n%n");
115                                 if (methodEnd) {
116                                     out.printf("    }%n%n");
117                                 }
118                             }
119                         });
120                         Charset cs = charsets.get("SJIS");
121                         if (cs == null || cs.pkgName.equals("sun.nio.cs.ext")) {
122                              // StandardCharsets.java has explicit reference
123                              // to aliases_SJIS/MS932. If we don't have these
124                              // two in std, just put a pair of dummy fields to
125                              // make the compiler happy.
126                              out.printf("    static String[] aliases_SJIS = null;%n%n");
127                              out.printf("    static String[] aliases_MS932 = null;%n%n");
128                         }
129                     } else if (line.indexOf("_INCLUDE_ALIASES_MAP_") != -1) {
130                         Hasher.genClass(out, aliasKeys, aliasValues,
131                                         null, "Aliases", "String",
132                                         11, 3, true, false, false);
133                     } else if (line.indexOf("_INCLUDE_CLASSES_MAP_") != -1) {
134                         Hasher.genClass(out, clzKeys, clzValues,
135                                         null, "Classes", "String",
136                                         11, 3, true, false, false);
137                     } else if (line.indexOf("_INCLUDE_CACHE_MAP_") != -1) {
138                         Hasher.genClass(out, clzKeys, clzValues,
139                                         null, "Cache", "Charset",
140                                         11, 3, true, true, false);
141                     } else {
142                         out.println(line);
143                     }
144                }
145            } else {
146                throw new RuntimeException("Unknown type:" + type);
147            }
148        }
149
150    }
151}
152