001package org.hl7.fhir.convertors.misc;
002
003import java.io.ByteArrayInputStream;
004import java.io.File;
005import java.io.FileOutputStream;
006import java.io.IOException;
007import java.text.ParseException;
008import java.text.SimpleDateFormat;
009import java.util.List;
010
011import org.hl7.fhir.exceptions.FHIRException;
012import org.hl7.fhir.r5.context.ContextUtilities;
013import org.hl7.fhir.r5.formats.IParser.OutputStyle;
014import org.hl7.fhir.r5.formats.JsonParser;
015import org.hl7.fhir.r5.model.Enumerations.PublicationStatus;
016import org.hl7.fhir.r5.model.ValueSet;
017import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent;
018import org.hl7.fhir.utilities.CSVReader;
019import org.hl7.fhir.utilities.TextFile;
020import org.hl7.fhir.utilities.Utilities;
021
022public class PhinVadsImporter extends OIDBasedValueSetImporter {
023
024  public PhinVadsImporter() throws FHIRException, IOException {
025    super();
026    init();
027  }
028
029  public static void main(String[] args) throws FHIRException, IOException, ParseException {
030//    new PhinVadsImporter().importValueSet(TextFile.fileToBytes("C:\\work\\org.hl7.fhir\\packages\\us.cdc.phinvads-source\\source\\PHVS_BirthDefectsLateralityatDiagnosis_HL7_V1.txt"));
031    PhinVadsImporter self = new PhinVadsImporter();
032    self.process(args[0], args[1]);
033  }
034
035  private void process(String source, String dest) {
036    for (File f : new File(source).listFiles()) {
037      try {
038        System.out.println("Process " + f.getName());
039        ValueSet vs = importValueSet(TextFile.fileToBytes(f));
040        if (vs.getId() != null) {
041          new JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(Utilities.path(dest, "ValueSet-" + vs.getId() + ".json")), vs);
042        }
043      } catch (Exception e) {
044        e.printStackTrace();
045      }
046    }
047  }
048
049  private ValueSet importValueSet(byte[] source) throws FHIRException, IOException, ParseException {
050    // first thing do is split into 2 
051    List<byte[]> parts = Utilities.splitBytes(source, "\r\n\r\n".getBytes());
052    if (parts.size() < 2) {
053      TextFile.bytesToFile(source, Utilities.path("[tmp]", "phinvads.txt"));
054      throw new FHIRException("Unable to parse phinvads value set: " + parts.size() + " parts found");
055    }
056    CSVReader rdr = new CSVReader(new ByteArrayInputStream(parts.get(0)));
057    rdr.setDelimiter('\t');
058    rdr.setMultiline(true);
059    rdr.readHeaders();
060    rdr.line();
061
062    ValueSet vs = new ValueSet();
063    vs.setId(rdr.cell("Value Set OID"));
064    vs.setUrl("http://phinvads.cdc.gov/fhir/ValueSet/" + vs.getId());
065    vs.getMeta().setSource("https://phinvads.cdc.gov/vads/ViewValueSet.action?oid=" + vs.getId());
066    vs.setVersion(rdr.cell("Value Set Version"));
067    vs.setTitle(rdr.cell("Value Set Name"));
068    vs.setName(rdr.cell("Value Set Code"));
069    vs.setDescription(rdr.cell("Value Set Definition"));
070    if ("Published".equals(rdr.cell("Value Set Status"))) {
071      vs.setStatus(PublicationStatus.ACTIVE);
072    } else {
073      vs.setStatus(PublicationStatus.DRAFT);
074    }
075    if (rdr.has("VS Last Updated Date")) {
076      vs.setDate(new SimpleDateFormat("mm/dd/yyyy").parse(rdr.cell("VS Last Updated Date")));
077    }
078
079    rdr = new CSVReader(new ByteArrayInputStream(parts.get(parts.size() - 1)));
080    rdr.setMultiline(true);
081    rdr.setDelimiter('\t');
082    rdr.readHeaders();
083    while (rdr.line()) {
084      String code = rdr.cell("Concept Code");
085      String display = rdr.cell("Preferred Concept Name");
086      String csoid = rdr.cell("Code System OID");
087      String csver = rdr.cell("Code System Version");
088      String url = new ContextUtilities(context).oid2Uri(csoid);
089      if (url == null) {
090        url = "urn:oid:" + csoid;
091      }
092      csver = fixVersionforSystem(url, csver);
093      ConceptSetComponent inc = getInclude(vs, url, csver);
094      inc.addConcept().setCode(code).setDisplay(display);
095    }
096    return vs;
097  }
098
099
100}