Skip to content

Commit f89b577

Browse files
authored
Merge pull request #59 from JCEmmons/issue42
Add logic to write comments from Java properties. Fixes #42.
2 parents 8aa26a0 + 510054e commit f89b577

4 files changed

Lines changed: 125 additions & 30 deletions

File tree

gp-res-filter/src/main/java/com/ibm/g11n/pipeline/resfilter/JavaPropertiesResource.java

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright IBM Corp. 2015, 2016
2+
* Copyright IBM Corp. 2015, 2017
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@
2525
import java.text.BreakIterator;
2626
import java.util.ArrayList;
2727
import java.util.Collections;
28+
import java.util.Date;
2829
import java.util.Enumeration;
2930
import java.util.HashMap;
3031
import java.util.HashSet;
@@ -41,7 +42,7 @@
4142
/**
4243
* Java properties resource filter implementation.
4344
*
44-
* @author Yoshito Umaoka
45+
* @author Yoshito Umaoka, JCEmmons
4546
*/
4647
public class JavaPropertiesResource implements ResourceFilter {
4748

@@ -161,11 +162,19 @@ public void write(OutputStream outStream, String language, Bundle resource) thro
161162
TreeSet<ResourceString> sortedResources = new TreeSet<>(new ResourceStringComparator());
162163
sortedResources.addAll(resource.getResourceStrings());
163164

164-
LinkedProperties props = new LinkedProperties();
165+
PrintWriter pw = new PrintWriter(new OutputStreamWriter(outStream, PROPS_ENC));
166+
for (String note : resource.getNotes()) {
167+
pw.println("#"+note);
168+
}
169+
if (!resource.getNotes().isEmpty()) {
170+
pw.println();
171+
}
172+
pw.println("#"+new Date().toString());
165173
for (ResourceString res : sortedResources) {
166-
props.setProperty(res.getKey(), res.getValue());
174+
PropDef pd = new PropDef(res.getKey(),res.getValue(),PropDef.PropSeparator.EQUAL,res.getNotes());
175+
pd.print(pw, language);
167176
}
168-
props.store(outStream, null);
177+
pw.close();
169178
}
170179

171180
private static final String PROPS_ENC = "ISO-8859-1";
@@ -174,7 +183,8 @@ static class PropDef {
174183
private String key;
175184
private String value;
176185
private PropSeparator separator;
177-
186+
private List<String> notes;
187+
178188
public enum PropSeparator {
179189
EQUAL('='), COLON(':'), SPACE(' ');
180190

@@ -192,10 +202,23 @@ public char getCharacter() {
192202
private static final String INDENT = " ";
193203
private static final int COLMAX = 80;
194204

205+
public PropDef(String key, String value, PropSeparator separator, List<String> notes) {
206+
this.key = key;
207+
this.value = value;
208+
this.separator = separator;
209+
if (notes != null) {
210+
this.notes = new ArrayList<>();
211+
this.notes.addAll(notes);
212+
} else {
213+
this.notes = null;
214+
}
215+
};
216+
195217
public PropDef(String key, String value, PropSeparator separator) {
196218
this.key = key;
197219
this.value = value;
198220
this.separator = separator;
221+
this.notes = null;
199222
};
200223

201224
public static PropDef parseLine(String line) {
@@ -239,7 +262,7 @@ public static PropDef parseLine(String line) {
239262
String key = unescapePropKey(line.substring(0, sepIdx).trim());
240263
String value = unescapePropValue(stripLeadingSpaces(line.substring(sepIdx + 1)));
241264

242-
PropDef pl = new PropDef(key, value, sep);
265+
PropDef pl = new PropDef(key, value, sep, null);
243266
return pl;
244267
}
245268

@@ -255,11 +278,22 @@ public PropSeparator getSeparator() {
255278
return separator;
256279
}
257280

281+
public List<String> getNotes() {
282+
return Collections.unmodifiableList(notes);
283+
}
284+
258285
public void print(PrintWriter pw, String language) throws IOException {
259286
StringBuilder buf = new StringBuilder(100);
260287
int len = key.length() + value.length()
261288
+ 3; /* 3 - length of separator plus two SPs */
262289

290+
// Write out any notes (comments) associated with this resource.
291+
if (notes != null) {
292+
for (String note : notes) {
293+
pw.println("#" + note);
294+
}
295+
}
296+
263297
if (len <= COLMAX) {
264298
// Print this property in a single line
265299
if (separator.getCharacter() == PropSeparator.SPACE.getCharacter()) {
@@ -290,7 +324,9 @@ public void print(PrintWriter pw, String language) throws IOException {
290324
buf.append(INDENT);
291325
}
292326

293-
BreakIterator brk = BreakIterator.getWordInstance(Locale.forLanguageTag(language));
327+
328+
BreakIterator brk = BreakIterator.getWordInstance(
329+
language == null ? Locale.getDefault() : Locale.forLanguageTag(language));
294330
brk.setText(value);
295331

296332
int start = 0;
@@ -355,6 +391,8 @@ public String toString() {
355391
builder.append(getValue());
356392
builder.append(" Sep=");
357393
builder.append("'" + getSeparator().getCharacter() + "'");
394+
builder.append(" Notes=");
395+
builder.append(getNotes().toString());
358396
return builder.toString();
359397
}
360398
}
@@ -611,7 +649,7 @@ public void merge(InputStream base, OutputStream outStream, String language, Bun
611649
}
612650
// Write the property key and value
613651
String key = pd.getKey();
614-
PropDef modPd = new PropDef(key, resMap.get(key), pd.getSeparator());
652+
PropDef modPd = new PropDef(key, resMap.get(key), pd.getSeparator(), null);
615653
modPd.print(outWriter, language);
616654
} else {
617655
if (orgLines.isEmpty()) {

gp-res-filter/src/test/java/com/ibm/g11n/pipeline/resfilter/JavaPropertiesResourceTest.java

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright IBM Corp. 2016
2+
* Copyright IBM Corp. 2016, 2017
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -40,7 +40,7 @@
4040
import com.ibm.g11n.pipeline.resfilter.ResourceString.ResourceStringComparator;
4141

4242
/**
43-
* @author Farhan Arshad
43+
* @author Farhan Arshad, JCEmmons
4444
*
4545
*/
4646
public class JavaPropertiesResourceTest {
@@ -95,14 +95,28 @@ public class JavaPropertiesResourceTest {
9595
WRITE_BUNDLE = new Bundle();
9696
WRITE_BUNDLE.addResourceString("language", "Not-English", 2);
9797
WRITE_BUNDLE.addResourceString("key with spaces",
98-
"Translated - This is the value that could be looked up with the key \"key with spaces\".", 4);
98+
"Translated - This is the value that could be looked up with the key \"key with spaces\".", 4,
99+
Arrays.asList(" Add spaces to the key"));
99100
WRITE_BUNDLE.addResourceString("website", "http://en.wikipedia.org/translated", 1);
100-
WRITE_BUNDLE.addResourceString("message", "Translated - Welcome to Wikipedia!", 3);
101-
WRITE_BUNDLE.addResourceString("tab", "Translated - pick up the\u00A5 tab", 5);
102-
WRITE_BUNDLE.addResourceString("leadSPs", "leading SPs", 6);
103-
WRITE_BUNDLE.addResourceString("leadTabs", "localized leading tabs", 7);
104-
WRITE_BUNDLE.addResourceString("trailSPs", "localized trailing SPs ", 8);
105-
WRITE_BUNDLE.addResourceString("withTabs", "localized Tab1\tTab2\tTab3\t", 9);
101+
WRITE_BUNDLE.addResourceString("message", "Translated - Welcome to Wikipedia!", 3,
102+
Arrays.asList(" The backslash below tells the application to continue reading",
103+
" the value onto the next line."));
104+
WRITE_BUNDLE.addResourceString("tab", "Translated - pick up the\u00A5 tab", 5,
105+
Arrays.asList(" Unicode"));
106+
WRITE_BUNDLE.addResourceString("leadSPs", "leading SPs", 6,
107+
Arrays.asList(" leading SPs"));
108+
WRITE_BUNDLE.addResourceString("leadTabs", "localized leading tabs", 7,
109+
Arrays.asList(" leading tabs"));
110+
WRITE_BUNDLE.addResourceString("trailSPs", "localized trailing SPs ", 8,
111+
Arrays.asList(" trailing SPs"));
112+
WRITE_BUNDLE.addResourceString("withTabs", "localized Tab1\tTab2\tTab3\t", 9,
113+
Arrays.asList(" tabs"));
114+
WRITE_BUNDLE.addNotes(Arrays.asList(
115+
" You are reading the \".properties\" entry.",
116+
" The exclamation mark can also mark text as comments.",
117+
" The key and element characters #, !, =, and : are written with",
118+
" a preceding backslash to ensure that they are properly loaded."));
119+
106120
}
107121

108122
private static LinkedList<PropDef> EXPECTED_PROP_DEF_LIST;
@@ -145,7 +159,8 @@ public void testWrite() throws IOException {
145159
os.flush();
146160
// Properties.store() puts a comment with date and time
147161
// on the first line, ignore it by passing n=1 to compareFiles()
148-
assertTrue(ResourceTestUtil.compareFiles(EXPECTED_WRITE_FILE, tempFile, 1));
162+
assertTrue(ResourceTestUtil.compareFilesUpTo(EXPECTED_WRITE_FILE, tempFile, 5));
163+
assertTrue(ResourceTestUtil.compareFiles(EXPECTED_WRITE_FILE, tempFile, 6));
149164
}
150165
}
151166

gp-res-filter/src/test/java/com/ibm/g11n/pipeline/resfilter/ResourceTestUtil.java

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright IBM Corp. 2016
2+
* Copyright IBM Corp. 2016, 2017
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -27,7 +27,7 @@
2727
import java.nio.file.Paths;
2828

2929
/**
30-
* @author farhan
30+
* @author farhan, JCEmmons
3131
*
3232
*/
3333
public class ResourceTestUtil {
@@ -76,6 +76,34 @@ public static boolean compareFiles(File expected, File actual, int n) throws Fil
7676

7777
return true;
7878
}
79+
/**
80+
* Returns true if the two files match exactly up to the number of lines
81+
* specified in n
82+
*/
83+
public static boolean compareFilesUpTo(File expected, File actual, int n) throws FileNotFoundException, IOException {
84+
try (BufferedReader expectedRdr = new BufferedReader(new FileReader(expected));
85+
BufferedReader actualRdr = new BufferedReader(new FileReader(actual))) {
86+
87+
String expectedLine;
88+
String actualLine;
89+
int lineNum = 0;
90+
while ((expectedLine = expectedRdr.readLine()) != null && lineNum < n) {
91+
actualLine = actualRdr.readLine();
92+
93+
lineNum++;
94+
95+
if (!expectedLine.equals(actualLine)) {
96+
fail("Comparing file <" + actual.getAbsolutePath() + "> with file <" + expected.getAbsolutePath()
97+
+ "> ..." + "\nContent differs on line " + lineNum + "\nExpected content: \n"
98+
+ fileToString(expected) + "\nActual content:\n" + fileToString(actual) + "\n");
99+
return false;
100+
}
101+
}
102+
103+
}
104+
105+
return true;
106+
}
79107

80108
/**
81109
* Returns true if the two files match exactly.
Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,24 @@
1+
# You are reading the ".properties" entry.
2+
# The exclamation mark can also mark text as comments.
3+
# The key and element characters #, !, =, and : are written with
4+
# a preceding backslash to ensure that they are properly loaded.
5+
16
#Fri Apr 22 11:07:23 EDT 2016
2-
website=http\://en.wikipedia.org/translated
3-
language=Not-English
4-
message=Translated - Welcome to Wikipedia\!
5-
key\ with\ spaces=Translated - This is the value that could be looked up with the key "key with spaces".
6-
tab=Translated - pick up the\u00A5 tab
7-
leadSPs=leading SPs
8-
leadTabs=localized leading tabs
9-
trailSPs=localized trailing SPs
10-
withTabs=localized Tab1\tTab2\tTab3\t
7+
website = http\://en.wikipedia.org/translated
8+
language = Not-English
9+
# The backslash below tells the application to continue reading
10+
# the value onto the next line.
11+
message = Translated - Welcome to Wikipedia\!
12+
# Add spaces to the key
13+
key\ with\ spaces = Translated - This is the value that could be looked up \
14+
with the key "key with spaces".
15+
# Unicode
16+
tab = Translated - pick up the\u00A5 tab
17+
# leading SPs
18+
leadSPs = leading SPs
19+
# leading tabs
20+
leadTabs = localized leading tabs
21+
# trailing SPs
22+
trailSPs = localized trailing SPs
23+
# tabs
24+
withTabs = localized Tab1\tTab2\tTab3\t

0 commit comments

Comments
 (0)