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