
001package org.hl7.fhir.r5.renderers.spreadsheets; 002 003import java.io.FileOutputStream; 004import java.io.IOException; 005import java.io.OutputStream; 006import java.util.List; 007 008import org.apache.poi.ss.usermodel.Row; 009import org.apache.poi.ss.usermodel.Sheet; 010import org.hl7.fhir.exceptions.DefinitionException; 011import org.hl7.fhir.r5.context.IWorkerContext; 012import org.hl7.fhir.r5.context.SimpleWorkerContext; 013import org.hl7.fhir.r5.model.CanonicalType; 014import org.hl7.fhir.r5.model.CodeSystem; 015import org.hl7.fhir.r5.model.CodeSystem.CodeSystemFilterComponent; 016import org.hl7.fhir.r5.model.CodeSystem.ConceptDefinitionComponent; 017import org.hl7.fhir.r5.model.CodeSystem.PropertyComponent; 018import org.hl7.fhir.r5.model.ElementDefinition; 019import org.hl7.fhir.r5.model.Enumeration; 020import org.hl7.fhir.r5.model.Enumerations.FilterOperator; 021import org.hl7.fhir.r5.model.ValueSet; 022import org.hl7.fhir.r5.model.ValueSet.ConceptReferenceComponent; 023import org.hl7.fhir.r5.model.ValueSet.ConceptSetComponent; 024import org.hl7.fhir.r5.model.ValueSet.ConceptSetFilterComponent; 025import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent; 026import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionParameterComponent; 027import org.hl7.fhir.r5.model.StructureDefinition.StructureDefinitionMappingComponent; 028import org.hl7.fhir.utilities.CommaSeparatedStringBuilder; 029import org.hl7.fhir.utilities.MarkedToMoveToAdjunctPackage; 030import org.hl7.fhir.utilities.i18n.I18nConstants; 031 032@MarkedToMoveToAdjunctPackage 033public class CodeSystemSpreadsheetGenerator extends CanonicalSpreadsheetGenerator { 034 035 public CodeSystemSpreadsheetGenerator(IWorkerContext context) { 036 super(context); 037 } 038 039 public boolean canGenerate(CodeSystem cs) { 040 return true; 041 } 042 043 public CodeSystemSpreadsheetGenerator renderCodeSystem(CodeSystem cs) throws IOException { 044 if (cs == null) { 045 System.out.println("no code system!"); 046 } 047 addCodeSystemMetadata(renderCanonicalResource(cs, false), cs); 048 049 if (cs.hasProperty()) { 050 addProperties(cs.getProperty()); 051 } 052 if (cs.hasFilter()) { 053 addFilters(cs.getFilter()); 054 } 055 if (cs.hasConcept()) { 056 addConcepts(cs.getConcept()); 057 } 058 return this; 059 } 060 061 private void addCodeSystemMetadata(Sheet sheet, CodeSystem cs) { 062 addMetadataRow(sheet, "Case Sensitive", cs.getCaseSensitiveElement().asStringValue()); 063 addMetadataRow(sheet, "Value Set (all codes)", cs.getValueSet()); 064 addMetadataRow(sheet, "Hierarchy", cs.getHierarchyMeaningElement().asStringValue()); 065 addMetadataRow(sheet, "Compositional", cs.getCompositionalElement().asStringValue()); 066 addMetadataRow(sheet, "Version Needed?", cs.getVersionNeededElement().asStringValue()); 067 addMetadataRow(sheet, "Content", cs.getContentElement().asStringValue()); 068 addMetadataRow(sheet, "Supplements", cs.getSupplements()); 069 addMetadataRow(sheet, "Count", cs.getCountElement().asStringValue()); 070 } 071 072 private void addFilters(List<CodeSystemFilterComponent> filters) { 073 Sheet sheet = makeSheet("Filters"); 074 addHeaders(sheet, "Code", "Description", "Operators", "Value"); 075 for (CodeSystemFilterComponent f : filters) { 076 CommaSeparatedStringBuilder cs = new CommaSeparatedStringBuilder(); 077 for (Enumeration<FilterOperator> op : f.getOperator()) { 078 cs.append(op.asStringValue()); 079 } 080 addRow(sheet, f.getCode(), f.getDescription(), cs.toString(), f.getValue()); 081 } 082 } 083 084 private void addProperties(List<PropertyComponent> properties) { 085 Sheet sheet = makeSheet("Properties"); 086 addHeaders(sheet, "Code", "Uri", "Description", "Type"); 087 for (PropertyComponent p : properties) { 088 addRow(sheet, p.getCode(), p.getUri(), p.getDescription(), p.getTypeElement().asStringValue()); 089 } 090 } 091 092 private void addConcepts(List<ConceptDefinitionComponent> concepts) { 093 Sheet sheet = makeSheet("Concepts"); 094 addHeaders(sheet, "Level", "Code", "Display", "Definition"); //todo: properties and designations 095 addConcepts(sheet, 1, concepts); 096 } 097 098 private void addConcepts(Sheet sheet, int i, List<ConceptDefinitionComponent> concepts) { 099 for (ConceptDefinitionComponent c : concepts) { 100 addRow(sheet, Integer.toString(i), c.getCode(), c.getDisplay(), c.getDefinition()); 101 if (c.hasConcept()) { 102 addConcepts(sheet, i+1, c.getConcept()); 103 } 104 } 105 } 106 107 private void genExpansionParams(List<ValueSetExpansionParameterComponent> params) { 108 Sheet sheet = makeSheet("Expansion Parameters"); 109 addHeaders(sheet, "Parameter", "Value"); 110 for (ValueSetExpansionParameterComponent p : params) { 111 addRow(sheet, p.getName(), dr.displayDataType(p.getValue())); 112 } 113 } 114 115 private void genExpansion(List<ValueSetExpansionContainsComponent> list) { 116 Sheet sheet = makeSheet("Expansion"); 117 addHeaders(sheet, "Level", "System", "version", "Code", "Display", "Abstract", "Inactive"); 118 genExpansionEntry(1, list, sheet); 119 } 120 121 public void genExpansionEntry(int level, List<ValueSetExpansionContainsComponent> list, Sheet sheet) { 122 for (ValueSetExpansionContainsComponent p : list) { 123 addRow(sheet, Integer.toString(level), p.getSystem(), p.getVersion(), p.getCode(), p.getDisplay(), bool(p.getAbstract()), bool(p.getInactive())); 124 if (p.hasContains()) { 125 genExpansionEntry(level + 1, p.getContains(), sheet); 126 } 127 } 128 } 129 130 private String bool(boolean value) { 131 return value ? "" : "false"; 132 } 133 134// private void genInclude(ValueSet vs, ConceptSetComponent inc, String mode) { 135// if (inc.hasSystem()) { 136// genIncludeSystem(vs, inc, mode); 137// } else { 138// genIncludeValueSets(vs, inc, mode); 139// } 140// String subname = inc.hasSystem() ? : "ValueSets"; 141// 142// 143// Row headerRow = sheet.createRow(0); 144// for (int i = 0; i < titles.length; i++) { 145// addCell(headerRow, i, titles[i], styles.get("header")); 146// } 147// int i = titles.length - 1; 148// for (StructureDefinitionMappingComponent map : sd.getMapping()) { 149// i++; 150// addCell(headerRow, i, "Mapping: " + map.getName(), styles.get("header")); 151// } 152// 153// for (ElementDefinition child : sd.getSnapshot().getElement()) { 154// processElement(sheet, sd, child); 155// } 156// configureSheet(sheet, sd); 157// } 158 159// private void genIncludeValueSets(ValueSet vs, ConceptSetComponent inc, String mode) { 160// Sheet sheet = makeSheet(mode+" ValueSets"); 161// addValueSets(sheet, inc.getValueSet()); 162// configureSheet(sheet); 163// } 164// 165// private void genIncludeSystem(ValueSet vs, ConceptSetComponent inc, String mode) { 166// Sheet sheet = makeSheet(mode+" from "+dr.displaySystem(inc.getSystem())); 167// if (inc.hasValueSet()) { 168// addValueSets(sheet, inc.getValueSet()); 169// } 170// if (inc.hasFilter()) { 171// addFilters(sheet, inc.getFilter()); 172// } 173// if (inc.hasConcept()) { 174// addConcepts(sheet, inc.getConcept()); 175// } 176// if (!inc.hasConcept() && !inc.hasFilter()) { 177// addAllCodes(sheet); 178// } 179// addRow(sheet, "", ""); 180// addRow(sheet, "System URI", inc.getSystem()); 181// 182// configureSheet(sheet); 183// } 184 185 private void addAllCodes(Sheet sheet) { 186 addHeaders(sheet, "Codes"); 187 addRow(sheet, "All codes"); 188 } 189 190 private void addValueSets(Sheet sheet, List<CanonicalType> valueSets) { 191 addHeaders(sheet, "ValueSet URL"); 192 for (CanonicalType u : valueSets) { 193 addRow(sheet, u.getValue()); 194 } 195 } 196 197 private void configureSheet(Sheet sheet) { 198 sheet.setColumnWidth(0, columnPixels(30)); 199 sheet.setColumnWidth(1, columnPixels(40)); 200 sheet.setColumnWidth(1, columnPixels(50)); 201 } 202 203 private void addConcepts(Sheet sheet, List<ConceptReferenceComponent> concepts) { 204 addHeaders(sheet, "Concept", "Description"); // todo: designations 205 for (ConceptReferenceComponent cd : concepts) { 206 addRow(sheet, cd.getCode(), cd.getDisplay()); 207 } 208 } 209 210 private void addFilters(Sheet sheet, List<ConceptSetFilterComponent> filters) { 211 addHeaders(sheet, "Property", "Operation", "Value"); 212 for (ConceptSetFilterComponent f : filters) { 213 addRow(sheet, f.getProperty(), f.getOpElement().asStringValue(), f.getValue()); 214 } 215 } 216 217}