Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/sourcetools/j9nls/com/ibm/oti/NLSTool/J9NLS.java
6004 views
1
/*******************************************************************************
2
* Copyright (c) 2004, 2019 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7
* or the Apache License, Version 2.0 which accompanies this distribution and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
20
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
21
*******************************************************************************/
22
package com.ibm.oti.NLSTool;
23
24
import java.io.BufferedReader;
25
import java.io.File;
26
import java.io.FileInputStream;
27
import java.io.FileNotFoundException;
28
import java.io.FileOutputStream;
29
import java.io.FileReader;
30
import java.io.FileWriter;
31
import java.io.IOException;
32
import java.util.Enumeration;
33
import java.util.Hashtable;
34
import java.util.Iterator;
35
import java.util.Properties;
36
import java.util.Vector;
37
import java.util.regex.Pattern;
38
39
public class J9NLS implements NLSConstants {
40
private static final int DIFFERENT_ORDER_FOUND = -1;
41
private Properties outputProperties;
42
private File palmResourceFile;
43
private FileWriter palmResourceWriter;
44
private Hashtable oldNLSFiles;
45
private Hashtable localeHashtable;
46
private Vector nlsInfos;
47
private int totalMessagesProcessed = 0;
48
private int totalNLSFilesFound = 0;
49
private int totalHeaderFilesCreated = 0;
50
private int totalHeaderFilesSkipped = 0;
51
private int totalPropertiesFilesCreated = 0;
52
private int totalPropertiesFilesSkipped = 0;
53
private int totalPalmFilesCreated = 0;
54
private int totalPalmFilesSkipped = 0;
55
private int messageNumber;
56
private int errorCount = 0;
57
private String workingDirectory = System.getProperty("user.dir");
58
private String sourceDirectory = System.getProperty("user.dir");
59
private String fileSeparator = System.getProperty("file.separator");
60
private String propertiesFileName = "java.properties"; // default
61
private String palmResourceFileName = "java.rc"; // default
62
private String htmlFileName = "properties.html"; // default
63
private String locale = DEFAULT_LOCALE;
64
private static boolean debugoutput = false;
65
66
public static void main(String[] args) {
67
J9NLS j9NLS = new J9NLS();
68
j9NLS.runMain(args);
69
}
70
71
public static void dp(String s){
72
if (debugoutput) {
73
System.out.println(s);
74
}
75
}
76
77
public J9NLS() {
78
}
79
80
private void runMain(String[] args) {
81
boolean palmMode = false;
82
boolean nohtml = false;
83
String outFileName;
84
85
for (int i = 0; i < args.length; i++) {
86
String arg = args[i];
87
if (arg.compareToIgnoreCase("-help") == 0) {
88
printUsage();
89
return;
90
} else if (arg.compareToIgnoreCase("-palm") == 0) {
91
palmMode = true;
92
} else if (arg.compareToIgnoreCase("-debug") == 0) {
93
debugoutput = true;
94
} else if (arg.compareToIgnoreCase("-nohtml") == 0) {
95
nohtml = true;
96
} else if (arg.compareToIgnoreCase("-out") == 0) {
97
if ((i + 1) >= args.length || args[i + 1].startsWith("-"))
98
failure("Output file name is not specified.");
99
else if (!(args[i + 1].endsWith(".rc") || args[i + 1].endsWith(".properties")))
100
failure("Output file name is not in correct format: " + args[i + 1]);
101
else
102
propertiesFileName = args[++i];
103
} else if (arg.compareToIgnoreCase("-html") == 0) {
104
if ((i + 1) >= args.length || args[i + 1].startsWith("-"))
105
failure("HTML file name is not specified.");
106
else if (!(args[i + 1].endsWith(".html") || args[i + 1].endsWith(".htm"))) {
107
failure("Output file name is not in correct format: " + args[i + 1]);
108
} else
109
htmlFileName = args[++i];
110
} else if (arg.compareToIgnoreCase("-source") == 0) {
111
if ((i + 1) >= args.length || args[i + 1].startsWith("-"))
112
failure("Source directory not specified");
113
File srcDir = new File(args[++i]);
114
if (!srcDir.exists() || ! srcDir.isDirectory())
115
failure("Source directory '" + srcDir + "' does not exist");
116
117
sourceDirectory = srcDir.getAbsolutePath();
118
} else {
119
failure("Unrecognized option: " + arg);
120
}
121
}
122
123
if (palmMode)
124
outFileName = palmResourceFileName;
125
else
126
outFileName = propertiesFileName;
127
128
nlsInfos = new Vector();
129
searchNLSFiles();
130
if (localeHashtable.size() < 1)
131
failure("Cannot find any NLS files below " + sourceDirectory);
132
133
try {
134
generatePropertiesFiles(outFileName, palmMode);
135
if (!nohtml)
136
new NLSHtmlGenerator().generateHTML(nlsInfos, outFileName, htmlFileName);
137
} catch (FileNotFoundException fnfe) {
138
if (debugoutput)
139
fnfe.printStackTrace();
140
failure("Caught exception: " + fnfe.getMessage(),true);
141
} catch (IOException e) {
142
if (debugoutput)
143
e.printStackTrace();
144
failure("Caught exception: " + e.getMessage(),true);
145
}
146
summarize();
147
}
148
149
private void generatePropertiesFiles(String outFileName, boolean palmMode) throws IOException, FileNotFoundException {
150
String moduleName, headerName;
151
FileOutputStream out = null;
152
Hashtable headerHashtable = new Hashtable();
153
Vector defaultNLSFiles = (Vector) localeHashtable.get(DEFAULT_LOCALE);
154
StringBuffer buffer = new StringBuffer();
155
156
// Create the output directory if it doesn't exist
157
File outputDir = new File(workingDirectory + fileSeparator + "nls");
158
if (!outputDir.exists()) {
159
dp("Output directory does not exist, creating it");
160
outputDir.mkdir();
161
}
162
163
for (Enumeration locales = localeHashtable.keys(); locales.hasMoreElements();) {
164
locale = (String) locales.nextElement();
165
Vector nlsFiles = (Vector) localeHashtable.get(locale);
166
dp("Processing " + nlsFiles.size() + " NLS files for " + getLocaleName(locale)
167
+ " locale");
168
169
if (!palmMode) {
170
outputProperties = new Properties();
171
}
172
173
for (int i = 0; i < nlsFiles.size(); i++) {
174
NLSInfo nlsInfo = null;
175
boolean newNLSInfo = false;
176
messageNumber = 0;
177
178
File nlsFile = (File) nlsFiles.elementAt(i);
179
String nlsPath = nlsFile.getPath();
180
Properties nlsProperties = new Properties();
181
java.io.FileInputStream strm = new java.io.FileInputStream(nlsPath);
182
nlsProperties.load(strm);
183
strm.close();
184
185
dp("Processing " + nlsPath);
186
187
validateKeys(nlsPath, nlsProperties);
188
189
moduleName = (String) nlsProperties.get(MODULE_KEY);
190
if (moduleName.length() != DEFAULT_MODULE_LENGTH)
191
failure("Module name must be exactly " + DEFAULT_MODULE_LENGTH + " characters long: "
192
+ moduleName);
193
194
String headerPath = workingDirectory + fileSeparator + "nls" + fileSeparator;
195
headerName = (String) nlsProperties.get(HEADER_KEY);
196
197
nlsInfo = findNLSInfo(nlsInfos, moduleName, headerName);
198
if (nlsInfo.getModule() == null)
199
newNLSInfo = true;
200
nlsInfo.setModule(moduleName);
201
nlsInfo.setPath(nlsPath.substring((sourceDirectory + fileSeparator).length()));
202
nlsInfo.setHeaderName(headerName);
203
nlsInfo.addLocale(locale);
204
205
HeaderBuffer headerBuffer = new HeaderBuffer(headerName, nlsFile.getName());
206
headerBuffer.writeHeader(headerName, moduleName);
207
208
compareWithOld(nlsFile, nlsProperties);
209
compareWithDefault(nlsFile, nlsProperties, defaultNLSFiles);
210
211
Iterator keyIterator = getOrderedKeys(nlsProperties, nlsFile).iterator();
212
Vector msgInfos = new Vector();
213
while (keyIterator.hasNext()) {
214
if (messageNumber >= MAX_NUMBER_OF_MESSAGES_PER_MODULE)
215
failure(moduleName + " has more messages than the max limit of "
216
+ MAX_NUMBER_OF_MESSAGES_PER_MODULE);
217
String key = (String) keyIterator.next();
218
if (nlsProperties.containsKey(key)) {
219
String formattedMsgNumber = formatMsgNumber(messageNumber);
220
String msg = (String) nlsProperties.get(key);
221
if ((!msg.equals("")) || (locale!="")){
222
if (palmMode) {
223
byte[] utf8Msg = msg.getBytes("UTF-8");
224
buffer.append("HEX \"" + moduleName + "\" ID " + formattedMsgNumber
225
+ " " + toHexString(utf8Msg) + "\n");
226
} else {
227
outputProperties.setProperty(moduleName + formattedMsgNumber, msg);
228
}
229
}
230
msgInfos
231
.addElement(createMsgInfo(moduleName + formattedMsgNumber, key, msg, nlsProperties));
232
233
if (msg.equals("")) {
234
headerBuffer.append("#define " + key + "__PREFIX \"" + moduleName + formattedMsgNumber
235
+ "\"\n");
236
} else {
237
headerBuffer.appendMsg(moduleName, key);
238
}
239
messageNumber++;
240
}
241
}
242
243
nlsInfo.setMsgInfo(msgInfos);
244
dp(messageNumber + " messages processed from " + nlsPath);
245
totalMessagesProcessed += messageNumber;
246
headerBuffer.append("\n#endif\n");
247
248
if (newNLSInfo)
249
nlsInfos.addElement(nlsInfo);
250
251
if (DEFAULT_LOCALE.equals(locale)) {
252
/* only output the header once (for the default locale) */
253
generateHeaderFile(headerHashtable, nlsFile, headerPath, headerBuffer);
254
}
255
}
256
257
//check if file already exists on the file system
258
//if found, compare it with the generated file; if the same, do not overwrite it
259
//if the file does not exists, write it to disk
260
if (palmMode) {
261
palmResourceFile = new File(getNameWithLocale(outFileName, locale));
262
if (differentFromCopyOnDisk(getNameWithLocale(outFileName, locale), buffer)) {
263
palmResourceWriter = new FileWriter(palmResourceFile);
264
palmResourceWriter.write(buffer.toString());
265
palmResourceWriter.close();
266
dp("** Generated " + palmResourceFileName + "\n");
267
totalPalmFilesCreated++;
268
} else {
269
dp("** Skipped writing [same as on file system]: " + palmResourceFile);
270
totalPalmFilesSkipped++;
271
}
272
} else {
273
String fileName = getNameWithLocale(outFileName, locale);
274
if (propertiesDifferentFromCopyOnDisk(fileName)) {
275
out = new FileOutputStream(fileName);
276
outputProperties.store(out, null);
277
out.flush();
278
dp("** Generated " + fileName + "\n");
279
totalPropertiesFilesCreated++;
280
} else {
281
dp("** Skipped writing [same as on file system]: " + fileName);
282
totalPropertiesFilesSkipped++;
283
}
284
}
285
286
if (null != out) {
287
out.close();
288
}
289
}
290
}
291
292
private MsgInfo createMsgInfo(String macro, String key, String msg, Properties nlsProperties) {
293
MsgInfo msgInfo = new MsgInfo();
294
msgInfo.setMacro(macro);
295
msgInfo.setKey(key);
296
msgInfo.setMsg(msg);
297
msgInfo.setId(messageNumber);
298
msgInfo.setExplanation(nlsProperties.getProperty(key + SUFFIX_EXPLANATION));
299
msgInfo.setSystemAction(nlsProperties.getProperty(key + SUFFIX_SYSTEM_ACTION));
300
msgInfo.setUserResponse(nlsProperties.getProperty(key + SUFFIX_USER_RESPONSE));
301
return msgInfo;
302
}
303
304
/**
305
* @param nlsPath
306
* @param nlsProperties
307
*/
308
private void validateKeys(String nlsPath, Properties nlsProperties) {
309
if (!nlsProperties.containsKey(MODULE_KEY))
310
failure("Module name not found in " + nlsPath + " file");
311
312
if (!nlsProperties.containsKey(HEADER_KEY))
313
failure("Header file name not found in " + nlsPath + " file");
314
315
for (Enumeration keys = nlsProperties.keys(); keys.hasMoreElements();) {
316
String key = (String) keys.nextElement();
317
318
if (isSpecialKey(key)) {
319
String entry = key.substring(0, key.indexOf('.'));
320
321
if (MODULE_KEY.equals(key)) {
322
// no validation of this key
323
} else if (HEADER_KEY.equals(key)) {
324
// no validation of this key
325
} else {
326
if (!nlsProperties.containsKey(entry)) {
327
failure(key + " has no corresponding NLS entry", false);
328
}
329
if (
330
key.endsWith(SUFFIX_EXPLANATION)
331
|| key.endsWith(SUFFIX_SYSTEM_ACTION)
332
|| key.endsWith(SUFFIX_USER_RESPONSE)
333
|| key.endsWith(SUFFIX_LINK)
334
|| Pattern.matches(".*\\.sample_input_[1-9][0-9]*", key))
335
{
336
// key is valid
337
} else {
338
failure(key + " is an unrecognized special key. ", false);
339
340
}
341
}
342
}
343
}
344
345
}
346
347
private NLSInfo findNLSInfo(Vector nlsInfos, String moduleName, String headerName) {
348
for (Enumeration e = nlsInfos.elements(); e.hasMoreElements();) {
349
NLSInfo nlsInfo = (NLSInfo) e.nextElement();
350
if (nlsInfo.isSameNLS(moduleName, headerName))
351
return nlsInfo;
352
}
353
return new NLSInfo();
354
}
355
356
private void compareWithOld(File nlsFile, Properties nlsProperties) throws IOException, FileNotFoundException {
357
Vector orderedKeys = getOrderedKeys(nlsProperties, nlsFile);
358
if (oldNLSFiles.containsKey(nlsFile.getName() + ".old")) {
359
File oldNLSFile = (File) oldNLSFiles.get(nlsFile.getName() + ".old");
360
Properties oldNLSProperties = new Properties();
361
java.io.FileInputStream strm = new java.io.FileInputStream(oldNLSFile.getPath());
362
oldNLSProperties.load(strm);
363
strm.close();
364
Vector oldOrderedKeys = getOrderedKeys(oldNLSProperties, oldNLSFile);
365
dp("Comparing with " + oldNLSFile.getPath());
366
int compareOrders = compareOrder(oldOrderedKeys, orderedKeys);
367
if (compareOrders == DIFFERENT_ORDER_FOUND) {
368
failure("Old messages in " + nlsFile.getPath() + " are different from the ones in "
369
+ oldNLSFile.getPath(), false);
370
} else if (compareOrders != 0)
371
dp(" Found " + compareOrders + " new message(s) in " + nlsFile.getPath());
372
else
373
dp(" They are identical to each other.");
374
}
375
}
376
377
private void compareWithDefault(File nlsFile, Properties nlsProperties, Vector defaultNLSFiles)
378
throws FileNotFoundException, IOException {
379
File defaultNLSFile = findDefault(nlsFile, defaultNLSFiles);
380
Properties defaultNLSProperties = new Properties();
381
FileInputStream strm = new java.io.FileInputStream(defaultNLSFile.getPath());
382
defaultNLSProperties.load(strm);
383
strm.close();
384
Vector defaultOrderedKeys = getOrderedKeys(defaultNLSProperties, defaultNLSFile);
385
Vector defaultMessages = getValuesForKeys(defaultOrderedKeys, defaultNLSFile);
386
Vector nlsMessages = getValuesForKeys(defaultOrderedKeys, nlsFile);
387
Iterator nlsKeys = defaultOrderedKeys.iterator();
388
Iterator defaultIterator = defaultMessages.iterator();
389
Iterator nlsIterator = nlsMessages.iterator();
390
while (defaultIterator.hasNext()) {
391
String key = (String)nlsKeys.next();
392
String defaultMessage = (String) defaultIterator.next();
393
String nlsMessage = (String) nlsIterator.next();
394
if (!"".equals(defaultMessage) && null != nlsMessage) {
395
if (false == formatSpecifiersAreEquivalent(defaultMessage, nlsMessage))
396
failure(key + " Message \"" + nlsMessage + "\" in " + nlsFile.getPath() + " is different from \""
397
+ defaultMessage + "\" in " + defaultNLSFile.getPath(), false);
398
}
399
}
400
}
401
402
private File findDefault(File nlsFile, Vector defaultNLSFiles) {
403
String nlsFileName = nlsFile.getName();
404
String defaultNLSFileName = ((nlsFileName.lastIndexOf('_') != -1) ? nlsFileName.substring(0, nlsFileName
405
.indexOf('_')) : nlsFileName.substring(0, nlsFileName.lastIndexOf('.')))
406
+ DEFAULT_LOCALE + nlsFileName.substring(nlsFileName.lastIndexOf('.'));
407
Iterator i = defaultNLSFiles.iterator();
408
while (i.hasNext()) {
409
File f = (File) i.next();
410
if (f != null && f.getName().equals(defaultNLSFileName)) {
411
return f;
412
}
413
}
414
return null;
415
}
416
417
private boolean formatSpecifiersAreEquivalent(String oldMessage, String newMessage) {
418
boolean reorderable = false;
419
Vector oldFormatSpec = formatSpecifiersOf(oldMessage);
420
Vector newFormatSpec = formatSpecifiersOf(newMessage);
421
422
if (newFormatSpec.size() != oldFormatSpec.size()) {
423
return false;
424
}
425
426
/*
427
* If the format specifiers contain $ signs, then the specifiers may
428
* appear in any order within the string. Detect if $ signs are being
429
* used to decide how the list of specifiers ought to be compared.
430
*/
431
for (Iterator iter = oldFormatSpec.iterator(); iter.hasNext();) {
432
String spec = (String) iter.next();
433
if (spec.indexOf('$') != -1) {
434
reorderable = true;
435
break;
436
}
437
}
438
439
if (reorderable) {
440
for (Iterator iter = oldFormatSpec.iterator(); iter.hasNext();) {
441
String spec = (String)iter.next();
442
if (spec.indexOf('$') == -1) {
443
failure("\"" + oldMessage + "\" includes a mix of ordered and unordered format sepcifiers", false);
444
}
445
if (!newFormatSpec.remove(spec)) {
446
return false;
447
}
448
}
449
return true;
450
} else {
451
return oldFormatSpec.equals(newFormatSpec);
452
}
453
}
454
455
private Vector formatSpecifiersOf(String s) {
456
Vector result = new Vector();
457
458
if (null == s)
459
return result;
460
461
StringBuffer buf = new StringBuffer();
462
int e = s.length();
463
int state = 0;
464
for (int i = 0; i < e; ++i) {
465
char c = s.charAt(i);
466
switch (state) {
467
case 0:
468
if ('%' == c)
469
state = 1;
470
break;
471
case 1:
472
if ('%' == c) {
473
state = 0;
474
break;
475
}
476
buf.append('%');
477
state = 2;
478
// FALLTHRU
479
case 2:
480
if ("pcsxXuidf".indexOf(c) != -1) {
481
if ('p' == c)
482
buf.append("zx");
483
else if ("csxf".indexOf(c) != -1)
484
buf.append(c);
485
else
486
buf.append('x');
487
result.add(buf.toString());
488
buf = new StringBuffer();
489
state = 0;
490
} else {
491
buf.append(c);
492
}
493
break;
494
default:
495
failure("unknown error extracting format specifiers from " + s);
496
}
497
}
498
499
return result;
500
}
501
502
private Vector getValuesForKeys(Vector keys, File nlsFile) throws FileNotFoundException, IOException {
503
String nlsPath = nlsFile.getPath();
504
Properties nlsProperties = new Properties();
505
java.io.FileInputStream strm = new java.io.FileInputStream(nlsPath);
506
nlsProperties.load(strm);
507
strm.close();
508
509
Vector values = new Vector();
510
Iterator i = keys.iterator();
511
while (i.hasNext()) {
512
values.addElement(nlsProperties.get(i.next()));
513
}
514
return values;
515
}
516
517
private boolean isSpecialKey(String key) {
518
return key.indexOf('.') >= 0;
519
}
520
521
private int compareOrder(Vector oldOrderedKeys, Vector orderedKeys) {
522
Iterator iterator = orderedKeys.iterator();
523
Iterator oldIterator = oldOrderedKeys.iterator();
524
String key, oldKey;
525
while (oldIterator.hasNext()) {
526
if (!iterator.hasNext())
527
return DIFFERENT_ORDER_FOUND;
528
else {
529
key = (String) iterator.next();
530
oldKey = (String) oldIterator.next();
531
if (!key.equals(oldKey)) {
532
dp("Mismatch found: " + key + ", " + oldKey);
533
return DIFFERENT_ORDER_FOUND;
534
}
535
}
536
}
537
int toReturn = 0;
538
while (iterator.hasNext()) {
539
iterator.next();
540
toReturn++;
541
}
542
return toReturn;
543
}
544
545
private void generateHeaderFile(Hashtable headerHashtable, File nlsFile, String headerPath,
546
HeaderBuffer headerBuffer) throws IOException,FileNotFoundException {
547
if (!headerHashtable.containsKey(headerBuffer.getHeaderName())) {
548
549
StringBuffer buffer = new StringBuffer();
550
buffer.append(headerBuffer.toString());
551
552
if (differentFromCopyOnDisk(headerPath + headerBuffer.getHeaderName(), buffer)){
553
File headerFile = new File(headerPath + headerBuffer.getHeaderName());
554
FileWriter headerFileWriter = new FileWriter(headerFile);
555
headerFileWriter.write(headerBuffer.toString());
556
headerHashtable.put(headerPath + headerBuffer.getHeaderName(), headerBuffer);
557
headerFileWriter.close();
558
dp("** Generated " + headerFile.getPath());
559
totalHeaderFilesCreated++;
560
}else{
561
totalHeaderFilesSkipped++;
562
dp("** Skipped writing [same as on file system]: " + headerPath + headerBuffer.getHeaderName());
563
}
564
} else {
565
HeaderBuffer oldBuffer = (HeaderBuffer) headerHashtable.get(headerBuffer.getHeaderName());
566
if (!oldBuffer.equals(headerBuffer))
567
failure("Header files generated from " + oldBuffer.getNLSFileName() + " and " + nlsFile.getName()
568
+ " do not match");
569
headerBuffer.clear();
570
}
571
}
572
573
protected Hashtable searchNLSFiles() {
574
dp("Searching for nls files...");
575
Vector dirToSearch = new Vector();
576
oldNLSFiles = new Hashtable();
577
localeHashtable = new Hashtable();
578
dirToSearch.addElement(new File(sourceDirectory + fileSeparator + "nls" + fileSeparator));
579
String files[];
580
581
while (dirToSearch.size() > 0) {
582
File dir = (File) dirToSearch.elementAt(0);
583
dirToSearch.remove(0);
584
if (!dir.exists() || ! dir.isDirectory()) {
585
failure("Failed to open directory - " + dir);
586
}
587
files = dir.list();
588
for (int i = 0; i < files.length; i++) {
589
File file = new File(dir, files[i]);
590
if (file.isDirectory())
591
dirToSearch.insertElementAt(file, 0);
592
else if (file.getName().endsWith(".nls")) {
593
dp("Found " + file.getPath());
594
String locale = getLocale(file.getName());
595
if (!localeHashtable.containsKey(locale)) {
596
dp("Found a new locale: " + getLocaleName(locale));
597
Vector temp = new Vector();
598
temp.add(file);
599
localeHashtable.put(locale, temp);
600
} else {
601
((Vector) localeHashtable.get(locale)).add(file);
602
}
603
totalNLSFilesFound++;
604
} else if (file.getName().endsWith(".nls.old")) {
605
dp("Found " + file.getPath());
606
oldNLSFiles.put(file.getName(), file);
607
}
608
}
609
}
610
dp("");
611
612
return localeHashtable;
613
}
614
615
private String getKey(String line) {
616
if (line.indexOf('=') != -1)
617
return line.substring(0, line.indexOf('='));
618
else
619
return null;
620
}
621
622
protected Vector getOrderedKeys(Properties nlsProperties, File nlsFile) throws IOException {
623
Vector keys = new Vector();
624
FileReader nlsFileReader = new FileReader(nlsFile);
625
BufferedReader bufferedNLSReader = new BufferedReader(nlsFileReader);
626
String line;
627
while ((line = bufferedNLSReader.readLine()) != null) {
628
String key = getKey(line);
629
if (key != null && !isSpecialKey(key)) {
630
if (keys.contains(key))
631
failure("Duplicate keys are found in " + nlsFile.getPath() + ": " + key, false);
632
if (nlsProperties.containsKey(key))
633
keys.add(key);
634
}
635
}
636
bufferedNLSReader.close();
637
638
return keys;
639
}
640
641
private String getNameWithLocale(String fileName, String locale) {
642
return workingDirectory + fileSeparator + fileName.substring(0, propertiesFileName.lastIndexOf('.')) + locale
643
+ fileName.substring(propertiesFileName.lastIndexOf('.'));
644
}
645
646
protected String formatMsgNumber(int msgNumber) {
647
String currentMsgNumber = String.valueOf(msgNumber);
648
while (currentMsgNumber.length() < DEFAULT_MESSAGE_NUMBER_LENGTH)
649
currentMsgNumber = "0" + currentMsgNumber;
650
return currentMsgNumber;
651
}
652
653
private String getLocale(String nlsFileName) {
654
if (nlsFileName.lastIndexOf('_') != -1)
655
return nlsFileName.substring(nlsFileName.indexOf('_'), nlsFileName.lastIndexOf("."));
656
else
657
return DEFAULT_LOCALE;
658
}
659
660
private String getLocaleName(String locale) {
661
if (locale.equals(DEFAULT_LOCALE))
662
return "\'default\'";
663
else
664
return "\'" + locale.substring(1) + "\'";
665
}
666
667
private void summarize() {
668
System.out.println("\n************************************************\n");
669
System.out.println("\tTotal # of locales processed:\t\t" + localeHashtable.size());
670
System.out.println("\tTotal # of NLS Files processed:\t\t" + totalNLSFilesFound);
671
System.out.println("\tTotal # of messages processed:\t\t" + totalMessagesProcessed + "\n");
672
System.out.println("\tTotal # of header files generated:\t" + totalHeaderFilesCreated);
673
if (totalHeaderFilesSkipped > 0) {
674
System.out.println("\tTotal # of unchanged header files:\t" + totalHeaderFilesSkipped);
675
}
676
System.out.println("\tTotal # of properties files generated:\t" + totalPropertiesFilesCreated);
677
if (totalPropertiesFilesSkipped > 0) {
678
System.out.println("\tTotal # of unchanged properties files:\t" + totalPropertiesFilesSkipped);
679
}
680
if (totalPalmFilesCreated > 0) {
681
System.out.println("\tTotal # of palm files generated:\t" + totalPalmFilesCreated);
682
}
683
if (totalPalmFilesSkipped > 0) {
684
System.out.println("\tTotal # of unchanged palm files:\t" + totalPalmFilesSkipped);
685
}
686
System.out.println("\tTotal # of errors:\t\t\t" + errorCount);
687
System.out.println("\n************************************************\n");
688
689
if (errorCount > 0) {
690
System.exit(1);
691
}
692
}
693
694
private void printUsage() {
695
System.out.println("J9 NLS Tool 1.2");
696
System.out.println("Usage: J9NLS [options]\n");
697
System.out.println("[options]");
698
System.out.println(" -help prints this message");
699
System.out.println(" -out xxx generates output named as xxx");
700
System.out.println(" -source path to the source directory");
701
System.out.println(" -[no]html xxx [do not] generates HTML file, which contains output results, named as xxx");
702
System.out.println(" -palm generates output as Palm resources\n");
703
System.out.println(" -debug generates informational output\n");
704
System.out.println("Defaults are:");
705
System.out.println(" -out " + propertiesFileName + "-html" + htmlFileName);
706
System.out.println(" -source . ");
707
}
708
709
private void failure(String msg) {
710
failure(msg, true);
711
}
712
713
private void failure(String msg, boolean fatal) {
714
System.out.println("\n* Failure occured during the process *");
715
System.out.println("Error: " + msg);
716
errorCount++;
717
if (fatal) {
718
summarize();
719
}
720
}
721
722
private class HeaderBuffer {
723
StringBuffer buffer;
724
String headerName;
725
String NLSFileName;
726
727
public HeaderBuffer(String headerName, String NLSFileName) {
728
this.headerName = headerName;
729
this.NLSFileName = NLSFileName;
730
buffer = new StringBuffer("");
731
}
732
733
public String toString() {
734
return buffer.toString();
735
}
736
737
public boolean equals(Object arg) {
738
HeaderBuffer other = (HeaderBuffer) arg;
739
if (null != other) {
740
return other.buffer.toString().equals(buffer.toString());
741
}
742
return super.equals(arg);
743
}
744
745
public void append(String s) {
746
buffer.append(s);
747
}
748
749
public void clear() {
750
buffer.delete(0, buffer.length());
751
}
752
753
public String getHeaderName() {
754
return headerName;
755
}
756
757
public String getNLSFileName() {
758
return NLSFileName;
759
}
760
761
private String getAscii(String moduleName) {
762
String asciiModuleName = "0x";
763
for (int i = 0; i < moduleName.length(); i++)
764
asciiModuleName += Integer.toHexString(moduleName.charAt(i));
765
return asciiModuleName;
766
}
767
768
public void appendMsg(String moduleName, String key) {
769
String defModule = key + "__MODULE";
770
String defID = key + "__ID";
771
append("#define " + defModule + " " + getAscii(moduleName) + "\n");
772
append("#define " + defID + " " + messageNumber + "\n");
773
append("#define " + key + " " + defModule + ", " + defID + "\n");
774
}
775
776
public void writeHeader(String headerName, String moduleName) {
777
String header = headerName.replace('.', '_');
778
append("/*\n");
779
append(" * Copyright (c) 1991, 2017 IBM Corp. and others\n");
780
append(" *\n");
781
append(" * This program and the accompanying materials are made available under\n");
782
append(" * the terms of the Eclipse Public License 2.0 which accompanies this\n");
783
append(" * distribution and is available at https://www.eclipse.org/legal/epl-2.0/\n");
784
append(" * or the Apache License, Version 2.0 which accompanies this distribution and\n");
785
append(" * is available at https://www.apache.org/licenses/LICENSE-2.0.\n");
786
append(" *\n");
787
append(" * This Source Code may also be made available under the following\n");
788
append(" * Secondary Licenses when the conditions for such availability set\n");
789
append(" * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU\n");
790
append(" * General Public License, version 2 with the GNU Classpath\n");
791
append(" * Exception [1] and GNU General Public License, version 2 with the\n");
792
append(" * OpenJDK Assembly Exception [2].\n");
793
append(" *\n");
794
append(" * [1] https://www.gnu.org/software/classpath/license.html\n");
795
append(" * [2] http://openjdk.java.net/legal/assembly-exception.html\n");
796
append(" *\n");
797
append(" * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception\n");
798
append(" */\n\n");
799
append("#ifndef " + header + "\n");
800
append("#define " + header + "\n\n");
801
append("#include \"j9port.h\"\n");
802
append("/* " + getAscii(moduleName) + " = " + moduleName + " */\n\n");
803
}
804
}
805
806
private String toHexString(byte[] b) {
807
final char[] hexChar = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
808
StringBuffer stringBuffer = new StringBuffer();
809
for (int i = 0; i < b.length; i++) {
810
stringBuffer.append("0x");
811
stringBuffer.append(hexChar[(b[i] & 0xf0) >>> 4]);
812
stringBuffer.append(hexChar[b[i] & 0x0f]);
813
stringBuffer.append(' ');
814
}
815
return stringBuffer.toString();
816
}
817
818
/**
819
* Checks if a file with given name exists on disk. Returns true if it does
820
* not exist. If the file exists, compares it with generated buffer and
821
* returns true if they are equals. Also it deletes old file from the file
822
* system.
823
*
824
* @param fileName
825
* @param buffer
826
* @return boolean TRUE|FALSE
827
* @throws FileNotFoundException
828
* @throws IOException
829
*/
830
public static boolean differentFromCopyOnDisk(String fileName, StringBuffer buffer) throws FileNotFoundException, IOException{
831
File fileOnDisk = new File (fileName);
832
if (!fileOnDisk.exists()){
833
return true;
834
}
835
836
StringBuffer fileBuffer = new StringBuffer();
837
FileReader fr = new FileReader(fileOnDisk);
838
char []charArray = new char[1024];
839
840
int numRead = -1;
841
while ( (numRead = fr.read(charArray)) != -1 ) {
842
fileBuffer.append(charArray, 0, numRead);
843
}
844
845
if ( buffer.toString().equals(fileBuffer.toString()) ) {
846
fr.close();
847
return false;
848
}
849
850
fr.close();
851
852
//delete file here, will write new file later
853
fileOnDisk.delete();
854
855
return true;
856
}
857
858
/**
859
* Compares given properties file with the generated properties.
860
* Returns true if they do not match, otherwise returns false.
861
* It also deletes the file from the file system, if it exists.
862
*
863
* @param fileName
864
* @return boolean TRUE|FALSE
865
* @throws FileNotFoundException
866
* @throws IOException
867
*/
868
private boolean propertiesDifferentFromCopyOnDisk(String fileName) throws FileNotFoundException, IOException{
869
File fileOnDisk = new File(fileName);
870
if (!fileOnDisk.exists()) {
871
return true;
872
}
873
874
//load the file
875
Properties oldProperties = new Properties();
876
FileInputStream in = new FileInputStream(fileOnDisk);
877
oldProperties.load(in);
878
in.close();
879
880
boolean isDifferent = false;
881
if (!oldProperties.keySet().equals(outputProperties.keySet())){
882
isDifferent = true;
883
}else{
884
//compare messages
885
Iterator keyIterator = oldProperties.keySet().iterator();
886
while (keyIterator.hasNext()){
887
if (!outputProperties.containsValue(oldProperties.getProperty(String.valueOf(keyIterator.next())))){
888
isDifferent = true;
889
break;
890
}
891
}
892
}
893
894
if (isDifferent) {
895
//delete old file here, will generate new file later
896
fileOnDisk.delete();
897
}
898
899
return isDifferent;
900
}
901
}
902
903