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.xml.XMLUtil;
057import org.w3c.dom.Document;
058import org.w3c.dom.Element;
059
060
061/**
062 * This is defined as a prototype ClaML importer
063 *
064 * @author Grahame
065 */
066
067public class ICPC2Importer {
068
069  private String sourceFileName; // the ICPC2 ClaML file
070  private String targetFileNameVS; // the value set to produce
071  private String targetFileNameCS; // the value set to produce
072
073  public ICPC2Importer() {
074    super();
075  }
076
077  public ICPC2Importer(String sourceFileName, String targetFileNameCS, String targetFileNameVS) {
078    super();
079    this.sourceFileName = sourceFileName;
080    this.targetFileNameCS = targetFileNameCS;
081    this.targetFileNameVS = targetFileNameVS;
082  }
083
084  public static void main(String[] args) {
085    try {
086      ICPC2Importer r = new ICPC2Importer();
087      r.setSourceFileName(Utilities.path("[tmp]", "ICPC-2e-v5.0.xml"));
088      r.setTargetFileNameCS(Utilities.path("[tmp]", "icpc2.xml"));
089      r.setTargetFileNameVS(Utilities.path("[tmp]", "icpc2-vs.xml"));
090      r.go();
091      System.out.println("Completed OK");
092    } catch (Exception e) {
093      e.printStackTrace();
094    }
095  }
096
097  public String getSourceFileName() {
098    return sourceFileName;
099  }
100
101  public void setSourceFileName(String sourceFileName) {
102    this.sourceFileName = sourceFileName;
103  }
104
105  public String getTargetFileNameCS() {
106    return targetFileNameCS;
107  }
108
109  public void setTargetFileNameCS(String targetFileName) {
110    this.targetFileNameCS = targetFileName;
111  }
112
113  public String getTargetFileNameVS() {
114    return targetFileNameVS;
115  }
116
117  public void setTargetFileNameVS(String targetFileName) {
118    this.targetFileNameVS = targetFileName;
119  }
120
121  public void go() throws Exception {
122    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
123    factory.setNamespaceAware(false);
124    DocumentBuilder builder = factory.newDocumentBuilder();
125    Document doc = builder.parse(new FileInputStream(sourceFileName));
126
127    ValueSet vs = new ValueSet();
128    vs.setUrl("http://hl7.org/fhir/sid/icpc2/vs");
129    Element title = XMLUtil.getNamedChild(doc.getDocumentElement(), "Title");
130    vs.setVersion(title.getAttribute("version"));
131    vs.setName(title.getAttribute("name"));
132    vs.setImmutable(true);
133    Element identifier = XMLUtil.getNamedChild(doc.getDocumentElement(), "Identifier");
134    vs.setPublisher(identifier.getAttribute("authority"));
135    vs.addIdentifier(new Identifier().setValue(identifier.getAttribute("uid")));
136    List<Element> authors = new ArrayList<Element>();
137    XMLUtil.getNamedChildren(XMLUtil.getNamedChild(doc.getDocumentElement(), "Authors"), "Author", authors);
138    for (Element a : authors)
139      if (!a.getAttribute("name").contains("+"))
140        vs.addContact().setName(a.getTextContent());
141    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");
142    vs.setStatus(PublicationStatus.ACTIVE);
143    vs.setDateElement(new DateTimeType(title.getAttribute("date")));
144
145    vs.getCompose().addInclude().setSystem("http://hl7.org/fhir/sid/icpc2");
146    CodeSystem cs = new CodeSystem();
147    cs.setUrl("http://hl7.org/fhir/sid/icpc2");
148    cs.setVersion(title.getAttribute("version"));
149    cs.setName(title.getAttribute("name"));
150    identifier = XMLUtil.getNamedChild(doc.getDocumentElement(), "Identifier");
151    cs.setPublisher(identifier.getAttribute("authority"));
152    cs.setIdentifier(new Identifier().setValue(identifier.getAttribute("uid")));
153    cs.setHierarchyMeaning(CodeSystemHierarchyMeaning.CLASSIFIEDWITH);
154    authors = new ArrayList<Element>();
155    XMLUtil.getNamedChildren(XMLUtil.getNamedChild(doc.getDocumentElement(), "Authors"), "Author", authors);
156    for (Element a : authors)
157      if (!a.getAttribute("name").contains("+"))
158        cs.addContact().setName(a.getTextContent());
159    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");
160    cs.setStatus(PublicationStatus.ACTIVE);
161    cs.setDateElement(new DateTimeType(title.getAttribute("date")));
162    cs.setValueSet(vs.getUrl());
163
164    Map<String, ConceptDefinitionComponent> concepts = new HashMap<String, ConceptDefinitionComponent>();
165    List<Element> classes = new ArrayList<Element>();
166    XMLUtil.getNamedChildren(doc.getDocumentElement(), "Class", classes);
167    for (Element cls : classes) {
168      processClass(cls, concepts, cs);
169    }
170
171    XmlParser xml = new XmlParser();
172    xml.setOutputStyle(OutputStyle.PRETTY);
173    xml.compose(new FileOutputStream(targetFileNameVS), vs);
174    xml.compose(new FileOutputStream(targetFileNameCS), cs);
175  }
176
177  private void processClass(Element cls, Map<String, ConceptDefinitionComponent> concepts, CodeSystem define) throws FHIRFormatError {
178    ConceptDefinitionComponent concept = new ConceptDefinitionComponent();
179    concept.setCode(cls.getAttribute("code"));
180    concept.setDefinition(getRubric(cls, "preferred"));
181    String s = getRubric(cls, "shortTitle");
182    if (s != null && !s.equals(concept.getDefinition()))
183      concept.addDesignation().setUse(new Coding().setSystem("http://hl7.org/fhir/sid/icpc2/rubrics").setCode("shortTitle")).setValue(s);
184    s = getRubric(cls, "inclusion");
185    if (s != null)
186      concept.addDesignation().setUse(new Coding().setSystem("http://hl7.org/fhir/sid/icpc2/rubrics").setCode("inclusion")).setValue(s);
187    s = getRubric(cls, "exclusion");
188    if (s != null)
189      concept.addDesignation().setUse(new Coding().setSystem("http://hl7.org/fhir/sid/icpc2/rubrics").setCode("exclusion")).setValue(s);
190    s = getRubric(cls, "criteria");
191    if (s != null)
192      concept.addDesignation().setUse(new Coding().setSystem("http://hl7.org/fhir/sid/icpc2/rubrics").setCode("criteria")).setValue(s);
193    s = getRubric(cls, "consider");
194    if (s != null)
195      concept.addDesignation().setUse(new Coding().setSystem("http://hl7.org/fhir/sid/icpc2/rubrics").setCode("consider")).setValue(s);
196    s = getRubric(cls, "note");
197    if (s != null)
198      concept.addDesignation().setUse(new Coding().setSystem("http://hl7.org/fhir/sid/icpc2/rubrics").setCode("note")).setValue(s);
199
200    concepts.put(concept.getCode(), concept);
201    List<Element> children = new ArrayList<Element>();
202    XMLUtil.getNamedChildren(cls, "SubClass", children);
203    if (children.size() > 0)
204      CodeSystemUtilities.setNotSelectable(define, concept);
205
206    Element parent = XMLUtil.getNamedChild(cls, "SuperClass");
207    if (parent == null) {
208      define.addConcept(concept);
209    } else {
210      ConceptDefinitionComponent p = concepts.get(parent.getAttribute("code"));
211      p.getConcept().add(concept);
212    }
213  }
214
215  private String getRubric(Element cls, String kind) {
216    List<Element> rubrics = new ArrayList<Element>();
217    XMLUtil.getNamedChildren(cls, "Rubric", rubrics);
218    for (Element r : rubrics) {
219      if (r.getAttribute("kind").equals(kind))
220        return XMLUtil.getNamedChild(r, "Label").getTextContent();
221    }
222    return null;
223  }
224
225}