
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.ActorDefinition; 011import org.hl7.fhir.r5.model.CanonicalResource; 012import org.hl7.fhir.r5.model.CodeSystem; 013import org.hl7.fhir.r5.model.Library; 014import org.hl7.fhir.r5.model.Requirements; 015import org.hl7.fhir.r5.model.Requirements.RequirementsStatementComponent; 016import org.hl7.fhir.r5.model.Resource; 017import org.hl7.fhir.r5.renderers.utils.RenderingContext; 018import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceWithReference; 019import org.hl7.fhir.r5.renderers.utils.ResourceWrapper; 020import org.hl7.fhir.r5.utils.EOperationOutcome; 021import org.hl7.fhir.utilities.MarkedToMoveToAdjunctPackage; 022import org.hl7.fhir.utilities.Utilities; 023import org.hl7.fhir.utilities.xhtml.XhtmlNode; 024 025@MarkedToMoveToAdjunctPackage 026public class RequirementsRenderer extends ResourceRenderer { 027 028 public RequirementsRenderer(RenderingContext context) { 029 super(context); 030 } 031 032 @Override 033 public String buildSummary(ResourceWrapper r) throws UnsupportedEncodingException, IOException { 034 return canonicalTitle(r); 035 } 036 037 @Override 038 public void buildNarrative(RenderingStatus status, XhtmlNode x, ResourceWrapper req) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome { 039 renderResourceTechDetails(req, x); 040 genSummaryTable(status, x, (CanonicalResource) req.getResourceNative()); 041 042 if (req.has("actor")) { 043 List<ResourceWrapper> actors = req.children("actor"); 044 if (actors.size() == 1) { 045 ActorDefinition acd = context.getWorker().fetchResource(ActorDefinition.class, actors.get(0).primitiveValue(), req.getResourceNative()); 046 XhtmlNode p = x.para(); 047 p.tx(context.formatPhrase(RenderingContext.REQ_ACTOR)+" "); 048 renderCanonical(status, p, ActorDefinition.class, actors.get(0)); 049 } else { 050 x.para().tx(context.formatPhrase(RenderingContext.REQ_FOLLOWING_ACTOR)+" "); 051 XhtmlNode ul = x.ul(); 052 for (ResourceWrapper a : actors) { 053 renderCanonical(status, ul.li(), ActorDefinition.class, a); 054 } 055 } 056 } 057 if (req.has("derivedFrom")) { 058 List<ResourceWrapper> list = req.children("derivedFrom"); 059 if (list.size() == 1) { 060 XhtmlNode p = x.para(); 061 p.tx(context.formatPhrase(RenderingContext.REQ_DERIVE)+" "); 062 renderCanonical(status, p, Requirements.class, list.get(0)); 063 } else { 064 x.para().tx(context.formatPhrase(RenderingContext.REQ_FOLLOWING_REQ)+" "); 065 XhtmlNode ul = x.ul(); 066 for (ResourceWrapper a : list) { 067 renderCanonical(status, ul.li(), Requirements.class, a); 068 } 069 } 070 } 071 if (req.has("reference")) { 072 XhtmlNode p = x.para(); 073 p.tx(context.formatPhrase(RenderingContext.GENERAL_REFS)+" "); 074 int i = 0; 075 for (ResourceWrapper c : req.children("reference")) { 076 i++; 077 if (i>1) p.tx(", "); 078 String url = c.primitiveValue(); 079 if (url.contains("#")) { 080 url = url.substring(0, url.indexOf("#")); 081 } 082 p.ah(context.prefixLocalHref(c.primitiveValue())).tx(url); 083 } 084 } 085 XhtmlNode tbl = x.table("grid", false); 086 087 for (ResourceWrapper stmt : req.children("statement")) { 088 XhtmlNode tr = tbl.tr(); 089 String lbl = stmt.has("label") ? stmt.primitiveValue("label") : stmt.primitiveValue("key"); 090 XhtmlNode td = tr.td(); 091 td.b().an(context.prefixAnchor(stmt.primitiveValue("key"))); 092 td.tx(lbl); 093 td = tr.td(); 094 boolean first = true; 095 CodeSystem cs = context.getWorker().fetchCodeSystem("http://hl7.org/fhir/conformance-expectation"); 096 for (ResourceWrapper t : stmt.children("conformance")) { 097 if (first) first = false; else td.tx(", "); 098 if (cs != null) { 099 td.ah(context.prefixLocalHref(cs.getWebPath()+"#conformance-expectation-"+t.primitiveValue())).tx(t.primitiveValue().toUpperCase()); 100 } else { 101 td.tx(t.primitiveValue().toUpperCase()); 102 } 103 } 104 td = tr.td(); 105 addMarkdown(td, stmt.primitiveValue("requirement")); 106 if (stmt.has("derivedFrom") || stmt.has("satisfiedBy") || stmt.has("reference") || stmt.has("source")) { 107 td.para().tx(context.formatPhrase(RenderingContext.REQ_LINKS)+" "); 108 XhtmlNode ul = td.ul(); 109 if (stmt.has("derivedFrom")) { 110 XhtmlNode li = ul.li(); 111 li.tx(context.formatPhrase(RenderingContext.REQ_DERIVED)+" "); 112 String url = stmt.primitiveValue("derivedFrom"); 113 String key = url.contains("#") ? url.substring(url.indexOf("#")+1) : ""; 114 if (url.contains("#")) { url = url.substring(0, url.indexOf("#")); }; 115 Requirements reqr = context.getWorker().fetchResource(Requirements.class, url, req.getResourceNative()); 116 if (reqr != null) { 117 RequirementsStatementComponent stmtr = reqr.findStatement(key); 118 if (stmtr != null) { 119 li.ah(context.prefixLocalHref(reqr.getWebPath()+"#"+key)).tx(reqr.present() + " # " +(stmt.has("label") ? stmt.primitiveValue("label") : stmt.primitiveValue("key"))); 120 } else { 121 li.ah(context.prefixLocalHref(reqr.getWebPath()+"#"+key)).tx(reqr.present()+" # "+key); 122 } 123 } else { 124 li.code(stmt.primitiveValue("derivedFrom")); 125 } 126 } 127 if (stmt.has("satisfiedBy")) { 128 XhtmlNode li = ul.li(); 129 li.tx(context.formatPhrase(RenderingContext.REQ_SATISFIED)+" "); 130 first = true; 131 for (ResourceWrapper c : stmt.children("satisfiedBy")) { 132 if (first) first = false; else li.tx(", "); 133 String url = c.primitiveValue(); 134 if (url.contains("#")) { 135 url = url.substring(0, url.indexOf("#")); 136 } 137 Resource r = context.getWorker().fetchResource(Resource.class, url, req.getResourceNative()); 138 if (r != null) { 139 String desc = getResourceDescription(r, null); 140 li.ah(context.prefixLocalHref(c.primitiveValue())).tx(desc); 141 } else { 142 li.ah(context.prefixLocalHref(c.primitiveValue())).tx(url); 143 } 144 } 145 } 146 if (stmt.has("reference")) { 147 XhtmlNode li = ul.li(); 148 li.tx(context.formatPhrase(RenderingContext.GENERAL_REFS)+" "); 149 int i = 0; 150 for (ResourceWrapper c : stmt.children("reference")) { 151 i++; 152 if (i>1) li.tx(", "); 153 String url = c.primitiveValue(); 154 if (url.contains("#")) { 155 url = url.substring(0, url.indexOf("#")); 156 } 157 li.ah(context.prefixLocalHref(c.primitiveValue())).tx(url); 158 } 159 } 160 if (stmt.has("source")) { 161 XhtmlNode li = ul.li(); 162 li.tx(context.formatPhrase(RenderingContext.GENERAL_SRC)+" "); 163 first = true; 164 for (ResourceWrapper c : stmt.children("source")) { 165 if (first) first = false; else li.tx(", "); 166 if (c.has("reference")) { 167 String url = c.primitiveValue("reference"); 168 if (url.contains("#")) { 169 url = url.substring(0, url.indexOf("#")); 170 } 171 Resource r = context.getWorker().fetchResource(Resource.class, url, req.getResourceNative()); 172 ResourceWithReference t = null; 173 if (r == null && context.getResolver() != null) { 174 t = context.getResolver().resolve(context, url, null); 175 } 176 if (r != null) { 177 String desc = getResourceDescription(r, c.primitiveValue("display")); 178 li.ah(context.prefixLocalHref(c.primitiveValue("reference"))).tx(desc); 179 } else if (t != null) { 180 String desc = getResourceDescription(t, c.primitiveValue("display")); 181 li.ah(context.prefixLocalHref(t.getWebPath())).tx(desc); 182 } else { 183 li.ah(context.prefixLocalHref(c.primitiveValue("reference"))).tx(url); 184 } 185 } else if (c.has("display")) { 186 li.tx(c.primitiveValue("display")); 187 } else { 188 li.tx("??"); 189 } 190 } 191 } 192 } 193 } 194 } 195 196 private String getResourceDescription(ResourceWithReference res, String display) throws UnsupportedEncodingException, IOException { 197 if (!Utilities.noString(display)) { 198 return display; 199 } 200 return RendererFactory.factory(res.getResource(), context.forContained()).buildSummary(res.getResource()); 201 } 202 203 private String getResourceDescription(Resource res, String display) throws UnsupportedEncodingException, IOException { 204 if (!Utilities.noString(display)) { 205 return display; 206 } 207 if (res instanceof CanonicalResource) { 208 return ((CanonicalResource) res).present(); 209 } 210 return RendererFactory.factory(res, context.forContained()).buildSummary(wrap(res)); 211 } 212 213 public void describe(XhtmlNode x, Library lib) { 214 x.tx(display(lib)); 215 } 216 217 public String display(Library lib) { 218 return lib.present(); 219 } 220 221}