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}