001package org.hl7.fhir.convertors.misc;
002
003import java.io.FileInputStream;
004import java.io.FileNotFoundException;
005import java.io.FileOutputStream;
006import java.io.IOException;
007import java.sql.SQLException;
008import java.util.Collections;
009import java.util.Comparator;
010import java.util.Date;
011
012import javax.xml.parsers.ParserConfigurationException;
013
014import org.fhir.ucum.Utilities;
015import org.hl7.fhir.convertors.misc.CVXImporter.CVXSorter;
016import org.hl7.fhir.exceptions.FHIRException;
017import org.hl7.fhir.exceptions.FHIRFormatError;
018import org.hl7.fhir.r4.formats.IParser.OutputStyle;
019import org.hl7.fhir.r4.formats.JsonParser;
020import org.hl7.fhir.r4.model.CodeSystem;
021import org.hl7.fhir.r4.model.CodeSystem.ConceptDefinitionComponent;
022import org.hl7.fhir.r4.model.CodeType;
023import org.hl7.fhir.r4.model.Coding;
024import org.hl7.fhir.r4.model.DateTimeType;
025import org.hl7.fhir.r4.model.StringType;
026import org.hl7.fhir.r4.terminologies.CodeSystemUtilities;
027import org.hl7.fhir.utilities.filesystem.ManagedFileAccess;
028import org.hl7.fhir.utilities.xml.XMLUtil;
029import org.w3c.dom.Document;
030import org.w3c.dom.Element;
031import org.xml.sax.SAXException;
032
033/**
034 * To use this class, download the CVX definitions from 
035 * https://www2a.cdc.gov/vaccines/iis/iisstandards/vaccines.asp?rpt=cvx
036 * using the XML-new format, and then execute this class with two parameters:
037 * - the name of the downloaded file
038 * - a local name for the file https://github.com/FHIR/packages/blob/master/packages/fhir.tx.support.r4/package/CodeSystem-cvx.json
039 * 
040 * //.Users/grahamegrieve/work/packages/packages/fhir.tx.support.r4/package/CodeSystem-cvx.json
041 */
042
043public class CVXImporter {
044
045  public class CVXSorter implements Comparator<ConceptDefinitionComponent> {
046
047    @Override
048    public int compare(ConceptDefinitionComponent o1, ConceptDefinitionComponent o2) {
049      int i1 = Integer.parseInt(o1.getCode());
050      int i2 = Integer.parseInt(o2.getCode());
051      return i1-i2;
052    }
053
054  }
055
056  public static void main(String[] args) throws FHIRException, FileNotFoundException, IOException, ClassNotFoundException, SQLException, ParserConfigurationException, SAXException {
057    new CVXImporter().doUpdate(args[0], args[1]);
058
059  }
060
061  private void doUpdate(String source, String dest) throws FHIRFormatError, FileNotFoundException, IOException, ParserConfigurationException, SAXException {
062    CodeSystem cvx = (CodeSystem) new JsonParser().parse(ManagedFileAccess.inStream(dest));
063    
064    String ldate = null;
065    
066    Document xml = XMLUtil.parseFileToDom(source);
067    Element cvxCodes = xml.getDocumentElement();
068    for (Element cvsInfo : XMLUtil.getNamedChildren(cvxCodes, "CVXInfo")) {
069      String desc = XMLUtil.getNamedChildText(cvsInfo, "ShortDescription").trim();
070      String fullName = XMLUtil.getNamedChildText(cvsInfo, "FullVaccinename").trim();
071      String code = XMLUtil.getNamedChildText(cvsInfo, "CVXCode").trim();
072      String notes = XMLUtil.getNamedChildText(cvsInfo, "Notes");
073      String status = XMLUtil.getNamedChildText(cvsInfo, "Status").trim();
074      String date = XMLUtil.getNamedChildText(cvsInfo, "LastUpdated").trim();
075      ConceptDefinitionComponent def = findCVXCode(cvx, code);
076      if (def == null) {
077        def = cvx.addConcept();
078        def.setCode(code);
079      } else {
080        def.getDesignation().clear();
081      }
082      def.setDisplay(desc);
083      def.addDesignation().setValue(fullName).setLanguage("en").setUse(new Coding().setSystem("http://snomed.info/sct").setCode("900000000000013009").setDisplay("Synonym"));
084      if (!Utilities.noString(notes)) {
085        def.forceProperty("notes").setValue(new StringType(notes.trim()));
086      }
087      def.forceProperty("vaccine-status").setValue(new CodeType(status.trim()));
088      String[] d = date.split("\\/");
089      String vdate = d[2]+"-"+Utilities.padLeft(d[0], '0', 2)+"-"+Utilities.padLeft(d[1], '0', 2);
090      def.forceProperty("last-updated").setValue(new DateTimeType(vdate));
091      if (ldate == null || ldate.compareTo(vdate) < 0) {
092        ldate = vdate;
093      }
094    }
095    Collections.sort(cvx.getConcept(), new CVXSorter());
096    cvx.setDateElement(new DateTimeType(ldate));
097    cvx.setVersion(ldate.replace("-", ""));
098    new JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(ManagedFileAccess.outStream(dest), cvx);
099  }
100
101  private ConceptDefinitionComponent findCVXCode(CodeSystem cvx, String code) {
102    for (ConceptDefinitionComponent t : cvx.getConcept()) {
103      if (code.equals(t.getCode())) {
104        return t;
105      }
106    }
107    return null;
108  }
109}