001package org.hl7.fhir.convertors.misc; 002 003 004import java.io.FileInputStream; 005import java.io.FileNotFoundException; 006import java.io.FileOutputStream; 007import java.io.IOException; 008import java.util.HashMap; 009import java.util.Map; 010 011import org.fhir.ucum.Utilities; 012import org.hl7.fhir.exceptions.FHIRException; 013import org.hl7.fhir.r5.formats.IParser.OutputStyle; 014import org.hl7.fhir.r5.formats.JsonParser; 015import org.hl7.fhir.r5.model.BooleanType; 016import org.hl7.fhir.r5.model.CodeSystem; 017import org.hl7.fhir.r5.model.CodeSystem.CodeSystemHierarchyMeaning; 018import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent; 019import org.hl7.fhir.r5.model.CodeSystem.PropertyType; 020import org.hl7.fhir.r5.model.CodeType; 021import org.hl7.fhir.utilities.CSVReader; 022 023public class ICFImporter { 024 025 public static void main(String[] args) throws FHIRException, FileNotFoundException, IOException { 026 new ICFImporter().doImport(args[0], args[1]); 027 028 } 029 030 private void doImport(String src, String dst) throws FHIRException, FileNotFoundException, IOException { 031 CSVReader csv = new CSVReader(new FileInputStream(src)); 032 csv.setDelimiter('\t'); 033 csv.readHeaders(); 034 035 CodeSystem cs = new CodeSystem(); 036 cs.setId("icf"); 037 cs.setUrl("http://id.who.int/icd/release/11/beta/icf"); 038 cs.setVersion("2023-06"); 039 cs.setName("WHOICF"); 040 cs.setTitle("WHO ICF"); 041 cs.setHierarchyMeaning(CodeSystemHierarchyMeaning.CLASSIFIEDWITH); 042 cs.setCopyright("© World Health Organization 2022\r\nSome rights reserved. This work is available under the Creative Commons Attribution-NoDerivatives 3.0 IGO license (CC BY-ND 3.0 IGO further specified at [[https://icd.who.int/en/docs/ICD11-license.pdf]]). \r\nUnder the terms of this license, you may copy and redistribute the work, provided the work is appropriately cited, as indicated below. In any use of this work, there should be no suggestion that WHO endorses any specific organization, products or services. The use of the WHO logo is not permitted. This license does not allow you to produce adaptations of the work (including translations) without permission from WHO.\r\nAny mediation relating to disputes arising under the license shall be conducted in accordance with the mediation rules of the World Intellectual Property Organization.\r\nThis FHIR version of ICD-11 was generated to support the FHIR Community. The definitive version of ICD-11 is available from [[https://icd.who.int/browse11/l-m/en]].\r\n"); 043 044 cs.addProperty().setCode("icd11-uri").setDescription("Entity URI to map to ICD_11").setType(PropertyType.CODE); 045 cs.addProperty().setCode("kind").setDescription("Whether concept is chapter, block, or category").setType(PropertyType.CODE); 046 cs.addProperty().setCode("IsResidual").setDescription("True if the concept is not completely defined by ICD-11").setType(PropertyType.BOOLEAN); 047 Map<String, ConceptDefinitionComponent> codes = new HashMap<>(); 048 049 int lastChapter = 0; 050 int lastBlock = 0; 051 while (csv.line()) { 052 String kind = csv.cell("ClassKind"); 053 String code = csv.cell("Code"); 054 if (Utilities.noString(code)) { 055 code = csv.cell("BlockId"); 056 } 057 ConceptDefinitionComponent c = new ConceptDefinitionComponent(); 058 c.setCode(code); 059 c.setDisplay(fixDisplay(csv.cell("Title"))); 060 c.addProperty().setCode("uri").setValue(new CodeType(csv.cell("Linearization (release) URI"))); 061 c.addProperty().setCode("kind").setValue(new CodeType(kind)); 062 String b = csv.cell("IsResidual").toLowerCase(); 063 if (!"false".equals(b)) { 064 c.addProperty().setCode("IsResidual").setValue(new BooleanType(b)); 065 } 066 int level = Integer.parseInt(csv.cell("DepthInKind")); 067 String id = kind+"-"+level; 068 String parentId = null; 069 switch (kind) { 070 case "chapter": 071 parentId = null; 072 lastChapter = level; 073 break; 074 case "block": 075 parentId = "chapter-"+lastChapter; 076 lastBlock = level; 077 break; 078 case "category": 079 parentId = "block-"+lastBlock; 080 break; 081 } 082 if (level > 1) { 083 parentId = kind+"-"+(level - 1); 084 } 085 System.out.println(code+" "+kind+" "+level+" "+id+" "+parentId+" ("+lastChapter+" "+lastBlock+")"); 086 if (parentId == null) { 087 cs.getConcept().add(c); 088 } else { 089 ConceptDefinitionComponent p = codes.get(parentId); 090 p.getConcept().add(c); 091 } 092 codes.put(id, c); 093 for (int i = level + 1; i < 100; i++) { 094 if (codes.containsKey(i)) { 095 codes.remove(i); 096 } 097 } 098 099 } 100 csv.close(); 101 new JsonParser().setOutputStyle(OutputStyle.PRETTY).compose(new FileOutputStream(dst), cs); 102 } 103// 104// private String processLink(String cell) { 105// String[] p = cell.split("\\\"\\\""); 106// return p[1]; 107// } 108 109 private String fixDisplay(String cell) { 110 int i = 0; 111 while (i < cell.length() && (cell.charAt(i) == ' ' || cell.charAt(i) == '-')) { 112 i++; 113 } 114 return cell.substring(i); 115 } 116 117}