Skip to content

Commit 9e38d24

Browse files
committed
First cut for structured JSON - simple keys only and no arrays.
1 parent f9f9848 commit 9e38d24

4 files changed

Lines changed: 76 additions & 33 deletions

File tree

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

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@
2222
import java.io.OutputStream;
2323
import java.io.OutputStreamWriter;
2424
import java.nio.charset.StandardCharsets;
25-
import java.util.LinkedHashMap;
2625
import java.util.Map;
2726
import java.util.TreeSet;
2827

2928
import com.google.gson.GsonBuilder;
3029
import com.google.gson.JsonElement;
30+
import com.google.gson.JsonObject;
3131
import com.google.gson.JsonParseException;
3232
import com.google.gson.JsonParser;
3333
import com.ibm.g11n.pipeline.resfilter.ResourceString.ResourceStringComparator;
@@ -46,35 +46,62 @@ public Bundle parse(InputStream inStream) throws IOException {
4646
JsonElement root = new JsonParser().parse(reader);
4747
if (!root.isJsonObject()) {
4848
throw new IllegalResourceFormatException("The root JSON element is not an JSON object.");
49-
}
50-
int sequenceNum = 0;
51-
for (Map.Entry<String, JsonElement> entry : root.getAsJsonObject().entrySet()) {
52-
String key = entry.getKey();
53-
JsonElement value = entry.getValue();
54-
if (!value.isJsonPrimitive() || !value.getAsJsonPrimitive().isString()) {
55-
throw new IllegalResourceFormatException("The value of JSON element " + key + " is not a string.");
56-
}
57-
sequenceNum++;
58-
bundle.addResourceString(key, value.getAsString(), sequenceNum);
59-
}
49+
}
50+
addBundleStrings(root.getAsJsonObject(),"", bundle, 0);
6051
} catch (JsonParseException e) {
6152
throw new IllegalResourceFormatException("Failed to parse the specified JSON contents.", e);
6253
}
6354
return bundle;
6455
}
6556

57+
private int addBundleStrings( JsonObject obj, String keyPrefix, Bundle bundle, int sequenceNum) {
58+
for (Map.Entry<String, JsonElement> entry : obj.entrySet()) {
59+
String key = entry.getKey();
60+
JsonElement value = entry.getValue();
61+
if (value.isJsonObject()) {
62+
String newKeyPrefix;
63+
if (keyPrefix.isEmpty()) {
64+
newKeyPrefix = "$." + key + ".";
65+
} else {
66+
newKeyPrefix = keyPrefix + key + ".";
67+
}
68+
sequenceNum = addBundleStrings(value.getAsJsonObject(),newKeyPrefix,bundle,sequenceNum);
69+
} else if (!value.isJsonPrimitive() || !value.getAsJsonPrimitive().isString()) {
70+
throw new IllegalResourceFormatException("The value of JSON element " + key + " is not a string.");
71+
} else {
72+
sequenceNum++;
73+
bundle.addResourceString(keyPrefix+key, value.getAsString(), sequenceNum);
74+
}
75+
}
76+
return sequenceNum;
77+
}
6678
@Override
6779
public void write(OutputStream outStream, String language, Bundle bundle) throws IOException {
6880
// extracts key value pairs in original sequence order
6981
TreeSet<ResourceString> sortedResources = new TreeSet<>(new ResourceStringComparator());
7082
sortedResources.addAll(bundle.getResourceStrings());
71-
LinkedHashMap<String, String> kvmap = new LinkedHashMap<>(sortedResources.size());
83+
JsonObject output = new JsonObject();
7284
for (ResourceString res : sortedResources) {
73-
kvmap.put(res.getKey(), res.getValue());
85+
String key = res.getKey();
86+
if (key.startsWith("$.")) {
87+
key = key.substring(2);
88+
}
89+
String[] keyPieces = key.split("\\.");
90+
JsonObject current = output;
91+
for (int i = 0 ; i < keyPieces.length ; i++ ) {
92+
if ( i + 1 < keyPieces.length ) { // There is structure under this key piece
93+
if (!current.has(keyPieces[i])) {
94+
current.add(keyPieces[i],new JsonObject());
95+
}
96+
current = current.getAsJsonObject(keyPieces[i]);
97+
} else { // This is the leaf node
98+
current.addProperty(keyPieces[i], res.getValue());
99+
}
100+
}
74101
}
75102
try (OutputStreamWriter writer = new OutputStreamWriter(new BufferedOutputStream(outStream),
76103
StandardCharsets.UTF_8)) {
77-
new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create().toJson(kvmap, writer);
104+
new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create().toJson(output, writer);
78105
}
79106
}
80107

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

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,11 @@ public class JsonResourceTest {
5050

5151
static {
5252
List<ResourceString> lst = new LinkedList<>();
53-
lst.add(new ResourceString("bear 1", "Brown Bear", 1));
54-
lst.add(new ResourceString("frog 2", "Red-eyed Tree Frog", 2));
55-
lst.add(new ResourceString("owl 3", "Great Horned Owl", 3));
53+
lst.add(new ResourceString("$.bears.grizzly.brown", "Brown Bear", 1));
54+
lst.add(new ResourceString("$.bears.grizzly.black", "Black Bear", 2));
55+
lst.add(new ResourceString("$.bears.white", "Polar Bear", 3));
56+
lst.add(new ResourceString("frog 2", "Red-eyed Tree Frog", 4));
57+
lst.add(new ResourceString("owl 3", "Great Horned Owl", 5));
5658

5759
Collections.sort(lst, new ResourceStringComparator());
5860
EXPECTED_INPUT_RES_LIST = lst;
@@ -62,9 +64,11 @@ public class JsonResourceTest {
6264

6365
static {
6466
WRITE_BUNDLE = new Bundle();
65-
WRITE_BUNDLE.addResourceString("owl 3", "Great Horned Owl - translated", 3);
66-
WRITE_BUNDLE.addResourceString("bear 1", "Brown Bear - translated", 1);
67-
WRITE_BUNDLE.addResourceString("frog 2", "Red-eyed Tree Frog - translated", 2);
67+
WRITE_BUNDLE.addResourceString("owl 3", "Great Horned Owl - translated", 5);
68+
WRITE_BUNDLE.addResourceString("$.bears.grizzly.brown", "Brown Bear - translated", 1);
69+
WRITE_BUNDLE.addResourceString("$.bears.grizzly.black", "Black Bear - translated", 2);
70+
WRITE_BUNDLE.addResourceString("$.bears.white", "Polar Bear - translated", 3);
71+
WRITE_BUNDLE.addResourceString("frog 2", "Red-eyed Tree Frog - translated", 4);
6872
}
6973

7074
private static final JsonResource res = new JsonResource();
@@ -93,16 +97,16 @@ public void testWrite() throws IOException {
9397
}
9498
}
9599

96-
@Test
97-
public void testMerge() throws IOException {
98-
File tempFile = File.createTempFile(this.getClass().getSimpleName(), ".json");
99-
tempFile.deleteOnExit();
100+
// @Test
101+
// public void testMerge() throws IOException {
102+
// File tempFile = File.createTempFile(this.getClass().getSimpleName(), ".json");
103+
// tempFile.deleteOnExit();
100104

101-
try (OutputStream os = new FileOutputStream(tempFile); InputStream is = new FileInputStream(INPUT_FILE)) {
102-
res.merge(is, os, null, WRITE_BUNDLE);
103-
os.flush();
105+
// try (OutputStream os = new FileOutputStream(tempFile); InputStream is = new FileInputStream(INPUT_FILE)) {
106+
// res.merge(is, os, null, WRITE_BUNDLE);
107+
// os.flush();
104108
// TODO: Not ready yet
105109
// assertTrue(ResourceTestUtil.compareFiles(EXPECTED_MERGE_FILE, tempFile));
106-
}
107-
}
110+
// }
111+
// }
108112
}
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
{
2-
"bear 1": "Brown Bear",
2+
"bears": {
3+
"grizzly": {
4+
"brown": "Brown Bear",
5+
"black": "Black Bear"
6+
},
7+
"white": "Polar Bear"
8+
},
39
"frog 2": "Red-eyed Tree Frog",
410
"owl 3": "Great Horned Owl"
511
}
Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
{
2-
"bear 1": "Brown Bear - translated",
2+
"bears": {
3+
"grizzly": {
4+
"brown": "Brown Bear - translated",
5+
"black": "Black Bear - translated"
6+
},
7+
"white": "Polar Bear - translated"
8+
},
39
"frog 2": "Red-eyed Tree Frog - translated",
410
"owl 3": "Great Horned Owl - translated"
5-
}
11+
}

0 commit comments

Comments
 (0)