
001package org.hl7.fhir.r5.renderers; 002 003import java.io.IOException; 004import java.io.UnsupportedEncodingException; 005import java.util.List; 006 007import org.hl7.fhir.exceptions.DefinitionException; 008import org.hl7.fhir.exceptions.FHIRException; 009import org.hl7.fhir.exceptions.FHIRFormatError; 010import org.hl7.fhir.r5.model.StructureDefinition; 011import org.hl7.fhir.r5.renderers.utils.RenderingContext; 012import org.hl7.fhir.r5.renderers.utils.ResourceWrapper; 013import org.hl7.fhir.r5.utils.EOperationOutcome; 014 015import org.hl7.fhir.utilities.MarkedToMoveToAdjunctPackage; 016import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator; 017import org.hl7.fhir.utilities.xhtml.NodeType; 018import org.hl7.fhir.utilities.xhtml.XhtmlNode; 019import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Cell; 020import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Piece; 021import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Row; 022 023@MarkedToMoveToAdjunctPackage 024public class FeatureDefinitionRenderer extends ResourceRenderer { 025 026 public FeatureDefinitionRenderer(RenderingContext context) { 027 super(context); 028 } 029 030 @Override 031 public boolean renderingUsesValidation() { 032 return true; 033 } 034 035 @Override 036 public String buildSummary(ResourceWrapper r) throws UnsupportedEncodingException, IOException { 037 return canonicalTitle(r); 038 } 039 040 @Override 041 public void buildNarrative(RenderingStatus status, XhtmlNode x, ResourceWrapper fd) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome { 042 renderResourceTechDetails(fd, x); 043 genSummaryTable(status, x, fd); 044 045 XhtmlNode tbl = x.table("grid", false).markGenerated(!context.forValidResource()); 046 047 XhtmlNode td = tbl.tr().td(); 048 td.tx("Feature "); 049 td.code().tx(fd.primitiveValue("url")); 050 051 addMarkdown(tbl.tr().td(), fd.primitiveValue("description")); 052 053 td = tbl.tr().td(); 054 td.b().tx("Type: "); 055 td.tx(fd.primitiveValue("valueType")); 056 057 td = tbl.tr().td(); 058 td.b().tx("Contexts"); 059 XhtmlNode ul = td.ul(); 060 for (ResourceWrapper c : fd.children("context")) { 061 String url = c.primitiveValue(); 062 var li = ul.li(); 063 if (url.contains("#")) { 064 String type = url.substring(0, url.indexOf("#")); 065 String id = url.substring(url.indexOf("#")+1); 066 StructureDefinition sd = context.getContext().fetchTypeDefinition(type); 067 if (sd != null && sd.hasWebPath()) { 068 li.ah(sd.getWebPath()).tx(sd.present()); 069 } else { 070 li.tx(url); 071 } 072 if (id != null) { 073 li.tx(" element "); 074 li.code().tx(id); 075 } 076 } else { 077 li.tx(url); 078 } 079 } 080 td = tbl.tr().td(); 081 if (fd.has("qualifier")) { 082 td.b().tx("Qualifiers"); 083 084 XhtmlNode tbl2 = td.table("lines", false).markGenerated(!context.forValidResource()); 085 XhtmlNode tr = tbl2.tr(); 086 tr.td().b().tx("Name"); 087 tr.td().b().tx("Type"); 088 tr.td().b().tx("Optional"); 089 tr.td().b().tx("Description"); 090 for (ResourceWrapper q : fd.children("qualifier")) { 091 tr = tbl2.tr(); 092 tr.td().tx(q.primitiveValue("name")); 093 tr.td().tx(q.primitiveValue("valueType")); 094 tr.td().tx(q.primitiveValue("optional")); 095 tr.td().tx(q.primitiveValue("description")); 096 097 } 098 } else { 099 td.tx("This feature doesn't have any qualifiers"); 100 } 101 102 } 103 104 private void renderSelect(RenderingStatus status, HierarchicalTableGenerator gen, List<Row> rows, ResourceWrapper vd, ResourceWrapper select) { 105 Row r = gen.new Row(); 106 rows.add(r); 107 108 r.setIcon("icon_vd_select.png", "Select"); 109 Cell c1 = gen.new Cell(null, null, "Select", null, null); 110 r.getCells().add(c1); 111 r.getCells().add(gen.new Cell(null, null, null, null, null)); 112 r.getCells().add(gen.new Cell(null, null, null, null, null)); 113 Cell cell = gen.new Cell(null, null, null, null, null); 114 if (select.has("forEach")) { 115 addFHIRPath(cell.getPieces().get(0), "for each ", select.primitiveValue("forEach"), null); 116 } else if (select.has("forEachOrNull")) { 117 addFHIRPath(cell.getPieces().get(0), "for each ", select.primitiveValue("forEachOrNull"), ", or null"); 118 } else { 119 } 120 r.getCells().add(cell); 121 122 for (ResourceWrapper column : select.children("column")) { 123 renderColumn(status, gen, r.getSubRows(), vd, select, column); 124 } 125 126 for (ResourceWrapper child : select.children("select")) { 127 renderSelect(status, gen, r.getSubRows(), vd, child); 128 } 129 130 } 131 132 private void renderColumn(RenderingStatus status, HierarchicalTableGenerator gen, List<Row> rows, ResourceWrapper vd, ResourceWrapper select, ResourceWrapper column) { 133 Row r = gen.new Row(); 134 rows.add(r); 135 136 r.setIcon("icon_vd_col.png", "Column"); 137 Cell c1 = gen.new Cell(null, null, column.primitiveValue("name"), null, null); 138 r.getCells().add(c1); 139 String coll = column.has("collection") ? "true".equals(column.primitiveValue("collection")) ? "Y" : "N" : ""; 140 r.getCells().add(gen.new Cell(null, null, coll, null, null)); 141 r.getCells().add(gen.new Cell(null, null, column.primitiveValue("type"), null, null)); 142 Cell cell = gen.new Cell(null, null, null, null, null); 143 addFHIRPath(cell.getPieces().get(0), null, column.primitiveValue("path"), null); 144 if (column.has("description")) { 145 cell.addPiece(gen.new Piece("br")); 146 cell.addPiece(gen.new Piece(null, column.primitiveValue("description"), null)); 147 } 148 for (ResourceWrapper tag : column.children("tag")) { 149 cell.addPiece(gen.new Piece("br")); 150 cell.addPiece(gen.new Piece(null, tag.primitiveValue("name")+"="+tag.primitiveValue("value"), null)); 151 } 152 r.getCells().add(cell); 153 } 154 155 private void addFHIRPath(Piece p, String pfx, String expr, String sfx) { 156 XhtmlNode x = new XhtmlNode(NodeType.Element, "span").style("font-size: 11px"); 157 p.addHtml(x); 158 if (pfx != null) { 159 x.tx(pfx); 160 } 161 x.code(expr); 162 if (sfx != null) { 163 x.tx(sfx); 164 } 165 } 166 167 private Row addViewRoot(HierarchicalTableGenerator gen, List<Row> rows, ResourceWrapper vd) throws IOException { 168 Row r = gen.new Row(); 169 rows.add(r); 170 171 r.setIcon("icon_vd_view.png", context.formatPhrase(RenderingContext.QUEST_ROOT)); 172 r.getCells().add(gen.new Cell(null, null, vd.primitiveValue("name"), null, null)); 173 r.getCells().add(gen.new Cell(null, null, "", null, null)); 174 r.getCells().add(gen.new Cell(null, null, vd.primitiveValue("resource"), null, null)); 175 r.getCells().add(gen.new Cell(null, null, vd.primitiveValue("description"), null, null)); 176 return r; 177 } 178 179}