001package org.hl7.fhir.convertors.misc; 002 003import com.google.common.base.Charsets; 004import com.google.gson.JsonArray; 005import com.google.gson.JsonObject; 006import org.apache.commons.compress.archivers.tar.TarArchiveEntry; 007import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; 008import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; 009import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream; 010import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream; 011import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_30_40; 012import org.hl7.fhir.convertors.advisors.impl.BaseAdvisor_30_50; 013import org.hl7.fhir.convertors.factory.*; 014import org.hl7.fhir.utilities.TextFile; 015import org.hl7.fhir.utilities.VersionUtilities; 016import org.hl7.fhir.utilities.json.JSONUtil; 017import org.hl7.fhir.utilities.json.JsonTrackingParser; 018import org.hl7.fhir.utilities.npm.NpmPackageIndexBuilder; 019 020import java.io.BufferedOutputStream; 021import java.io.ByteArrayOutputStream; 022import java.io.FileInputStream; 023import java.io.IOException; 024import java.nio.charset.StandardCharsets; 025import java.util.ArrayList; 026import java.util.HashMap; 027import java.util.List; 028import java.util.Map; 029import java.util.Map.Entry; 030 031public class NpmPackageVersionConverter { 032 033 private static final int BUFFER_SIZE = 1024; 034 035 private final String source; 036 private final String dest; 037 private final String version; 038 private final String vCode; 039 private final List<String> errors = new ArrayList<>(); 040 private String currentVersion; 041 042 public NpmPackageVersionConverter(String source, String dest, String version) { 043 super(); 044 this.source = source; 045 this.dest = dest; 046 this.vCode = version; 047 this.version = VersionUtilities.versionFromCode(version); 048 } 049 050 public static void main(String[] args) throws IOException { 051 NpmPackageVersionConverter self = new NpmPackageVersionConverter(args[0], args[1], args[2]); 052 self.execute(); 053 System.out.println("Finished"); 054 for (String s : self.errors) { 055 System.out.println(s); 056 } 057 } 058 059 public List<String> getErrors() { 060 return errors; 061 } 062 063 public void execute() throws IOException { 064 GzipCompressorInputStream gzipIn; 065 try { 066 gzipIn = new GzipCompressorInputStream(new FileInputStream(source)); 067 } catch (Exception e) { 068 throw new IOException("Error reading " + source + ": " + e.getMessage(), e); 069 } 070 Map<String, byte[]> content = new HashMap<>(); 071 072 try (TarArchiveInputStream tarIn = new TarArchiveInputStream(gzipIn)) { 073 TarArchiveEntry entry; 074 075 while ((entry = (TarArchiveEntry) tarIn.getNextEntry()) != null) { 076 String n = entry.getName(); 077 if (!entry.isDirectory()) { 078 int count; 079 byte[] data = new byte[BUFFER_SIZE]; 080 ByteArrayOutputStream fos = new ByteArrayOutputStream(); 081 try (BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER_SIZE)) { 082 while ((count = tarIn.read(data, 0, BUFFER_SIZE)) != -1) { 083 dest.write(data, 0, count); 084 } 085 } 086 fos.close(); 087 content.put(n, fos.toByteArray()); 088 } 089 } 090 } 091 092 Map<String, byte[]> output = new HashMap<>(); 093 output.put("package/package.json", convertPackage(content.get("package/package.json"))); 094 095 for (Entry<String, byte[]> e : content.entrySet()) { 096 if (!e.getKey().equals("package/package.json")) { 097 byte[] cnv = e.getValue(); 098 try { 099 JsonObject json = JsonTrackingParser.parseJson(e.getValue()); 100 if (json.has("resourceType")) { 101 cnv = convertResource(e.getKey(), e.getValue()); 102 } 103 } catch (Exception ex) { 104 } 105 if (cnv != null && cnv.length > 0) { 106 output.put(e.getKey(), cnv); 107 } 108 } 109 } 110 111 TarArchiveOutputStream tar; 112 ByteArrayOutputStream OutputStream; 113 BufferedOutputStream bufferedOutputStream; 114 GzipCompressorOutputStream gzipOutputStream; 115 116 OutputStream = new ByteArrayOutputStream(); 117 bufferedOutputStream = new BufferedOutputStream(OutputStream); 118 gzipOutputStream = new GzipCompressorOutputStream(bufferedOutputStream); 119 tar = new TarArchiveOutputStream(gzipOutputStream); 120 121 122 Map<String, NpmPackageIndexBuilder> indexers = new HashMap<>(); 123 for (Entry<String, byte[]> e : output.entrySet()) { 124 String n = e.getKey().substring(0, e.getKey().lastIndexOf("/")); 125 String s = e.getKey().substring(n.length() + 1); 126 byte[] b = e.getValue(); 127 NpmPackageIndexBuilder indexer = indexers.get(n); 128 if (indexer == null) { 129 indexer = new NpmPackageIndexBuilder(); 130 indexer.start(); 131 indexers.put(n, indexer); 132 } 133 indexer.seeFile(s, b); 134 if (!s.equals(".index.json") && !s.equals("package.json")) { 135 TarArchiveEntry entry = new TarArchiveEntry(e.getKey()); 136 entry.setSize(b.length); 137 tar.putArchiveEntry(entry); 138 tar.write(b); 139 tar.closeArchiveEntry(); 140 } 141 } 142 for (Entry<String, NpmPackageIndexBuilder> e : indexers.entrySet()) { 143 byte[] cnt = e.getValue().build().getBytes(StandardCharsets.UTF_8); 144 TarArchiveEntry entry = new TarArchiveEntry(e.getKey() + "/.index.json"); 145 entry.setSize(cnt.length); 146 tar.putArchiveEntry(entry); 147 tar.write(cnt); 148 tar.closeArchiveEntry(); 149 } 150 151 byte[] cnt = output.get("package/package.json"); 152 TarArchiveEntry entry = new TarArchiveEntry("package/package.json"); 153 entry.setSize(cnt.length); 154 tar.putArchiveEntry(entry); 155 tar.write(cnt); 156 tar.closeArchiveEntry(); 157 158 tar.finish(); 159 tar.close(); 160 gzipOutputStream.close(); 161 bufferedOutputStream.close(); 162 OutputStream.close(); 163 byte[] b = OutputStream.toByteArray(); 164 TextFile.bytesToFile(b, dest); 165 } 166 167 private byte[] convertPackage(byte[] cnt) throws IOException { 168 JsonObject json = JsonTrackingParser.parseJson(cnt); 169 currentVersion = json.getAsJsonArray("fhirVersions").get(0).getAsString(); 170 String name = JSONUtil.str(json, "name"); 171 json.remove("name"); 172 json.addProperty("name", name + "." + vCode); 173 json.remove("fhirVersions"); 174 json.remove("dependencies"); 175 JsonArray fv = new JsonArray(); 176 json.add("fhirVersions", fv); 177 fv.add(version); 178 JsonObject dep = new JsonObject(); 179 json.add("dependencies", dep); 180 dep.addProperty(VersionUtilities.packageForVersion(version), version); 181 return JsonTrackingParser.write(json).getBytes(Charsets.UTF_8); 182 } 183 184 private byte[] convertResource(String n, byte[] cnt) { 185 try { 186 if (VersionUtilities.isR2Ver(currentVersion)) { 187 org.hl7.fhir.dstu2.model.Resource res = new org.hl7.fhir.dstu2.formats.JsonParser().parse(cnt); 188 if (VersionUtilities.isR2Ver(version)) { 189 return new org.hl7.fhir.dstu2.formats.JsonParser().composeBytes(res); 190 } else if (VersionUtilities.isR2BVer(version)) { 191 return new org.hl7.fhir.dstu2016may.formats.JsonParser().composeBytes(VersionConvertorFactory_14_30.convertResource(VersionConvertorFactory_10_30.convertResource(res))); 192 } else if (VersionUtilities.isR3Ver(version)) { 193 return new org.hl7.fhir.dstu3.formats.JsonParser().composeBytes(VersionConvertorFactory_10_30.convertResource(res)); 194 } else if (VersionUtilities.isR4Ver(version)) { 195 return new org.hl7.fhir.r4.formats.JsonParser().composeBytes(VersionConvertorFactory_10_40.convertResource(res)); 196 } else if (VersionUtilities.isR5Ver(version)) { 197 return new org.hl7.fhir.r5.formats.JsonParser().composeBytes(VersionConvertorFactory_10_50.convertResource(res)); 198 } 199 } else if (VersionUtilities.isR2BVer(currentVersion)) { 200 org.hl7.fhir.dstu2016may.model.Resource res = new org.hl7.fhir.dstu2016may.formats.JsonParser().parse(cnt); 201 if (VersionUtilities.isR2Ver(version)) { 202 return new org.hl7.fhir.dstu2.formats.JsonParser().composeBytes(VersionConvertorFactory_10_30.convertResource(VersionConvertorFactory_14_30.convertResource(res))); 203 } else if (VersionUtilities.isR2BVer(version)) { 204 return new org.hl7.fhir.dstu2016may.formats.JsonParser().composeBytes(res); 205 } else if (VersionUtilities.isR3Ver(version)) { 206 return new org.hl7.fhir.dstu3.formats.JsonParser().composeBytes(VersionConvertorFactory_14_30.convertResource(res)); 207 } else if (VersionUtilities.isR4Ver(version)) { 208 return new org.hl7.fhir.r4.formats.JsonParser().composeBytes(VersionConvertorFactory_14_40.convertResource(res)); 209 } else if (VersionUtilities.isR5Ver(version)) { 210 return new org.hl7.fhir.r5.formats.JsonParser().composeBytes(VersionConvertorFactory_14_50.convertResource(res)); 211 } 212 } else if (VersionUtilities.isR3Ver(currentVersion)) { 213 org.hl7.fhir.dstu3.model.Resource res = new org.hl7.fhir.dstu3.formats.JsonParser().parse(cnt); 214 if (VersionUtilities.isR2Ver(version)) { 215 return new org.hl7.fhir.dstu2.formats.JsonParser().composeBytes(VersionConvertorFactory_10_30.convertResource(res)); 216 } else if (VersionUtilities.isR2BVer(version)) { 217 return new org.hl7.fhir.dstu2016may.formats.JsonParser().composeBytes(VersionConvertorFactory_14_30.convertResource(res)); 218 } else if (VersionUtilities.isR3Ver(version)) { 219 return new org.hl7.fhir.dstu3.formats.JsonParser().composeBytes(res); 220 } else if (VersionUtilities.isR4Ver(version)) { 221 return new org.hl7.fhir.r4.formats.JsonParser().composeBytes(VersionConvertorFactory_30_40.convertResource(res)); 222 } else if (VersionUtilities.isR5Ver(version)) { 223 return new org.hl7.fhir.r5.formats.JsonParser().composeBytes(VersionConvertorFactory_30_50.convertResource(res)); 224 } 225 } else if (VersionUtilities.isR4Ver(currentVersion)) { 226 org.hl7.fhir.r4.model.Resource res = new org.hl7.fhir.r4.formats.JsonParser().parse(cnt); 227 if (VersionUtilities.isR2Ver(version)) { 228 return new org.hl7.fhir.dstu2.formats.JsonParser().composeBytes(VersionConvertorFactory_10_40.convertResource(res, new PR2Handler())); 229 } else if (VersionUtilities.isR2BVer(version)) { 230 return new org.hl7.fhir.dstu2016may.formats.JsonParser().composeBytes(VersionConvertorFactory_14_40.convertResource(res)); 231 } else if (VersionUtilities.isR3Ver(version)) { 232 return new org.hl7.fhir.dstu3.formats.JsonParser().composeBytes(VersionConvertorFactory_30_40.convertResource(res, new BaseAdvisor_30_40(false))); 233 } else if (VersionUtilities.isR4Ver(version)) { 234 return new org.hl7.fhir.r4.formats.JsonParser().composeBytes(res); 235 } else if (VersionUtilities.isR5Ver(version)) { 236 return new org.hl7.fhir.r5.formats.JsonParser().composeBytes(VersionConvertorFactory_40_50.convertResource(res)); 237 } 238 } else if (VersionUtilities.isR5Ver(currentVersion)) { 239 org.hl7.fhir.r5.model.Resource res = new org.hl7.fhir.r5.formats.JsonParser().parse(cnt); 240 if (VersionUtilities.isR2Ver(version)) { 241 return new org.hl7.fhir.dstu2.formats.JsonParser().composeBytes(VersionConvertorFactory_10_50.convertResource(res)); 242 } else if (VersionUtilities.isR2BVer(version)) { 243 return new org.hl7.fhir.dstu2016may.formats.JsonParser().composeBytes(VersionConvertorFactory_14_50.convertResource(res)); 244 } else if (VersionUtilities.isR3Ver(version)) { 245 return new org.hl7.fhir.dstu3.formats.JsonParser().composeBytes(VersionConvertorFactory_30_50.convertResource(res, new BaseAdvisor_30_50(false))); 246 } else if (VersionUtilities.isR4Ver(version)) { 247 return new org.hl7.fhir.r4.formats.JsonParser().composeBytes(VersionConvertorFactory_40_50.convertResource(res)); 248 } else if (VersionUtilities.isR5Ver(version)) { 249 return new org.hl7.fhir.r5.formats.JsonParser().composeBytes(res); 250 } 251 } 252 throw new Error("Unknown version " + currentVersion + " -> " + version); 253 } catch (Exception ex) { 254 ex.printStackTrace(); 255 errors.add("Error converting " + n + ": " + ex.getMessage()); 256 return null; 257 } 258 } 259 260}