001package org.hl7.fhir.utilities; 002 003import java.io.File; 004import java.io.FileInputStream; 005import java.io.FileNotFoundException; 006import java.io.FileOutputStream; 007import java.io.IOException; 008import java.io.OutputStreamWriter; 009import java.util.ArrayList; 010import java.util.Collections; 011import java.util.HashMap; 012import java.util.HashSet; 013import java.util.List; 014import java.util.Map; 015import java.util.Set; 016 017import com.google.gson.Gson; 018import com.google.gson.GsonBuilder; 019import com.google.gson.JsonElement; 020import com.google.gson.JsonObject; 021import com.google.gson.JsonSyntaxException; 022 023public class NDJsonWriter { 024 025 private class ResourceInfo { 026 private FileOutputStream stream; 027 private Set<String> ids = new HashSet<String>(); 028 public OutputStreamWriter writer; 029 } 030 031 private static com.google.gson.JsonParser parser = new com.google.gson.JsonParser(); 032 private Gson gson = new GsonBuilder().create(); 033 private Map<String, ResourceInfo> outputs = new HashMap<String, ResourceInfo>(); 034 private String filename; 035 private String scratch; 036 037 public NDJsonWriter(String filename, String scratch) { 038 this.filename = filename; 039 this.scratch = scratch; 040 outputs.clear(); 041 } 042 043 public void addFilesFiltered(String actualDir, String ext, String[] noExt) throws IOException { 044 File f = new CSFile(actualDir); 045 046 String files[] = f.list(); 047 for (int i = 0; i < files.length; i++) { 048 if ( new CSFile(actualDir + files[i]).isFile() && ((ext == null || files[i].endsWith(ext)))) { 049 boolean ok = true; 050 for (String n : noExt) { 051 ok = ok && !files[i].endsWith(n); 052 } 053 if (ok) { 054 addFile(Utilities.path(actualDir, files[i])); 055 } 056 } 057 } 058 } 059 060 private void addFile(String path) throws JsonSyntaxException, FileNotFoundException, IOException { 061 JsonObject js = parser.parse(TextFile.fileToString(path)).getAsJsonObject(); 062 if (js.has("resourceType")) { 063 addResource(js); 064 } 065 } 066 067 private void addResource(JsonObject js) throws IOException { 068 String rn = js.get("resourceType").getAsString(); 069 if (rn.equals("Bundle")) { 070 if (js.has("entry")) { 071 for (JsonElement item : js.getAsJsonArray("entry")) { 072 if (item instanceof JsonObject && ((JsonObject) item).has("resource")) { 073 JsonObject r = (JsonObject) ((JsonObject) item).get("resource"); 074 rn = r.get("resourceType").getAsString(); 075 addResource(r); 076 } 077 } 078 } 079 } else { 080 if (!js.has("id")) 081 return; 082 083 String id = js.get("id").getAsString(); 084 String json = gson.toJson(js); 085 086 if (outputs.containsKey(rn)) { 087 ResourceInfo ri = outputs.get(rn); 088 if (!ri.ids.contains(id)) { 089 ri.ids.add(id); 090 ri.writer.append("\r\n"); 091 ri.writer.append(json); 092 } 093 } else { 094 ResourceInfo ri = new ResourceInfo(); 095 outputs.put(rn, ri); 096 ri.ids.add(id); 097 ri.stream = new FileOutputStream(Utilities.path(scratch, rn+".ndjson")); 098 ri.writer = new OutputStreamWriter(ri.stream, "UTF-8"); 099 ri.writer.append(json); 100 } 101 } 102 } 103 104 public void close() throws IOException { 105 ZipGenerator zip = new ZipGenerator(filename); 106 for (String rn : sorted(outputs.keySet())) { 107 ResourceInfo ri = outputs.get(rn); 108 ri.writer.flush(); 109 ri.writer.close(); 110 ri.stream.close(); 111 112 zip.addStream(rn+".ndjson", new FileInputStream(Utilities.path(scratch, rn+".ndjson")), false); 113 } 114 zip.close(); 115 } 116 117 private List<String> sorted(Set<String> keys) { 118 List<String> res = new ArrayList<String>(); 119 res.addAll(keys); 120 Collections.sort(res); 121 return res; 122 } 123 124 public static void main(String[] args) throws IOException { 125 String dstDir = "C:\\work\\org.hl7.fhir\\build\\publish\\"; 126 NDJsonWriter ndjson = new NDJsonWriter(dstDir + "examples-ndjson.zip", "c:\\temp\\ndjson"); 127 ndjson.addFilesFiltered(dstDir, ".json", new String[] {".schema.json", ".canonical.json", ".diff.json", "expansions.json", "package.json"}); 128 ndjson.close(); 129 } 130 131}