001package org.hl7.fhir.convertors.misc;
002
003import java.io.FileInputStream;
004import java.io.FileOutputStream;
005import java.util.ArrayList;
006import java.util.HashMap;
007import java.util.List;
008import java.util.Map;
009
010import javax.xml.parsers.DocumentBuilder;
011import javax.xml.parsers.DocumentBuilderFactory;
012
013/*
014  Copyright (c) 2011+, HL7, Inc.
015  All rights reserved.
016  
017  Redistribution and use in source and binary forms, with or without modification, 
018  are permitted provided that the following conditions are met:
019    
020   * Redistributions of source code must retain the above copyright notice, this 
021     list of conditions and the following disclaimer.
022   * Redistributions in binary form must reproduce the above copyright notice, 
023     this list of conditions and the following disclaimer in the documentation 
024     and/or other materials provided with the distribution.
025   * Neither the name of HL7 nor the names of its contributors may be used to 
026     endorse or promote products derived from this software without specific 
027     prior written permission.
028  
029  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
030  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
031  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
032  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
033  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
034  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
035  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
036  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
037  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
038  POSSIBILITY OF SUCH DAMAGE.
039  
040 */
041
042
043import org.hl7.fhir.dstu3.formats.IParser.OutputStyle;
044import org.hl7.fhir.dstu3.formats.XmlParser;
045import org.hl7.fhir.dstu3.model.CodeSystem;
046import org.hl7.fhir.dstu3.model.CodeSystem.CodeSystemHierarchyMeaning;
047import org.hl7.fhir.dstu3.model.CodeSystem.ConceptDefinitionComponent;
048import org.hl7.fhir.dstu3.model.Coding;
049import org.hl7.fhir.dstu3.model.DateTimeType;
050import org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus;
051import org.hl7.fhir.dstu3.model.Identifier;
052import org.hl7.fhir.dstu3.model.ValueSet;
053import org.hl7.fhir.dstu3.terminologies.CodeSystemUtilities;
054import org.hl7.fhir.exceptions.FHIRFormatError;
055import org.hl7.fhir.utilities.Utilities;
056import org.hl7.fhir.utilities.filesystem.ManagedFileAccess;
057import org.hl7.fhir.utilities.xml.XMLUtil;
058import org.w3c.dom.Document;
059import org.w3c.dom.Element;
060
061
062/**
063 * This is defined as a prototype ClaML importer
064 *
065 * @author Grahame
066 */
067
068public class ICPC2Importer {
069
070  private String sourceFileName; // the ICPC2 ClaML file
071  private String targetFileNameVS; // the value set to produce
072  private String targetFileNameCS; // the value set to produce
073
074  public ICPC2Importer() {
075    super();
076  }
077
078  public ICPC2Importer(String sourceFileName, String targetFileNameCS, String targetFileNameVS) {
079    super();
080    this.sourceFileName = sourceFileName;
081    this.targetFileNameCS = targetFileNameCS;
082    this.targetFileNameVS = targetFileNameVS;
083  }
084
085  public static void main(String[] args) {
086    try {
087      ICPC2Importer r = new ICPC2Importer();
088      r.setSourceFileName(Utilities.path("[tmp]", "ICPC-2e-v5.0.xml"));
089      r.setTargetFileNameCS(Utilities.path("[tmp]", "icpc2.xml"));
090      r.setTargetFileNameVS(Utilities.path("[tmp]", "icpc2-vs.xml"));
091      r.go();
092      System.out.println("Completed OK");
093    } catch (Exception e) {
094      e.printStackTrace();
095    }
096  }
097
098  public String getSourceFileName() {
099    return sourceFileName;
100  }
101
102  public void setSourceFileName(String sourceFileName) {
103    this.sourceFileName = sourceFileName;
104  }
105
106  public String getTargetFileNameCS() {
107    return targetFileNameCS;
108  }
109
110  public void setTargetFileNameCS(String targetFileName) {
111    this.targetFileNameCS = targetFileName;
112  }
113
114  public String getTargetFileNameVS() {
115    return targetFileNameVS;
116  }
117
118  public void setTargetFileNameVS(String targetFileName) {
119    this.targetFileNameVS = targetFileName;
120  }
121
122  public void go() throws Exception {
123    DocumentBuilderFactory factory = XMLUtil.newXXEProtectedDocumentBuilderFactory();
124    factory.setNamespaceAware(false);
125    DocumentBuilder builder = factory.newDocumentBuilder();
126    Document doc = builder.parse(ManagedFileAccess.inStream(sourceFileName));
127
128    ValueSet vs = new ValueSet();
129    vs.setUrl("http://hl7.org/fhir/sid/icpc2/vs");
130    Element title = XMLUtil.getNamedChild(doc.getDocumentElement(), "Title");
131    vs.setVersion(title.getAttribute("version"));
132    vs.setName(title.getAttribute("name"));
133    vs.setImmutable(true);
134    Element identifier = XMLUtil.getNamedChild(doc.getDocumentElement(), "Identifier");
135    vs.setPublisher(identifier.getAttribute("authority"));
136    vs.addIdentifier(new Identifier().setValue(identifier.getAttribute("uid")));
137    List<Element> authors = new ArrayList<Element>();
138    XMLUtil.getNamedChildren(XMLUtil.getNamedChild(doc.getDocumentElement(), "Authors"), "Author", authors);
139    for (Element a : authors)
140      if (!a.getAttribute("name").contains("+"))
141        vs.addContact().setName(a.getTextContent());
142    vs.setCopyright("The copyright of ICPC, both in hard copy and in electronic form, is owned by Wonca. See http://www.kith.no/templates/kith_WebPage____1110.aspx");
143    vs.setStatus(PublicationStatus.ACTIVE);
144    vs.setDateElement(new DateTimeType(title.getAttribute("date")));
145
146    vs.getCompose().addInclude().setSystem("http://hl7.org/fhir/sid/icpc2");
147    CodeSystem cs = new CodeSystem();
148    cs.setUrl("http://hl7.org/fhir/sid/icpc2");
149    cs.setVersion(title.getAttribute("version"));
150    cs.setName(title.getAttribute("name"));
151    identifier = XMLUtil.getNamedChild(doc.getDocumentElement(), "Identifier");
152    cs.setPublisher(identifier.getAttribute("authority"));
153    cs.setIdentifier(new Identifier().setValue(identifier.getAttribute("uid")));
154    cs.setHierarchyMeaning(CodeSystemHierarchyMeaning.CLASSIFIEDWITH);
155    authors = new ArrayList<Element>();
156    XMLUtil.getNamedChildren(XMLUtil.getNamedChild(doc.getDocumentElement(), "Authors"), "Author", authors);
157    for (Element a : authors)
158      if (!a.getAttribute("name").contains("+"))
159        cs.addContact().setName(a.getTextContent());
160    cs.setCopyright("The copyright of ICPC, both in hard copy and in electronic form, is owned by Wonca. See http://www.kith.no/templates/kith_WebPage____1110.aspx");
161    cs.setStatus(PublicationStatus.ACTIVE);
162    cs.setDateElement(new DateTimeType(title.getAttribute("date")));
163    cs.setValueSet(vs.getUrl());
164
165    Map<String, ConceptDefinitionComponent> concepts = new HashMap<String, ConceptDefinitionComponent>();
166    List<Element> classes = new ArrayList<Element>();
167    XMLUtil.getNamedChildren(doc.getDocumentElement(), "Class", classes);
168    for (Element cls : classes) {
169      processClass(cls, concepts, cs);
170    }
171
172    XmlParser xml = new XmlParser();
173    xml.setOutputStyle(OutputStyle.PRETTY);
174    xml.compose(ManagedFileAccess.outStream(targetFileNameVS), vs);
175    xml.compose(ManagedFileAccess.outStream(targetFileNameCS), cs);
176  }
177
178  private void processClass(Element cls, Map<String, ConceptDefinitionComponent> concepts, CodeSystem define) throws FHIRFormatError {
179    ConceptDefinitionComponent concept = new ConceptDefinitionComponent();
180    concept.setCode(cls.getAttribute("code"));
181    concept.setDefinition(getRubric(cls, "preferred"));
182    String s = getRubric(cls, "shortTitle");
183    if (s != null && !s.equals(concept.getDefinition()))
184      concept.addDesignation().setUse(new Coding().setSystem("http://hl7.org/fhir/sid/icpc2/rubrics").setCode("shortTitle")).setValue(s);
185    s = getRubric(cls, "inclusion");
186    if (s != null)
187      concept.addDesignation().setUse(new Coding().setSystem("http://hl7.org/fhir/sid/icpc2/rubrics").setCode("inclusion")).setValue(s);
188    s = getRubric(cls, "exclusion");
189    if (s != null)
190      concept.addDesignation().setUse(new Coding().setSystem("http://hl7.org/fhir/sid/icpc2/rubrics").setCode("exclusion")).setValue(s);
191    s = getRubric(cls, "criteria");
192    if (s != null)
193      concept.addDesignation().setUse(new Coding().setSystem("http://hl7.org/fhir/sid/icpc2/rubrics").setCode("criteria")).setValue(s);
194    s = getRubric(cls, "consider");
195    if (s != null)
196      concept.addDesignation().setUse(new Coding().setSystem("http://hl7.org/fhir/sid/icpc2/rubrics").setCode("consider")).setValue(s);
197    s = getRubric(cls, "note");
198    if (s != null)
199      concept.addDesignation().setUse(new Coding().setSystem("http://hl7.org/fhir/sid/icpc2/rubrics").setCode("note")).setValue(s);
200
201    concepts.put(concept.getCode(), concept);
202    List<Element> children = new ArrayList<Element>();
203    XMLUtil.getNamedChildren(cls, "SubClass", children);
204    if (children.size() > 0)
205      CodeSystemUtilities.setNotSelectable(define, concept);
206
207    Element parent = XMLUtil.getNamedChild(cls, "SuperClass");
208    if (parent == null) {
209      define.addConcept(concept);
210    } else {
211      ConceptDefinitionComponent p = concepts.get(parent.getAttribute("code"));
212      p.getConcept().add(concept);
213    }
214  }
215
216  private String getRubric(Element cls, String kind) {
217    List<Element> rubrics = new ArrayList<Element>();
218    XMLUtil.getNamedChildren(cls, "Rubric", rubrics);
219    for (Element r : rubrics) {
220      if (r.getAttribute("kind").equals(kind))
221        return XMLUtil.getNamedChild(r, "Label").getTextContent();
222    }
223    return null;
224  }
225
226}