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