2222import java .io .OutputStream ;
2323import java .io .OutputStreamWriter ;
2424import java .nio .charset .StandardCharsets ;
25- import java .util .LinkedHashMap ;
2625import java .util .Map ;
2726import java .util .TreeSet ;
2827
2928import com .google .gson .GsonBuilder ;
3029import com .google .gson .JsonElement ;
30+ import com .google .gson .JsonObject ;
3131import com .google .gson .JsonParseException ;
3232import com .google .gson .JsonParser ;
3333import 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
0 commit comments