Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/make/src/classes/build/tools/generatelsrequivmaps/EquivMapsGenerator.java
32287 views
1
/*
2
* Copyright (c) 2012, 2017, 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.generatelsrequivmaps;
27
28
import java.io.BufferedWriter;
29
import java.io.IOException;
30
import java.nio.charset.Charset;
31
import java.nio.charset.StandardCharsets;
32
import java.nio.file.Files;
33
import java.nio.file.Paths;
34
import java.util.ArrayList;
35
import java.util.Calendar;
36
import java.util.List;
37
import java.util.Locale;
38
import java.util.Map;
39
import java.util.TimeZone;
40
import java.util.TreeMap;
41
42
/**
43
* This tool reads the IANA Language Subtag Registry data file downloaded from
44
* http://www.iana.org/assignments/language-subtag-registry, which is specified
45
* in the command line and generates a .java source file as specified in
46
* command line. The generated .java source file contains equivalent language
47
* maps. These equivalent language maps are used by LocaleMatcher.java
48
* for the locale matching mechanism specified in RFC 4647 "Matching of Language
49
* Tags".
50
*/
51
public class EquivMapsGenerator {
52
53
public static void main(String[] args) throws Exception {
54
if (args.length != 2) {
55
System.err.println("Usage: java EquivMapsGenerator"
56
+ " language-subtag-registry.txt LocaleEquivalentMaps.java");
57
System.exit(1);
58
}
59
readLSRfile(args[0]);
60
generateEquivalentMap();
61
generateSourceCode(args[1]);
62
}
63
64
private static String LSRrevisionDate;
65
private static Map<String, StringBuilder> initialLanguageMap =
66
new TreeMap<>();
67
private static Map<String, StringBuilder> initialRegionVariantMap =
68
new TreeMap<>();
69
70
private static Map<String, String> sortedLanguageMap1 = new TreeMap<>();
71
private static Map<String, String[]> sortedLanguageMap2 = new TreeMap<>();
72
private static Map<String, String> sortedRegionVariantMap =
73
new TreeMap<>();
74
75
private static void readLSRfile(String filename) throws Exception {
76
String type = null;
77
String tag = null;
78
String preferred = null;
79
80
for (String line : Files.readAllLines(Paths.get(filename),
81
Charset.forName("UTF-8"))) {
82
line = line.toLowerCase(Locale.ROOT);
83
int index = line.indexOf(' ')+1;
84
if (line.startsWith("file-date:")) {
85
LSRrevisionDate = line.substring(index);
86
} else if (line.startsWith("type:")) {
87
type = line.substring(index);
88
} else if (line.startsWith("tag:") || line.startsWith("subtag:")) {
89
tag = line.substring(index);
90
} else if (line.startsWith("preferred-value:")
91
&& !type.equals("extlang")) {
92
preferred = line.substring(index);
93
processDeprecatedData(type, tag, preferred);
94
} else if (line.equals("%%")) {
95
type = null;
96
tag = null;
97
}
98
}
99
}
100
101
private static void processDeprecatedData(String type,
102
String tag,
103
String preferred) {
104
StringBuilder sb;
105
if (type.equals("region") || type.equals("variant")) {
106
if (!initialRegionVariantMap.containsKey(preferred)) {
107
sb = new StringBuilder("-");
108
sb.append(preferred);
109
sb.append(",-");
110
sb.append(tag);
111
initialRegionVariantMap.put("-"+preferred, sb);
112
} else {
113
throw new RuntimeException("New case, need implementation."
114
+ " A region/variant subtag \"" + preferred
115
+ "\" is registered for more than one subtags.");
116
}
117
} else { // language, grandfahered, and redundant
118
if (!initialLanguageMap.containsKey(preferred)) {
119
sb = new StringBuilder(preferred);
120
sb.append(',');
121
sb.append(tag);
122
initialLanguageMap.put(preferred, sb);
123
} else {
124
sb = initialLanguageMap.get(preferred);
125
sb.append(',');
126
sb.append(tag);
127
initialLanguageMap.put(preferred, sb);
128
}
129
}
130
}
131
132
private static void generateEquivalentMap() {
133
String[] subtags;
134
for (String preferred : initialLanguageMap.keySet()) {
135
subtags = initialLanguageMap.get(preferred).toString().split(",");
136
137
if (subtags.length == 2) {
138
sortedLanguageMap1.put(subtags[0], subtags[1]);
139
sortedLanguageMap1.put(subtags[1], subtags[0]);
140
} else if (subtags.length > 2) {
141
for (int i = 0; i < subtags.length; i++) {
142
sortedLanguageMap2.put(subtags[i], createLangArray(i, subtags));
143
}
144
} else {
145
throw new RuntimeException("New case, need implementation."
146
+ " A language subtag \"" + preferred
147
+ "\" is registered for more than two subtags. ");
148
}
149
}
150
151
for (String preferred : initialRegionVariantMap.keySet()) {
152
subtags =
153
initialRegionVariantMap.get(preferred).toString().split(",");
154
155
sortedRegionVariantMap.put(subtags[0], subtags[1]);
156
sortedRegionVariantMap.put(subtags[1], subtags[0]);
157
}
158
159
}
160
161
/* create the array of subtags excluding the subtag at index location */
162
private static String[] createLangArray(int index, String[] subtags) {
163
List<String> list = new ArrayList<>();
164
for (int i = 0; i < subtags.length; i++) {
165
if (i != index) {
166
list.add(subtags[i]);
167
}
168
}
169
return list.toArray(new String[list.size()]);
170
}
171
172
private static String generateValuesString(String[] values) {
173
String outputStr = "";
174
for (int i = 0; i < values.length; i++) {
175
if (i != values.length - 1) {
176
outputStr = outputStr + "\"" + values[i] + "\", ";
177
} else {
178
outputStr = outputStr + "\"" + values[i] + "\"";
179
}
180
181
}
182
return outputStr;
183
}
184
185
private static final String COPYRIGHT = "/*\n"
186
+ " * Copyright (c) 2012, %d, Oracle and/or its affiliates. All rights reserved.\n"
187
+ " * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n"
188
+ " *\n"
189
+ " * This code is free software; you can redistribute it and/or modify it\n"
190
+ " * under the terms of the GNU General Public License version 2 only, as\n"
191
+ " * published by the Free Software Foundation. Oracle designates this\n"
192
+ " * particular file as subject to the \"Classpath\" exception as provided\n"
193
+ " * by Oracle in the LICENSE file that accompanied this code.\n"
194
+ " *\n"
195
+ " * This code is distributed in the hope that it will be useful, but WITHOUT\n"
196
+ " * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n"
197
+ " * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n"
198
+ " * version 2 for more details (a copy is included in the LICENSE file that\n"
199
+ " * accompanied this code).\n"
200
+ " *\n"
201
+ " * You should have received a copy of the GNU General Public License version\n"
202
+ " * 2 along with this work; if not, write to the Free Software Foundation,\n"
203
+ " * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n"
204
+ " *\n"
205
+ " * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n"
206
+ " * or visit www.oracle.com if you need additional information or have any\n"
207
+ " * questions.\n"
208
+ "*/\n\n";
209
210
private static final String headerText =
211
"package sun.util.locale;\n\n"
212
+ "import java.util.HashMap;\n"
213
+ "import java.util.Map;\n\n"
214
+ "final class LocaleEquivalentMaps {\n\n"
215
+ " static final Map<String, String> singleEquivMap;\n"
216
+ " static final Map<String, String[]> multiEquivsMap;\n"
217
+ " static final Map<String, String> regionVariantEquivMap;\n\n"
218
+ " static {\n"
219
+ " singleEquivMap = new HashMap<>();\n"
220
+ " multiEquivsMap = new HashMap<>();\n"
221
+ " regionVariantEquivMap = new HashMap<>();\n\n"
222
+ " // This is an auto-generated file and should not be manually edited.\n";
223
224
private static final String footerText =
225
" }\n\n"
226
+ "}";
227
228
private static String getOpenJDKCopyright() {
229
int year = Calendar.getInstance(TimeZone
230
.getTimeZone("America/Los_Angeles")).get(Calendar.YEAR);
231
return String.format(Locale.US, COPYRIGHT, year);
232
}
233
234
/**
235
* The input lsr data file is in UTF-8, so theoretically for the characters
236
* beyond US-ASCII, the generated Java String literals need to be Unicode
237
* escaped (\\uXXXX) while writing to a file. But as of now, there is not
238
* the case since we don't use "description", "comment" or alike.
239
*/
240
private static void generateSourceCode(String fileName) {
241
242
try (BufferedWriter writer = Files.newBufferedWriter(
243
Paths.get(fileName), StandardCharsets.UTF_8)) {
244
writer.write(getOpenJDKCopyright());
245
writer.write(headerText
246
+ " // LSR Revision: " + LSRrevisionDate);
247
writer.newLine();
248
249
for (String key : sortedLanguageMap1.keySet()) {
250
String value = sortedLanguageMap1.get(key);
251
writer.write(" singleEquivMap.put(\""
252
+ key + "\", \"" + value + "\");");
253
writer.newLine();
254
}
255
256
writer.newLine();
257
for (String key : sortedLanguageMap2.keySet()) {
258
String[] values = sortedLanguageMap2.get(key);
259
260
if (values.length >= 2) {
261
writer.write(" multiEquivsMap.put(\""
262
+ key + "\", new String[] {"
263
+ generateValuesString(values) + "});");
264
writer.newLine();
265
}
266
}
267
268
writer.newLine();
269
for (String key : sortedRegionVariantMap.keySet()) {
270
String value = sortedRegionVariantMap.get(key);
271
writer.write(" regionVariantEquivMap.put(\""
272
+ key + "\", \"" + value + "\");");
273
writer.newLine();
274
}
275
276
writer.write(footerText);
277
} catch (IOException ex) {
278
ex.printStackTrace(System.err);
279
System.exit(1);
280
}
281
282
}
283
284
}
285
286