Skip to content

Commit 128fe04

Browse files
authored
Merge pull request #57 from JCEmmons/issue41
Implement support for handling of comments in iOS strings. Fixes #41.
2 parents e2bf543 + f242ad4 commit 128fe04

9 files changed

Lines changed: 114 additions & 20 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
eclipse.preferences.version=1
2+
encoding//gp-res-filter/src/test/resource/resfilter/ios/write-output.strings=UTF-8
23
encoding//src/main/java=UTF-8
34
encoding//src/main/resources=UTF-8
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
eclipse.preferences.version=1
22
encoding//src/main/java=UTF-8
33
encoding//src/test/java=UTF-8
4+
encoding//src/test/resource/resfilter/ios/write-output.strings=UTF-8

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ public void addResourceString(String key, String value, int sequenceNumber) {
5050
addResourceString(new ResourceString(key, value, sequenceNumber));
5151
}
5252

53+
public void addResourceString(String key, String value, int sequenceNumber, List<String> notes) {
54+
addResourceString(new ResourceString(key, value, sequenceNumber, notes));
55+
}
56+
5357
public void addNote(String note) {
5458
if (notes == null) {
5559
notes = new ArrayList<>();

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

Lines changed: 64 additions & 14 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.
@@ -23,7 +23,9 @@
2323
import java.io.OutputStream;
2424
import java.io.OutputStreamWriter;
2525
import java.text.BreakIterator;
26+
import java.util.ArrayList;
2627
import java.util.HashMap;
28+
import java.util.Iterator;
2729
import java.util.LinkedList;
2830
import java.util.List;
2931
import java.util.Locale;
@@ -40,21 +42,42 @@
4042
public class IOSStringsResource implements ResourceFilter {
4143

4244
private static final String CHAR_SET = "UTF-8";
43-
45+
private static final String COMMENT_BEGIN = "/*";
46+
private static final String COMMENT_END = "*/";
47+
4448
@Override
4549
public Bundle parse(InputStream in) throws IOException {
4650
Bundle bundle = new Bundle();
4751
BufferedReader reader = new BufferedReader(new InputStreamReader(in, CHAR_SET));
4852

4953
int sqNum = 0;
5054
String line;
55+
List<String> notes = new ArrayList<>();
56+
Boolean commentIsGlobal = true;
5157
while ((line = reader.readLine()) != null) {
52-
if (line.matches("^\\s*/\\*.*")) {// begins with /*
58+
if (line.trim().startsWith(COMMENT_BEGIN)) {// begins with /*
5359
// skip comments until line ends with */
5460
// the short circuit expression evaluation handles both
5561
// single and multi lined comments
56-
while (!line.matches(".*\\*/$") && (line = reader.readLine()) != null)
57-
;
62+
String comment = line.substring(line.indexOf(COMMENT_BEGIN)+2);
63+
Boolean commentEndProcessed = false;
64+
while (!commentEndProcessed && line != null) {
65+
if (comment.trim().endsWith(COMMENT_END)) {
66+
comment = comment.substring(0, comment.lastIndexOf(COMMENT_END));
67+
commentEndProcessed = true;
68+
}
69+
notes.add(comment);
70+
if (!commentEndProcessed) {
71+
line = reader.readLine();
72+
comment = line;
73+
}
74+
}
75+
} else if (commentIsGlobal && line.isEmpty()) {
76+
commentIsGlobal = false;
77+
if (!notes.isEmpty()) {
78+
bundle.addNotes(notes);
79+
notes.clear();
80+
}
5881
} else if (line.matches("^\\s*\".*")) { // begins with quote char
5982
// new entry
6083
StringBuilder entry = new StringBuilder(128);
@@ -69,7 +92,12 @@ public Bundle parse(InputStream in) throws IOException {
6992
String key = parts[0].substring(parts[0].indexOf('"') + 1).trim();
7093
String value = parts[1].substring(0, parts[1].lastIndexOf('"')).trim();
7194

72-
bundle.addResourceString(key, value, ++sqNum);
95+
if (notes.isEmpty()) {
96+
bundle.addResourceString(key, value, ++sqNum);
97+
} else {
98+
bundle.addResourceString(key, value, ++sqNum, notes);
99+
notes.clear();
100+
}
73101
}
74102
}
75103

@@ -83,9 +111,19 @@ public void write(OutputStream os, String language, Bundle bundle) throws IOExce
83111

84112
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, CHAR_SET));
85113

114+
boolean globalNotesWritten = false;
115+
for (String globalNote : bundle.getNotes()) {
116+
writer.write(COMMENT_BEGIN+globalNote+COMMENT_END);
117+
writer.newLine();
118+
globalNotesWritten = true;
119+
}
120+
if (globalNotesWritten) {
121+
writer.newLine();
122+
}
123+
86124
for (ResourceString res : sortedResources) {
87125
// empties the buffer
88-
writer.write(formatEntry(res.getKey(), res.getValue(), language));
126+
writer.write(formatEntry(res.getKey(), res.getValue(), language, res.getNotes()));
89127
}
90128

91129
writer.flush();
@@ -95,9 +133,9 @@ public void write(OutputStream os, String language, Bundle bundle) throws IOExce
95133
public void merge(InputStream base, OutputStream os, String language, Bundle bundle)
96134
throws IOException {
97135
// put res data into a map for easier searching
98-
Map<String, String> resMap = new HashMap<String, String>(bundle.getResourceStrings().size() * 4 / 3 + 1);
136+
Map<String, ResourceString> resMap = new HashMap<String, ResourceString>(bundle.getResourceStrings().size() * 4 / 3 + 1);
99137
for (ResourceString res : bundle.getResourceStrings()) {
100-
resMap.put(res.getKey(), res.getValue());
138+
resMap.put(res.getKey(), res);
101139
}
102140

103141
BufferedReader reader = new BufferedReader(new InputStreamReader(base, CHAR_SET));
@@ -130,7 +168,7 @@ public void merge(InputStream base, OutputStream os, String language, Bundle bun
130168
continue;
131169
}
132170

133-
writer.write(formatEntry(key, resMap.get(key), language));
171+
writer.write(formatEntry(key, resMap.get(key).getValue(), language, resMap.get(key).getNotes()));
134172
} else {
135173
writer.write(line);
136174
writer.newLine();
@@ -140,11 +178,23 @@ public void merge(InputStream base, OutputStream os, String language, Bundle bun
140178
writer.flush();
141179
}
142180

143-
static String formatEntry(String key, String value, String localeStr) {
181+
static String formatEntry(String key, String value, String localeStr, List<String> notes) {
144182
int maxLineLen = 80;
145183

146184
StringBuilder output = new StringBuilder();
147-
185+
StringBuilder comments = new StringBuilder();
186+
187+
if (notes.size() > 0) {
188+
comments.append(COMMENT_BEGIN);
189+
Iterator<String> i = notes.iterator();
190+
while (i.hasNext()) {
191+
comments.append(i.next());
192+
if (i.hasNext()) {
193+
comments.append("\n");
194+
}
195+
}
196+
comments.append(COMMENT_END).append("\n");
197+
}
148198
// construct the entire entry, i.e.
149199
// "key" = "value";
150200
StringBuilder entryBuilder = new StringBuilder(key.length() + value.length() + 7);
@@ -154,7 +204,7 @@ static String formatEntry(String key, String value, String localeStr) {
154204
int entryLen = entry.length();
155205
// entry fits on one line
156206
if (maxLineLen > entryLen) {
157-
return entry;
207+
return comments.toString()+entry;
158208
}
159209

160210
// entry needs to be split onto multiple lines
@@ -197,7 +247,7 @@ static String formatEntry(String key, String value, String localeStr) {
197247
}
198248
}
199249

200-
return output.toString();
250+
return comments.toString()+output.toString();
201251
}
202252

203253
}

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

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.io.InputStream;
2626
import java.io.OutputStream;
2727
import java.util.ArrayList;
28+
import java.util.Arrays;
2829
import java.util.Collection;
2930
import java.util.Collections;
3031
import java.util.LinkedList;
@@ -49,12 +50,19 @@ public class IOSStringsResourceTest {
4950
private static final File EXPECTED_MERGE_2_FILE = new File("src/test/resource/resfilter/ios/merge-output-2.strings");
5051

5152
private static final Collection<ResourceString> EXPECTED_INPUT_RES_LIST;
53+
private static final List<String> EXPECTED_GLOBAL_NOTES = Arrays.asList(
54+
" This is the first global comment... ",
55+
" This is the 2nd global comment... ");
5256

5357
static {
54-
List<ResourceString> lst = new LinkedList<>();
55-
lst.add(new ResourceString("Insert Element", "Insert Element", 1));
56-
lst.add(new ResourceString("ErrorString_1", "An unknown error occurred.", 2));
57-
lst.add(new ResourceString("bear 3", "Brown Bear", 3));
58+
List<ResourceString> lst = new ArrayList<>();
59+
lst.add(new ResourceString("Insert Element", "Insert Element", 1,
60+
Arrays.asList(" Insert = Element menu item ")));
61+
lst.add(new ResourceString("ErrorString_1", "An unknown error occurred.", 2,
62+
Arrays.asList(" Error string used "," for unknown error types. ")));
63+
lst.add(new ResourceString("bear 3", "Brown Bear", 3,
64+
Arrays.asList(" Brown Bear has multiple comments "," Mama Bear ",
65+
" Papa Bear "," Baby Bear ")));
5866
lst.add(new ResourceString("frog 4", "Red-eyed Tree Frog", 4));
5967
lst.add(new ResourceString("owl 5", "Great Horned Owl", 5));
6068

@@ -66,8 +74,11 @@ public class IOSStringsResourceTest {
6674

6775
static {
6876
WRITE_BUNDLE = new Bundle();
69-
WRITE_BUNDLE.addResourceString("sealion 3", "California Sea Lion", 3);
70-
WRITE_BUNDLE.addResourceString("otter 1", "Sea Otter", 1);
77+
WRITE_BUNDLE.addResourceString("sealion 3", "California Sea Lion", 3,
78+
Arrays.asList(" This is a brilliant comment"," about California Sea Lions! "));
79+
80+
WRITE_BUNDLE.addResourceString("otter 1", "Sea Otter", 1,
81+
Arrays.asList(" The sea otter swims a lot. "));
7182
WRITE_BUNDLE.addResourceString("crow 2", "American Crow", 2);
7283
WRITE_BUNDLE.addResourceString("Lorem",
7384
"Loremのイプサムは、単に印刷と植字業界のダミーテキストです。 Loremのイプサムは、未知のプリンターがタイプのゲラを取り、"
@@ -81,6 +92,10 @@ public class IOSStringsResourceTest {
8192
+ "1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 "
8293
+ "1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 ",
8394
4);
95+
WRITE_BUNDLE.addNote(" This is the first global comment... ");
96+
WRITE_BUNDLE.addNote(" This is the 2nd global comment... ");
97+
98+
;
8499
}
85100

86101
private static Bundle MERGE_BUNDLE;
@@ -123,6 +138,8 @@ public void testParse() throws IOException {
123138
List<ResourceString> resStrList = new ArrayList<>(bundle.getResourceStrings());
124139
Collections.sort(resStrList, new ResourceStringComparator());
125140
assertEquals("ResourceStrings did not match.", EXPECTED_INPUT_RES_LIST, resStrList);
141+
List<String> globalNotes = bundle.getNotes();
142+
assertEquals("Global comments did not match.", EXPECTED_GLOBAL_NOTES, globalNotes);
126143
}
127144
}
128145

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1+
/* This is the first global comment... */
2+
/* This is the 2nd global comment... */
3+
14
/* Insert = Element menu item */
25
"Insert Element" = "Insert Element";
36
/* Error string used
47
for unknown error types. */
58
"ErrorString_1" = "An unknown error
69
occurred.";
10+
/* Brown Bear has multiple comments */
11+
/* Mama Bear */
12+
/* Papa Bear */
13+
/* Baby Bear */
714
"bear 3" = "Brown Bear";
815
"frog 4" = "Red-eyed Tree Frog";
916
"owl 5"= "Great Horned Owl";

gp-res-filter/src/test/resource/resfilter/ios/merge-input-1.strings

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
for unknown error types. */
55
"ErrorString_1" = "An unknown error
66
occurred.";
7+
/* Brown Bear has multiple comments */
8+
/* Mama Bear */
9+
/* Papa Bear */
10+
/* Baby Bear */
711
"bear 3" = "Brown Bear";
812
"frog 4" = "Red-eyed Tree Frog";
913
"owl 5"="Great Horned Owl";

gp-res-filter/src/test/resource/resfilter/ios/merge-output-1.strings

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
/* Error string used
44
for unknown error types. */
55
"ErrorString_1" = "An unknown error occurred - translated.";
6+
/* Brown Bear has multiple comments */
7+
/* Mama Bear */
8+
/* Papa Bear */
9+
/* Baby Bear */
610
"bear 3" = "Brown Bear - translated";
711
"frog 4" = "Red-eyed Tree Frog - translated";
812
"owl 5" = "Great Horned Owl - translated";

gp-res-filter/src/test/resource/resfilter/ios/write-output.strings

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1+
/* This is the first global comment... */
2+
/* This is the 2nd global comment... */
3+
4+
/* The sea otter swims a lot. */
15
"otter 1" = "Sea Otter";
26
"crow 2" = "American Crow";
7+
/* This is a brilliant comment
8+
about California Sea Lions! */
39
"sealion 3" = "California Sea Lion";
410
"numbers" = "1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4
511
5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2

0 commit comments

Comments
 (0)