001package org.hl7.fhir.utilities; 002 003/* 004 Copyright (c) 2011+, HL7, Inc. 005 All rights reserved. 006 007 Redistribution and use in source and binary forms, with or without modification, 008 are permitted provided that the following conditions are met: 009 010 * Redistributions of source code must retain the above copyright notice, this 011 list of conditions and the following disclaimer. 012 * Redistributions in binary form must reproduce the above copyright notice, 013 this list of conditions and the following disclaimer in the documentation 014 and/or other materials provided with the distribution. 015 * Neither the name of HL7 nor the names of its contributors may be used to 016 endorse or promote products derived from this software without specific 017 prior written permission. 018 019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 020 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 021 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 022 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 023 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 024 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 025 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 026 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 027 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 028 POSSIBILITY OF SUCH DAMAGE. 029 030 */ 031 032 033 034import java.io.File; 035import java.io.FileInputStream; 036import java.io.FileNotFoundException; 037import java.io.FileOutputStream; 038import java.io.IOException; 039import java.io.OutputStreamWriter; 040import java.util.ArrayList; 041import java.util.Collections; 042import java.util.HashMap; 043import java.util.HashSet; 044import java.util.List; 045import java.util.Map; 046import java.util.Set; 047 048import com.google.gson.Gson; 049import com.google.gson.GsonBuilder; 050import com.google.gson.JsonElement; 051import com.google.gson.JsonObject; 052import com.google.gson.JsonSyntaxException; 053 054public class NDJsonWriter { 055 056 private class ResourceInfo { 057 private FileOutputStream stream; 058 private Set<String> ids = new HashSet<String>(); 059 public OutputStreamWriter writer; 060 } 061 062 private static com.google.gson.JsonParser parser = new com.google.gson.JsonParser(); 063 private Gson gson = new GsonBuilder().create(); 064 private Map<String, ResourceInfo> outputs = new HashMap<String, ResourceInfo>(); 065 private String filename; 066 private String scratch; 067 068 public NDJsonWriter(String filename, String scratch) { 069 this.filename = filename; 070 this.scratch = scratch; 071 outputs.clear(); 072 } 073 074 public void addFilesFiltered(String actualDir, String ext, String[] noExt) throws IOException { 075 File f = new CSFile(actualDir); 076 077 String files[] = f.list(); 078 for (int i = 0; i < files.length; i++) { 079 if ( new CSFile(actualDir + files[i]).isFile() && ((ext == null || files[i].endsWith(ext)))) { 080 boolean ok = true; 081 for (String n : noExt) { 082 ok = ok && !files[i].endsWith(n); 083 } 084 if (ok) { 085 addFile(Utilities.path(actualDir, files[i])); 086 } 087 } 088 } 089 } 090 091 private void addFile(String path) throws JsonSyntaxException, FileNotFoundException, IOException { 092 JsonObject js = parser.parse(TextFile.fileToString(path)).getAsJsonObject(); 093 if (js.has("resourceType")) { 094 addResource(js); 095 } 096 } 097 098 private void addResource(JsonObject js) throws IOException { 099 String rn = js.get("resourceType").getAsString(); 100 if (rn.equals("Bundle")) { 101 if (js.has("entry")) { 102 for (JsonElement item : js.getAsJsonArray("entry")) { 103 if (item instanceof JsonObject && ((JsonObject) item).has("resource")) { 104 JsonObject r = (JsonObject) ((JsonObject) item).get("resource"); 105 rn = r.get("resourceType").getAsString(); 106 addResource(r); 107 } 108 } 109 } 110 } else { 111 if (!js.has("id")) 112 return; 113 114 String id = js.get("id").getAsString(); 115 String json = gson.toJson(js); 116 117 if (outputs.containsKey(rn)) { 118 ResourceInfo ri = outputs.get(rn); 119 if (!ri.ids.contains(id)) { 120 ri.ids.add(id); 121 ri.writer.append("\r\n"); 122 ri.writer.append(json); 123 } 124 } else { 125 ResourceInfo ri = new ResourceInfo(); 126 outputs.put(rn, ri); 127 ri.ids.add(id); 128 ri.stream = new FileOutputStream(Utilities.path(scratch, rn+".ndjson")); 129 ri.writer = new OutputStreamWriter(ri.stream, "UTF-8"); 130 ri.writer.append(json); 131 } 132 } 133 } 134 135 public void close() throws IOException { 136 ZipGenerator zip = new ZipGenerator(filename); 137 for (String rn : sorted(outputs.keySet())) { 138 ResourceInfo ri = outputs.get(rn); 139 ri.writer.flush(); 140 ri.writer.close(); 141 ri.stream.close(); 142 143 zip.addStream(rn+".ndjson", new FileInputStream(Utilities.path(scratch, rn+".ndjson")), false); 144 } 145 zip.close(); 146 } 147 148 private List<String> sorted(Set<String> keys) { 149 List<String> res = new ArrayList<String>(); 150 res.addAll(keys); 151 Collections.sort(res); 152 return res; 153 } 154 155 public static void main(String[] args) throws IOException { 156 String dstDir = "C:\\work\\org.hl7.fhir\\build\\publish\\"; 157 NDJsonWriter ndjson = new NDJsonWriter(dstDir + "examples-ndjson.zip", "c:\\temp\\ndjson"); 158 ndjson.addFilesFiltered(dstDir, ".json", new String[] {".schema.json", ".canonical.json", ".diff.json", "expansions.json", "package.json"}); 159 ndjson.close(); 160 } 161 162}