001package org.hl7.fhir.r5.renderers; 002 003import java.io.IOException; 004import java.io.UnsupportedEncodingException; 005 006import org.hl7.fhir.exceptions.DefinitionException; 007import org.hl7.fhir.exceptions.FHIRFormatError; 008import org.hl7.fhir.r5.model.Annotation; 009import org.hl7.fhir.r5.model.Base; 010import org.hl7.fhir.r5.model.ListResource; 011import org.hl7.fhir.r5.model.ListResource.ListResourceEntryComponent; 012import org.hl7.fhir.r5.model.Reference; 013import org.hl7.fhir.r5.model.Resource; 014import org.hl7.fhir.r5.renderers.utils.BaseWrappers.BaseWrapper; 015import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper; 016import org.hl7.fhir.r5.renderers.utils.RenderingContext; 017import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext; 018import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceWithReference; 019import org.hl7.fhir.utilities.xhtml.XhtmlNode; 020 021public class ListRenderer extends ResourceRenderer { 022 023 public ListRenderer(RenderingContext context) { 024 super(context); 025 } 026 027 public ListRenderer(RenderingContext context, ResourceContext rcontext) { 028 super(context, rcontext); 029 } 030 031 public boolean render(XhtmlNode x, Resource dr) throws FHIRFormatError, DefinitionException, IOException { 032 return render(x, (ListResource) dr); 033 } 034 035 public boolean render(XhtmlNode x, ResourceWrapper list) throws FHIRFormatError, DefinitionException, IOException { 036 if (list.has("title")) { 037 x.h2().tx(list.get("title").primitiveValue()); 038 } 039 XhtmlNode t = x.table("clstu"); 040 XhtmlNode tr = t.tr(); 041 XhtmlNode td = tr.td(); 042 if (list.has("date")) { 043 td.tx("Date: "+list.get("date").dateTimeValue().toHumanDisplay()); 044 } 045 if (list.has("mode")) { 046 td.tx("Mode: "+list.get("mode").primitiveValue()); 047 } 048 if (list.has("status")) { 049 td.tx("Status: "+list.get("status").primitiveValue()); 050 } 051 if (list.has("code")) { 052 td.tx("Code: "+displayBase(list.get("code"))); 053 } 054 tr = t.tr(); 055 td = tr.td(); 056 if (list.has("subject")) { 057 td.tx("Subject: "); 058 shortForRef(td, list.get("subject")); 059 } 060 if (list.has("encounter")) { 061 td.tx("Encounter: "); 062 shortForRef(td, list.get("encounter")); 063 } 064 if (list.has("source")) { 065 td.tx("Source: "); 066 shortForRef(td, list.get("encounter")); 067 } 068 if (list.has("orderedBy")) { 069 td.tx("Order: "+displayBase(list.get("orderedBy"))); 070 } 071 // for (Annotation a : list.getNote()) { 072 // renderAnnotation(a, x); 073 // } 074 boolean flag = false; 075 boolean deleted = false; 076 boolean date = false; 077 for (BaseWrapper e : list.children("entry")) { 078 flag = flag || e.has("flag"); 079 deleted = deleted || e.has("deleted"); 080 date = date || e.has("date"); 081 } 082 t = x.table("grid"); 083 tr = t.tr().style("backgound-color: #eeeeee"); 084 tr.td().b().tx("Items"); 085 if (date) { 086 tr.td().tx("Date"); 087 } 088 if (flag) { 089 tr.td().tx("Flag"); 090 } 091 if (deleted) { 092 tr.td().tx("Deleted"); 093 } 094 for (BaseWrapper e : list.children("entry")) { 095 tr = t.tr(); 096 shortForRef(tr.td(), e.get("item")); 097 if (date) { 098 tr.td().tx(e.has("date") ? e.get("date").dateTimeValue().toHumanDisplay() : ""); 099 } 100 if (flag) { 101 tr.td().tx(e.has("flag") ? displayBase(e.get("flag")) : ""); 102 } 103 if (deleted) { 104 tr.td().tx(e.has("deleted") ? e.get("deleted").primitiveValue() : ""); 105 } 106 } 107 return false; 108 } 109 public boolean render(XhtmlNode x, ListResource list) throws FHIRFormatError, DefinitionException, IOException { 110 if (list.hasTitle()) { 111 x.h2().tx(list.getTitle()); 112 } 113 XhtmlNode t = x.table("clstu"); 114 XhtmlNode tr = t.tr(); 115 if (list.hasDate()) { 116 tr.td().tx("Date: "+list.getDate().toLocaleString()); 117 } 118 if (list.hasMode()) { 119 tr.td().tx("Mode: "+list.getMode().getDisplay()); 120 } 121 if (list.hasStatus()) { 122 tr.td().tx("Status: "+list.getStatus().getDisplay()); 123 } 124 if (list.hasCode()) { 125 tr.td().tx("Code: "+display(list.getCode())); 126 } 127 tr = t.tr(); 128 if (list.hasSubject()) { 129 if (list.getSubject().size() == 1) { 130 shortForRef(tr.td().txN("Subject: "), list.getSubjectFirstRep()); 131 } else { 132 XhtmlNode td = tr.td(); 133 td.txN("Subject: "); 134 int i = 0; 135 for (Reference subj : list.getSubject()) { 136 if (i == list.getSubject().size() - 1) { 137 td.tx(" and "); 138 } else if (i > 0) { 139 td.tx(", "); 140 } 141 shortForRef(td, subj); 142 } 143 } 144 } 145 if (list.hasEncounter()) { 146 shortForRef(tr.td().txN("Encounter: "), list.getEncounter()); 147 } 148 if (list.hasSource()) { 149 shortForRef(tr.td().txN("Source: "), list.getEncounter()); 150 } 151 if (list.hasOrderedBy()) { 152 tr.td().tx("Order: "+display(list.getOrderedBy())); 153 } 154 for (Annotation a : list.getNote()) { 155 renderAnnotation(x, a); 156 } 157 boolean flag = false; 158 boolean deleted = false; 159 boolean date = false; 160 for (ListResourceEntryComponent e : list.getEntry()) { 161 flag = flag || e.hasFlag(); 162 deleted = deleted || e.hasDeleted(); 163 date = date || e.hasDate(); 164 } 165 t = x.table("grid"); 166 tr = t.tr().style("backgound-color: #eeeeee"); 167 tr.td().b().tx("Items"); 168 if (date) { 169 tr.td().tx("Date"); 170 } 171 if (flag) { 172 tr.td().tx("Flag"); 173 } 174 if (deleted) { 175 tr.td().tx("Deleted"); 176 } 177 for (ListResourceEntryComponent e : list.getEntry()) { 178 tr = t.tr(); 179 shortForRef(tr.td(), e.getItem()); 180 if (date) { 181 tr.td().tx(e.hasDate() ? e.getDate().toLocaleString() : ""); 182 } 183 if (flag) { 184 tr.td().tx(e.hasFlag() ? display(e.getFlag()) : ""); 185 } 186 if (deleted) { 187 tr.td().tx(e.hasDeleted() ? Boolean.toString(e.getDeleted()) : ""); 188 } 189 } 190 return false; 191 } 192 193 public void describe(XhtmlNode x, ListResource list) { 194 x.tx(display(list)); 195 } 196 197 public String display(ListResource list) { 198 return list.getTitle(); 199 } 200 201 @Override 202 public String display(Resource r) throws UnsupportedEncodingException, IOException { 203 return ((ListResource) r).getTitle(); 204 } 205 206 @Override 207 public String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException { 208 if (r.has("title")) { 209 return r.children("title").get(0).getBase().primitiveValue(); 210 } 211 return "??"; 212 } 213 214 private void shortForRef(XhtmlNode x, Reference ref) throws UnsupportedEncodingException, IOException { 215 ResourceWithReference r = context.getResolver().resolve(context, ref.getReference()); 216 if (r == null) { 217 x.tx(display(ref)); 218 } else { 219 RendererFactory.factory(r.getResource().getName(), context).renderReference(r.getResource(), x, ref); 220 } 221 } 222 223 private XhtmlNode shortForRef(XhtmlNode x, Base ref) throws UnsupportedEncodingException, IOException { 224 if (ref == null) { 225 x.tx("(null)"); 226 } else { 227 String disp = ref.getChildByName("display") != null && ref.getChildByName("display").hasValues() ? ref.getChildByName("display").getValues().get(0).primitiveValue() : null; 228 if (ref.getChildByName("reference").hasValues()) { 229 String url = ref.getChildByName("reference").getValues().get(0).primitiveValue(); 230 if (url.startsWith("#")) { 231 x.tx("?ngen-16a?"); 232 } else { 233 ResourceWithReference r = context.getResolver().resolve(context, url); 234 if (r == null) { 235 if (disp == null) { 236 disp = url; 237 } 238 x.tx(disp); 239 } else if (r.getResource() != null) { 240 RendererFactory.factory(r.getResource().getName(), context).renderReference(r.getResource(), x, (Reference) ref); 241 } else { 242 x.ah(r.getReference()).tx(url); 243 } 244 } 245 } else if (disp != null) { 246 x.tx(disp); 247 } else { 248 x.tx("?ngen-16?"); 249 } 250 } 251 return x; 252 } 253}