Skip to content

Commit b050631

Browse files
committed
Externalized strings
1 parent bf9b02f commit b050631

6 files changed

Lines changed: 112 additions & 30 deletions

File tree

README.md

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,15 @@
44

55
## Java Properties Manager
66

7-
JavaPM is a set of scripts for localizing Java projects using XLIFF as intermediate format.
7+
JavaPM is a set of scripts for localizing Java projects using XLIFF as an intermediate format.
8+
9+
JavaPM scans a source folder for all Java resource bundles and converts all source .properties files into a single XLIFF file.
10+
11+
After translating an XLIFF file created by JavaPM, import it to generate the .properties files corresponding to the target language.
12+
13+
## Binary downloads
14+
15+
You can download compressed binary packages for Windows, macOS and Linux from [https://maxprograms.com/products/javapm.html](https://maxprograms.com/products/javapm.html).
816

917
## Convert .properties to XLIFF
1018

@@ -37,15 +45,19 @@ Usage:
3745
3846
Where:
3947
40-
-help: (optional) display this help information and exit
41-
-src: source code folder
42-
-xliff: XLIFF file to merge
48+
-help: (optional) display this help information and exit
49+
-src: source code folder
50+
-xliff: XLIFF file to merge
51+
-unapproved: (optional) accept translations from unapproved segments
52+
-export: (optional) generate TMX file from approved segments
4353
```
4454

4555
## Build Requirements
4656

47-
- JDK 17 or newer is required for compiling and building. Pre-built binaries already include everything you need to run all options.
48-
- Apache Ant 1.10.12 or newer
57+
- JDK 17 or newer is required for compiling and building.
58+
- Apache Ant 1.10.12 or newer.
59+
60+
Pre-built binaries already include everything you need to run all options.
4961

5062
## Building
5163

lib/openxliff.jar

10 Bytes
Binary file not shown.

src/com/maxprograms/javapm/CreateXliff.java

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -79,15 +79,15 @@ public static void main(String[] args) {
7979
return;
8080
}
8181
if (srcFolder.isEmpty()) {
82-
logger.log(Level.ERROR, "Missing '-src' parameter");
82+
logger.log(Level.ERROR, Messages.getString("CreateXliff.0"));
8383
return;
8484
}
8585
if (xliff.isEmpty()) {
86-
logger.log(Level.ERROR, "Missing '-xliff' parameter");
86+
logger.log(Level.ERROR, Messages.getString("CreateXliff.1"));
8787
return;
8888
}
8989
if (srcLang.isEmpty()) {
90-
logger.log(Level.ERROR, "Missing '-srcLang' parameter");
90+
logger.log(Level.ERROR, Messages.getString("CreateXliff.2"));
9191
return;
9292
}
9393

@@ -102,28 +102,28 @@ private static void generateXliff(String src, String xliff, String srcLang, Stri
102102
boolean xliff2) throws IOException, SAXException, ParserConfigurationException {
103103
File srcFolder = new File(src);
104104
if (!srcFolder.exists()) {
105-
throw new IOException("'src' folder does not exist");
105+
throw new IOException(Messages.getString("CreateXliff.3"));
106106
}
107107
File catalogFolder = new File("catalog");
108108
if (!catalogFolder.exists()) {
109-
throw new IOException("'catalog' folder not found");
109+
throw new IOException(Messages.getString("CreateXliff.4"));
110110
}
111111
File catalog = new File(catalogFolder, "catalog.xml");
112112
if (!catalog.exists()) {
113-
throw new IOException("Catalog file does not exist");
113+
throw new IOException(Messages.getString("CreateXliff.5"));
114114
}
115115
File srxFolder = new File("srx");
116116
if (!srxFolder.exists()) {
117-
throw new IOException("'srx' folder not found");
117+
throw new IOException(Messages.getString("CreateXliff.6"));
118118
}
119119
File srx = new File(srxFolder, "default.srx");
120120
if (!srx.exists()) {
121-
throw new IOException("SRX file does not exist");
121+
throw new IOException(Messages.getString("CreateXliff.7"));
122122
}
123123
sourceFiles = new ArrayList<>();
124124
harvestProperties(srcFolder);
125125
if (sourceFiles.isEmpty()) {
126-
throw new IOException("There are no '.properties' files to process");
126+
throw new IOException(Messages.getString("CreateXliff.8"));
127127
}
128128
List<String> xliffs = new ArrayList<>();
129129
for (int i = 0; i < sourceFiles.size(); i++) {
@@ -221,8 +221,7 @@ private static void harvestProperties(File folder) throws IOException {
221221

222222
private static void help() {
223223
String launcher = File.separatorChar == '/' ? "createxliff.sh" : "createxliff.bat";
224-
MessageFormat mf = new MessageFormat(
225-
"Usage:\n\n {0} [-help] -src sourceFolder -xliff xliffFile -srcLang sourceLanguage [-enc characterSet] [-tgtLang targetLanguage] [-2.0]\n\nWhere:\n\n -help: (optional) display this help information and exit\n -src: source code folder\n -xliff: XLIFF file to generate\n -srcLang: source language code\n -enc: (optional) character set code for .properties files; default: ISO-8859-1\n -tgtLang: (optional) target language code\n -2.0: (optional) generate XLIFF 2.0\n\n");
224+
MessageFormat mf = new MessageFormat(Messages.getString("CreateXliff.9"));
226225
System.out.println(mf.format(new String[] { launcher }));
227226
}
228227
}

src/com/maxprograms/javapm/MergeXliff.java

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
import com.maxprograms.converters.Constants;
2626
import com.maxprograms.converters.Merge;
27+
import com.maxprograms.converters.TmxExporter;
2728
import com.maxprograms.converters.Utils;
2829
import com.maxprograms.xml.Document;
2930
import com.maxprograms.xml.Element;
@@ -38,6 +39,8 @@ public static void main(String[] args) {
3839
String[] arguments = Utils.fixPath(args);
3940
String srcFolder = "";
4041
String xliff = "";
42+
boolean unapproved = false;
43+
boolean exportTMX = false;
4144
for (int i = 0; i < arguments.length; i++) {
4245
String arg = arguments[i];
4346
if (arg.equals("-help")) {
@@ -50,49 +53,55 @@ public static void main(String[] args) {
5053
if (arg.equals("-xliff") && (i + 1) < arguments.length) {
5154
xliff = arguments[i + 1];
5255
}
56+
if (arg.equals("-unapproved")) {
57+
unapproved = true;
58+
}
59+
if (arg.equals("-export")) {
60+
exportTMX = true;
61+
}
5362
}
5463
if (arguments.length < 4) {
5564
help();
5665
return;
5766
}
5867
if (srcFolder.isEmpty()) {
59-
logger.log(Level.ERROR, "Missing '-src' parameter");
68+
logger.log(Level.ERROR, Messages.getString("MergeXliff.0"));
6069
return;
6170
}
6271
if (xliff.isEmpty()) {
63-
logger.log(Level.ERROR, "Missing '-xliff' parameter");
72+
logger.log(Level.ERROR, Messages.getString("MergeXliff.1"));
6473
return;
6574
}
6675
try {
67-
mergeXliff(srcFolder, xliff);
76+
mergeXliff(srcFolder, xliff, unapproved, exportTMX);
6877
} catch (IOException | SAXException | ParserConfigurationException e) {
6978
logger.log(Level.ERROR, e.getMessage(), e);
7079
}
7180
}
7281

73-
private static void mergeXliff(String src, String xliff)
82+
private static void mergeXliff(String src, String xliff, boolean unapproved, boolean exportTMX)
7483
throws IOException, SAXException, ParserConfigurationException {
7584
File srcFolder = new File(src);
7685
if (!srcFolder.exists()) {
7786
Files.createDirectories(srcFolder.toPath());
7887
}
7988
File catalogFolder = new File("catalog");
8089
if (!catalogFolder.exists()) {
81-
throw new IOException("'catalog' folder not found");
90+
throw new IOException(Messages.getString("MergeXliff.2"));
8291
}
8392
File catalog = new File(catalogFolder, "catalog.xml");
8493
if (!catalog.exists()) {
85-
throw new IOException("Catalog file does not exist");
94+
throw new IOException(Messages.getString("MergeXliff.3"));
8695
}
8796
File xliffFile = new File(xliff);
8897
if (!xliffFile.exists()) {
89-
throw new IOException("'xliff' file does not exist");
98+
throw new IOException(Messages.getString("MergeXliff.4"));
9099
}
91100
SAXBuilder builder = new SAXBuilder();
92101
Document doc = builder.build(xliffFile);
93102
Element root = doc.getRootElement();
94103
if (!"xliff".equals(root.getName())) {
95-
throw new IOException("Selected file is not an XLIFF document");
104+
throw new IOException(Messages.getString("MergeXliff.5"));
96105
}
97106
String tgtLang = "";
98107
if (root.getAttributeValue("version").startsWith("2.")) {
@@ -102,13 +111,26 @@ private static void mergeXliff(String src, String xliff)
102111
tgtLang = file.getAttributeValue("target-language");
103112
}
104113
if (tgtLang.isEmpty()) {
105-
throw new IOException("Target language not set");
114+
throw new IOException(Messages.getString("MergeXliff.6"));
106115
}
107116
xliffFile = processFiles(xliffFile, doc, tgtLang);
108-
List<String> result = Merge.merge(xliffFile.getAbsolutePath(), src, catalog.getAbsolutePath(), true);
117+
List<String> result = Merge.merge(xliffFile.getAbsolutePath(), src, catalog.getAbsolutePath(), unapproved);
109118
if (Constants.ERROR.equals(result.get(0))) {
110119
throw new IOException(result.get(1));
111120
}
121+
if (exportTMX) {
122+
String tmx = "";
123+
if (xliff.toLowerCase().endsWith(".xlf")) {
124+
tmx = xliff.substring(0, xliff.lastIndexOf('.')) + ".tmx";
125+
} else {
126+
tmx = xliff + ".tmx";
127+
}
128+
result = TmxExporter.export(xliffFile.getAbsolutePath(), tmx, catalog.getAbsolutePath());
129+
}
130+
if (!Constants.SUCCESS.equals(result.get(0))) {
131+
MessageFormat mf = new MessageFormat(Messages.getString("MergeXliff.7"));
132+
logger.log(Level.ERROR, mf.format(new String[] { result.get(1) }));
133+
}
112134
}
113135

114136
private static File processFiles(File xliffFile, Document doc, String tgtLang) throws IOException {
@@ -132,16 +154,15 @@ private static File processFiles(File xliffFile, Document doc, String tgtLang) t
132154
private static String updateOriginal(String original, String tgtLang) throws IOException {
133155
int index = original.lastIndexOf(".properties");
134156
if (index == -1) {
135-
throw new IOException("File is not a Java .properties bundle");
157+
throw new IOException(Messages.getString("MergeXliff.8"));
136158
}
137159
String name = original.substring(0, index);
138160
return name + "_" + tgtLang + ".properties";
139161
}
140162

141163
private static void help() {
142164
String launcher = File.separatorChar == '/' ? "mergexliff.sh" : "mergexliff.bat";
143-
MessageFormat mf = new MessageFormat(
144-
"Usage:\n\n {0} [-help] -src sourceFolder -xliff xliffFile\n\nWhere:\n\n -help: (optional) display this help information and exit\n -src: source code folder\n -xliff: XLIFF file to merge\n\n");
165+
MessageFormat mf = new MessageFormat(Messages.getString("MergeXliff.9"));
145166
System.out.println(mf.format(new String[] { launcher }));
146167
}
147168
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2023 Maxprograms.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License 1.0 which accompanies this distribution,
6+
* and is available at https://www.eclipse.org/org/documents/epl-v10.html
7+
*
8+
* Contributors: Maxprograms - initial API and implementation
9+
*******************************************************************************/
10+
package com.maxprograms.javapm;
11+
12+
import java.util.MissingResourceException;
13+
import java.util.ResourceBundle;
14+
15+
public class Messages {
16+
private static final String BUNDLE_NAME = Messages.class.getPackageName() + ".javapm"; //$NON-NLS-1$
17+
18+
private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME);
19+
20+
private Messages() {
21+
}
22+
23+
public static String getString(String key) {
24+
try {
25+
return RESOURCE_BUNDLE.getString(key);
26+
} catch (MissingResourceException e) {
27+
return '!' + key + '!';
28+
}
29+
}
30+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
CreateXliff.0=Missing '-src' parameter
2+
CreateXliff.1=Missing '-xliff' parameter
3+
CreateXliff.2=Missing '-srcLang' parameter
4+
CreateXliff.3='src' folder does not exist
5+
CreateXliff.4='catalog' folder not found
6+
CreateXliff.5=Catalog file does not exist
7+
CreateXliff.6='srx' folder not found
8+
CreateXliff.7=SRX file does not exist
9+
CreateXliff.8=There are no '.properties' files to process
10+
CreateXliff.9=Usage:\n\n {0} [-help] -src sourceFolder -xliff xliffFile -srcLang sourceLanguage [-enc characterSet] [-tgtLang targetLanguage] [-2.0]\n\nWhere:\n\n -help: (optional) display this help information and exit\n -src: source code folder\n -xliff: XLIFF file to generate\n -srcLang: source language code\n -enc: (optional) character set code for .properties files; default: ISO-8859-1\n -tgtLang: (optional) target language code\n -2.0: (optional) generate XLIFF 2.0\n\n
11+
MergeXliff.0=Missing '-src' parameter
12+
MergeXliff.1=Missing '-xliff' parameter
13+
MergeXliff.2='catalog' folder not found
14+
MergeXliff.3=Catalog file does not exist
15+
MergeXliff.4='xliff' file does not exist
16+
MergeXliff.5=Selected file is not an XLIFF document
17+
MergeXliff.6=Target language not set
18+
MergeXliff.7=Error exporting TMX: {0}
19+
MergeXliff.8=File is not a Java .properties bundle
20+
MergeXliff.9=Usage:\n\n {0} [-help] -src sourceFolder -xliff xliffFile [-unapproved] [-export]\n\nWhere:\n\n -help: (optional) display this help information and exit\n -src: source code folder\n -xliff: XLIFF file to merge\n -unapproved: (optional) accept translations from unapproved segments\n -export: (optional) generate TMX file from approved segments\n\n

0 commit comments

Comments
 (0)