001package org.hl7.fhir.dstu3.utils;
002
003import java.io.File;
004import java.io.FileInputStream;
005import java.io.FileNotFoundException;
006import java.io.FileOutputStream;
007import java.io.IOException;
008import java.util.ArrayList;
009import java.util.HashMap;
010import java.util.List;
011import java.util.Map;
012
013import org.hl7.fhir.dstu3.formats.IParser.OutputStyle;
014import org.hl7.fhir.dstu3.formats.JsonParser;
015import org.hl7.fhir.dstu3.formats.XmlParser;
016import org.hl7.fhir.dstu3.model.Bundle;
017import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
018import org.hl7.fhir.dstu3.model.DomainResource;
019import org.hl7.fhir.dstu3.model.Resource;
020import org.hl7.fhir.exceptions.FHIRFormatError;
021import org.hl7.fhir.utilities.Utilities;
022
023public class R3TEchnicalCorrectionProcessor {
024
025  public static void main(String[] args) throws FileNotFoundException, IOException {
026    new R3TEchnicalCorrectionProcessor().execute(args[0], args[1]);
027
028  }
029
030  private void execute(String src, String packageRoot) throws FileNotFoundException, IOException {
031    System.out.println("Loading resources from "+src);
032    List<Resource> resources = new ArrayList<>();
033    Map<String, Resource> definitions = new HashMap<>();
034    for (File f : new File(src).listFiles()) {
035      if (f.getName().endsWith(".xml") && !(f.getName().endsWith("warnings.xml") || f.getName().endsWith(".diff.xml"))) {
036        try {
037          Resource r = new XmlParser().parse(new FileInputStream(f));
038          if (f.getName().contains("canonical")) {
039            resources.add(r);
040          }
041          if (Utilities.existsInList(f.getName(), "conceptmaps.xml", "dataelements.xml", "extension-definitions.xml", "profiles-others.xml", "profiles-resources.xml", 
042                "profiles-types.xml", "search-parameters.xml", "v2-tables.xml", "v3-codesystems.xml", "valuesets.xml")) {
043            definitions.put(f.getName(), r);
044          }
045          r.setUserData("path", f.getName().substring(0, f.getName().indexOf(".")));
046//          FileUtils.copyFile(f, new File(f.getAbsolutePath()+"1"));
047//          FileUtils.copyFile(f, new File(f.getAbsolutePath()+"2"));
048        } catch (Exception e) {
049          System.out.println("Unable to load "+f.getName()+": "+e.getMessage());
050        }
051      }
052      if (f.getName().endsWith(".json") && !(f.getName().endsWith("schema.json") || f.getName().endsWith(".diff.json"))) {
053        try {
054//          new JsonParser().parse(new FileInputStream(f));
055//          FileUtils.copyFile(f, new File(f.getAbsolutePath()+"1"));
056//          FileUtils.copyFile(f, new File(f.getAbsolutePath()+"2"));
057        } catch (Exception e) {
058          System.out.println("Unable to load "+f.getName()+": "+e.getMessage());
059        }
060      }
061    }
062    System.out.println(Integer.toString(resources.size())+" resources");
063    System.out.println(Integer.toString(definitions.size())+" resources");
064    produceExamplesXml(resources, src);
065    produceDefinitionsXml(definitions, src);
066    produceExamplesJson(resources, src);
067    produceDefinitionsJson(definitions, src);
068    for (Resource r : definitions.values()) {
069      if (r instanceof Bundle) {
070        Bundle bnd = (Bundle) r;
071        for (BundleEntryComponent be : bnd.getEntry()) {
072          resources.add(be.getResource());
073        }
074      }
075    }
076    extractToPackageMaster(resources, packageRoot);
077    System.out.println("Done");
078  }
079
080  private void produceDefinitionsXml(Map<String, Resource> definitions, String dest) throws IOException {
081    for (String n : definitions.keySet()) {
082      File f = new File(Utilities.path(dest, "definitions.xml", n));
083      new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(f), definitions.get(n));     
084    }
085  }
086
087  private void produceDefinitionsJson(Map<String, Resource> definitions, String dest) throws IOException {
088    for (String n : definitions.keySet()) {
089      File f = new File(Utilities.path(dest, "definitions.json", Utilities.changeFileExt(n, ".json")));
090      new JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(f), definitions.get(n));     
091    }
092  }
093
094  private void produceExamplesJson(List<Resource> resources, String dest) throws FileNotFoundException, IOException {
095    for (Resource r : resources) {
096      String n = r.fhirType().toLowerCase()+"-"+r.getUserString("path");
097      if (!r.getId().equals(r.getUserString("path"))) {
098        n = n+"("+r.getId()+")";
099      }
100      File f = new File(Utilities.path(dest, "examples-json", n+".json"));
101      new JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(f), r);
102    }
103    
104  }
105
106  private void produceExamplesXml(List<Resource> resources, String dest) throws FileNotFoundException, IOException {
107    for (Resource r : resources) {
108      String n = r.fhirType().toLowerCase()+"-"+r.getUserString("path");
109      if (!r.getId().equals(r.getUserString("path"))) {
110        n = n+"("+r.getId()+")";
111      }
112      File f = new File(Utilities.path(dest, "examples", n+".xml"));
113      new XmlParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(f), r);
114    }
115  }
116
117  private void extractToPackageMaster(List<Resource> list, String root) throws IOException, FHIRFormatError {
118    System.out.println("Updating Packages Master");
119    String corePath = Utilities.path(root, "hl7.fhir.r3.core", "package");
120    String examplesPath = Utilities.path(root, "hl7.fhir.r3.examples", "package");
121    String elementsPath = Utilities.path(root, "hl7.fhir.r3.elements", "package");
122    int coreTotal = new File(corePath).list().length-1;
123    int examplesTotal = new File(examplesPath).list().length-1;
124    int elementsTotal = new File(elementsPath).list().length-1;
125        
126    int coreCount = 0;
127    int examplesCount = 0;
128    int elementsCount = 0;
129    for (Resource r : list) {
130      String n = r.fhirType()+"-"+r.getId()+".json";
131      FileOutputStream dst = null;
132        if (n.startsWith("DataElement-")) {
133          elementsCount++;
134          dst = new FileOutputStream(Utilities.path(elementsPath, n));
135          new JsonParser().setOutputStyle(OutputStyle.NORMAL).compose(dst, r);
136        } else {
137          dst = new FileOutputStream(Utilities.path(examplesPath, n));
138          new JsonParser().setOutputStyle(OutputStyle.NORMAL).compose(dst, r);
139          examplesCount++;
140          if (isCoreResource(r.fhirType())) {
141            coreCount++;
142            DomainResource dr = (DomainResource) r;
143            dr.setText(null);
144            new JsonParser().setOutputStyle(OutputStyle.NORMAL).compose(new FileOutputStream(Utilities.path(corePath, n)), r);
145          }
146        }
147    }
148    System.out.println("  Core @ "+corePath+": Replaced "+coreCount+" of "+coreTotal);
149    System.out.println("  Examples @ "+examplesPath+": Replaced "+examplesCount+" of "+examplesTotal);
150    System.out.println("  Elements @ "+elementsPath+": Replaced "+elementsCount+" of "+elementsTotal);
151  }
152  
153  private boolean isCoreResource(String rt) {
154    return Utilities.existsInList(rt, "CapabilityStatement", "CodeSystem", "CompartmentDefinition", "ConceptMap", "NamingSystem", "OperationDefinition", "SearchParameter", "StructureDefinition", "StructureMap", "ValueSet");
155  }
156
157}