001package org.hl7.fhir.utilities.npm;
002
003import java.io.File;
004import java.io.FileInputStream;
005import java.io.FileNotFoundException;
006import java.io.FileOutputStream;
007import java.io.IOException;
008import java.nio.charset.StandardCharsets;
009import java.util.ArrayList;
010import java.util.List;
011import java.util.Map;
012
013import org.hl7.fhir.utilities.TextFile;
014import org.hl7.fhir.utilities.Utilities;
015import org.hl7.fhir.utilities.json.model.JsonArray;
016import org.hl7.fhir.utilities.json.model.JsonObject;
017import org.hl7.fhir.utilities.json.parser.JsonParser;
018
019
020
021/**
022 * intenral use only - set the file name to edit in main(), and fill out the edit routine
023 * 
024 * @author grahame
025 *
026 */
027public class PackageHacker {
028
029  private static boolean useSecureReferences = false;
030  
031  public static void main(String[] args) throws FileNotFoundException, IOException {
032    new PackageHacker().edit("/Users/grahamegrieve/web/hl7.org/fhir/5.0.0-snapshot3/hl7.fhir.r5.expansions.tgz");
033  }
034
035  private void edit(String name) throws FileNotFoundException, IOException {
036    File f = new File(name);
037    if (!f.exists())
038      throw new Error("Unable to find "+f.getAbsolutePath());
039    
040    NpmPackage pck = NpmPackage.fromPackage(new FileInputStream(f));
041    System.out.println("Altering Package "+f.getAbsolutePath());
042    System.out.println(nice(pck.getNpm()));
043    
044    change(pck.getNpm());
045    fixContent(pck.getFolders().get("package").getContent());
046    if (pck.getFolders().containsKey("openapi")) {
047      fixContent(pck.getFolders().get("openapi").getContent());
048    }
049    if (pck.getFolders().containsKey("xml")) {
050      fixContent(pck.getFolders().get("xml").getContent());
051    }
052//    fixExampleContent(pck.getFolders().get("example").getContent());
053    
054    System.out.println("Revised Package");
055    System.out.println("=======================");
056    System.out.println(nice(pck.getNpm()));
057    System.out.println("=======================");
058    System.out.print("save? y/n: ");
059    int r = System.in.read();
060    if (r == 'y') {
061      f.renameTo(new File(Utilities.changeFileExt(name, ".tgz.bak")));
062      pck.save(new FileOutputStream(f));
063    }   
064  }
065
066  private void fixExampleContent(Map<String, byte[]> content) {
067//    byte[] cnt = content.get("ServiceRequest-SDOHCC-ServiceRequestCompletedFoodPantryApplicationAssistExample.json");
068//    content.put("ServiceRequest-SDOHCC-ServiceRequestCompletedFoodPantryApplicationAssist.json", cnt);
069//    content.remove("ServiceRequest-SDOHCC-ServiceRequestCompletedFoodPantryApplicationAssistExample.json");
070  }
071
072  private void fixContent(Map<String, byte[]> content) {
073//    fixVersionInContent(content);
074
075  }
076
077  private String nice(JsonObject json) {
078    return JsonParser.compose(json, true);
079  }
080
081  private void change(JsonObject npm) throws FileNotFoundException, IOException {
082//    fixVersions(npm);
083    npm.remove("notForPublication");
084//    npm.remove("url");
085//    npm.add("url", "https://hl7chile.cl/fhir/ig/CoreCL/1.7.0");
086//    npm.remove("name");
087//    npm.addProperty("name", "hl7.fhir.uv.smart-app-launch");
088//    npm.remove("canonical");
089//    npm.addProperty("canonical", "http://hl7.org/fhir/us/davinci-drug-formulary");
090////    npm.remove("description");
091////    npm.addProperty("description", "Group Wrapper that includes all the R4 packages");
092//    npm.remove("url");
093//    npm.addProperty("url", "http://hl7.org/fhir/R4B");
094//    npm.remove("homepage");
095//    npm.addProperty("homepage", "http://hl7.org/fhir/R4B");
096//    npm.remove("dependencies");
097//    JsonObject dep = new JsonObject();
098//    npm.add("dependencies", dep);
099//    dep.addProperty("hl7.fhir.r4.core", "4.0.1");
100//    dep.addProperty("ch.fhir.ig.ch-core", "2.0.0");
101//    dep.addProperty("ch.fhir.ig.ch-epr-term", "2.0.4");
102//    dep.addProperty("ch.fhir.ig.ch-emed","current");
103
104//    dep.addProperty("hl7.fhir.r4.examples", "4.0.1");
105//    dep.addProperty("hl7.fhir.r4.expansions", "4.0.1");
106//    dep.addProperty("hl7.fhir.r4.elements", "4.0.1");
107//    npm.addProperty("jurisdiction", "urn:iso:std:iso:3166#CL");
108  }
109
110  private void fixVersionInContent(Map<String, byte[]> content) {
111    for (String n : content.keySet()) {
112      if (n.endsWith(".json") || n.endsWith(".xml") || n.endsWith(".xsd")) {
113        String json = new String(content.get(n));
114        if (json.contains("4.3.0-cibuild") && !json.contains("4.3.0-snapshot1")) {
115          json = json.replace("4.3.0-cibuild", "4.3.0");
116          content.put(n, json.getBytes(StandardCharsets.UTF_8));
117        }
118      }
119    }
120    
121  }
122
123  private void fixVersions(JsonObject npm) {
124    npm.remove("fhirVersions");
125    JsonArray a = new JsonArray();
126    npm.add("fhirVersions", a);
127    a.add("3.0.1");
128  }
129
130  private void setProperty(JsonObject npm, String name, String value) {
131    npm.remove("homepage");
132    npm.add("homepage", "http://hl7.org/fhir");    
133  }
134
135  private void fixNames(Map<String, byte[]> content) {
136    List<String> names = new ArrayList<>();
137    names.addAll(content.keySet());
138    for (String s : names) {
139      if (s.endsWith("json") && !s.endsWith(".json")) {
140        String n = s.substring(0, s.length()-4)+".json";
141        content.put(n, content.get(s));
142        content.remove(s);
143      }
144    }
145  }
146
147  private void addContentFrom(String folder, Map<String, byte[]> content) throws FileNotFoundException, IOException {
148    for (File f : new File(folder).listFiles()) {
149      if (f.getName().endsWith(".json") && !f.getName().endsWith(".canonical.json")) {
150         String cnt = TextFile.fileToString(f);
151         if (cnt.contains("\"resourceType\"")) {
152           content.put("package/"+f.getName(), TextFile.fileToBytes(f));
153         }
154      }
155    }
156  }
157
158  public static String fixPackageUrl(String webref) {
159    if (webref == null) {
160      return null;
161    }
162    // workaround for past publishing problems
163    switch (webref) {
164    case "file://C:\\GitHub\\hl7.fhir.us.breast-radiology#0.2.0\\output":   return "http://hl7.org/fhir/us/breast-radiology/2020May"; 
165    case "file://C:\\GitHub\\hl7.fhir.us.bser#1.0.0\\output":                return "http://hl7.org/fhir/us/bser/STU1"; 
166    case "file://C:\\GitHub\\hl7.fhir.us.carin-bb#0.1.0\\output":            return "http://hl7.org/fhir/us/carin-bb/2020Feb"; 
167    case "file://C:\\GitHub\\hl7.fhir.us.carin-rtpbc#0.1.0\\output":         return "http://hl7.org/fhir/us/carin-rtpbc/2020Feb"; 
168    case "file://C:\\GitHub\\hl7.fhir.us.cqfmeasures#1.1.0\\output":         return "http://hl7.org/fhir/us/cqfmeasures/2020Feb"; 
169    case "file://C:\\GitHub\\hl7.fhir.us.cqfmeasures#2.0.0\\output":         return "http://hl7.org/fhir/us/cqfmeasures/STU2"; 
170    case "file://C:\\GitHub\\hl7.fhir.us.davinci-alerts#0.2.0\\output":      return "http://hl7.org/fhir/us/davinci-alerts/2020Feb"; 
171    case "file://C:\\GitHub\\hl7.fhir.us.davinci-atr#0.1.0\\output":         return "http://hl7.org/fhir/us/davinci-atr/2020Feb";  
172    case "file://C:\\GitHub\\hl7.fhir.us.davinci-deqm#1.1.0\\output":        return "http://hl7.org/fhir/us/davinci-deqm/2020Feb"; 
173    case "file://C:\\GitHub\\hl7.fhir.us.davinci-deqm#1.0.0\\output":        return "http://hl7.org/fhir/us/davinci-deqm/STU1"; 
174    case "file://C:\\GitHub\\hl7.fhir.us.dme-orders#0.1.1\\output":          return "http://hl7.org/fhir/us/dme-orders/2020May"; 
175    case "file://C:\\GitHub\\hl7.fhir.us.ecr#1.0.0\\output":                 return "http://hl7.org/fhir/us/ecr/STU1"; 
176    case "file://C:\\GitHub\\hl7.fhir.us.mcode#1.0.0\\output":               return "http://hl7.org/fhir/us/mcode/STU1"; 
177    case "file://C:\\GitHub\\hl7.fhir.us.odh#1.0.0\\output":                 return "http://hl7.org/fhir/us/odh/STU1"; 
178    case "file://C:\\GitHub\\hl7.fhir.us.qicore#4.0.0\\output":              return "http://hl7.org/fhir/us/qicore/STU4"; 
179    case "file://C:\\GitHub\\hl7.fhir.uv.ips#1.0.0\\output":                 return "http://hl7.org/fhir/uv/ips/STU1"; 
180    case "file://C:\\GitHub\\hl7.fhir.uv.mhealth-framework#0.1.0\\output":   return "http://hl7.org/fhir/uv/mhealth-framework/2020May"; 
181    case "file://C:\\GitHub\\hl7.fhir.uv.security-label-ds4p#0.1.0\\output": return "http://hl7.org/fhir/uv/security-label-ds4p/2020May"; 
182    case "file://C:\\GitHub\\hl7.fhir.uv.shorthand#0.12.0\\output":          return "http://hl7.org/fhir/uv/shorthand/2020May"; 
183    case "http://build.fhir.org/branches/R4B//":                             return "http://hl7.org/fhir/2021Mar"; 
184    }
185
186    // https://github.com/HL7/fhir-ig-publisher/issues/295
187    if (webref.contains("hl7.org/fhir/us/core/STU4.0.0")) {
188      return webref.replace("hl7.org/fhir/us/core/STU4.0.0", "hl7.org/fhir/us/core/STU4");
189    }
190
191    if (isUseSecureReferences()) {
192      return webref.replace("http://hl7.org/fhir", "https://hl7.org/fhir").replace("http://build.fhir.org", "https://build.fhir.org");
193    } else {
194      return webref;
195    }
196  }
197
198  public static boolean isUseSecureReferences() {
199    return useSecureReferences;
200  }
201
202  public static void setUseSecureReferences(boolean useSecureReferences) {
203    PackageHacker.useSecureReferences = useSecureReferences;
204  }
205
206}