JsonResource extends ResourceFilter { @Override public void write(OutputStream outStream, LanguageBundle languageBundle, FilterOptions options) throws IOException, ResourceFilterException { List<ResourceString> resStrings = languageBundle.getSortedResourceStrings(); JsonObject output = new JsonObject(); JsonObject top_level; if (this instanceof GlobalizeJsResource) { String resLanguageCode = languageBundle.getEmbeddedLanguageCode(); if (resLanguageCode == null || resLanguageCode.isEmpty()) { throw new ResourceFilterException("Missing resource language code in the specified language bundle."); } top_level = new JsonObject(); top_level.add(resLanguageCode, output); } else { top_level = output; } for (ResourceString res : resStrings) { String key = res.getKey(); List<KeyPiece> keyPieces = splitKeyPieces(key); JsonElement current = output; for (int i = 0; i < keyPieces.size(); i++) { if (i + 1 < keyPieces.size()) { if (current.isJsonObject()) { JsonObject currentObject = current.getAsJsonObject(); if (!currentObject.has(keyPieces.get(i).keyValue)) { if (keyPieces.get(i + 1).keyType == JsonToken.BEGIN_ARRAY) { currentObject.add(keyPieces.get(i).keyValue, new JsonArray()); } else { currentObject.add(keyPieces.get(i).keyValue, new JsonObject()); } } current = currentObject.get(keyPieces.get(i).keyValue); } else { JsonArray currentArray = current.getAsJsonArray(); Integer idx = Integer.valueOf(keyPieces.get(i).keyValue); for (int arrayIndex = currentArray.size(); arrayIndex <= idx; arrayIndex++) { currentArray.add(JsonNull.INSTANCE); } if (currentArray.get(idx).isJsonNull()) { if (keyPieces.get(i + 1).keyType == JsonToken.BEGIN_ARRAY) { currentArray.set(idx, new JsonArray()); } else { currentArray.set(idx, new JsonObject()); } } current = currentArray.get(idx); } } else { if (keyPieces.get(i).keyType == JsonToken.BEGIN_ARRAY) { JsonArray currentArray = current.getAsJsonArray(); Integer idx = Integer.valueOf(keyPieces.get(i).keyValue); JsonPrimitive e = new JsonPrimitive(res.getValue()); for (int arrayIndex = currentArray.size(); arrayIndex <= idx; arrayIndex++) { currentArray.add(JsonNull.INSTANCE); } current.getAsJsonArray().set(idx, e); } else { current.getAsJsonObject().addProperty(keyPieces.get(i).keyValue, res.getValue()); } } } } try (OutputStreamWriter writer = new OutputStreamWriter(new BufferedOutputStream(outStream), StandardCharsets.UTF_8)) { new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create().toJson(top_level, writer); } }  @Override LanguageBundle parse(InputStream inStream, FilterOptions options); @Override void write(OutputStream outStream, LanguageBundle languageBundle,
            FilterOptions options);  }
@Test public void testWrite() throws IOException, ResourceFilterException { File tempFile = File.createTempFile(this.getClass().getSimpleName(), ".json"); tempFile.deleteOnExit(); try (OutputStream os = new FileOutputStream(tempFile)) { res.write(os, WRITE_BUNDLE, null); os.flush(); ResourceTestUtil.compareFilesJson(EXPECTED_WRITE_FILE, tempFile); } }