Files
JIMRI/java/test/jmri/util/i18n/PropertiesMergeTool.java
2026-06-17 14:00:51 +02:00

119 lines
4.6 KiB
Java

/**
* A command line tool to maintain properties files for translation.
* Takes the names of two properties files. The first is the master, default
* English version, and the second is a partially translated file.
*
* When run, the program will re-write the 2nd file with
* All the key/value pairs in the order they appear in the first file
* With k/v pairs missing in the 2nd file filled out with the k/v from the first file.
*
* Effectively, this puts English into the 2nd file for later translation, while
* maintaining the files in the same order for readability.
*
* Note that comments in the 2nd file are not preserved. If desired, those have
* to be added back in by hand. Also note that multi-line values will be
* converted to a single (perhaps very long) values.
*
* Usage:
* java java/test/jmri/util/i18n/PropertiesMergeTool.java java/src/jmri/NamedBeanBundle.properties java/src/jmri/NamedBeanBundle_es.properties
*/
package jmri.util.i18n;
import java.util.*;
import java.io.*;
class PropertiesMergeTool {
public static void main(String[] args) {
if (args.length < 2) {
System.err.println("Needs two file names");
return;
}
try {
var stream1 = new FileInputStream(args[0]);
var stream2 = new FileInputStream(args[1]);
ResourceBundle bundle1 = new PropertyResourceBundle(stream1);
ResourceBundle bundle2 = new PropertyResourceBundle(stream2);
// now that bundle is read, open same file for output
outFile = new File(args[1]);
outWriter = new FileWriter(outFile);
// put pathname at top of output file
outWriter.write("# "+args[1]+"\n");
// Apparently there's no way to address these in order, so we separately
// read the file to do that.
File inFile = new File(args[0]);
try (var fileReader = new BufferedReader(new FileReader(inFile))) {
// process every line
for(String line; (line = fileReader.readLine()) != null; ) {
// decode line types
int index;
if (line.startsWith("#")) {
writeOutLine(line);
} else if ((index = line.indexOf("=")) >= 0) {
String part1 = line.substring(0, index);
String key = part1.trim();
var lookUpKey = key.replace("\\", "");
String part2 = line.substring(index+1);
StringBuilder pad = new StringBuilder();
// pad with same number of leading spaces
while (part2.startsWith(" ") || part2.startsWith("\t")) {
pad.append(part2.substring(0,1));
part2 = part2.substring(1);
}
// check if translation in 2nd file
if (bundle2.containsKey(key)) {
// write translated value
writeOutLine(part1+"="+pad.toString()+bundle2.getString(lookUpKey));
} else {
// write untranslated value
writeOutLine(part1+"="+pad.toString()+bundle1.getString(lookUpKey));
}
} else if (isBlankLine(line)) {
// blank line
writeOutLine("");
} else {
// don't understand the line, so skip it
// usually part of multiline output
}
}
}
// done, flush and close output
outWriter.close();
} catch (IOException e) {
System.err.println("IOException: "+e);
e.printStackTrace();
} finally {
try {
if (outWriter != null) outWriter.close();
} catch (IOException ex) {
System.err.println("exception closing output");
}
}
}
public static boolean isBlankLine(String line) {
while (line.startsWith(" ")) {
line = line.substring(1);
}
return line.isEmpty();
}
private static File outFile = null;
private static Writer outWriter = null;
public static void writeOutLine(String line) throws IOException {
// double \ characters to have them go through explicitly
var literalLine = line.replaceAll("\\n", "\\\\n");
literalLine = literalLine.replaceAll("\\r", "\\\\r");
outWriter.write(literalLine+"\n");
}
}