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.ActorDefinition; 009import org.hl7.fhir.r5.model.CanonicalResource; 010import org.hl7.fhir.r5.model.CanonicalType; 011import org.hl7.fhir.r5.model.CodeSystem; 012import org.hl7.fhir.r5.model.Enumeration; 013import org.hl7.fhir.r5.model.Library; 014import org.hl7.fhir.r5.model.Reference; 015import org.hl7.fhir.r5.model.Requirements; 016import org.hl7.fhir.r5.model.Requirements.ConformanceExpectation; 017import org.hl7.fhir.r5.model.Requirements.RequirementsStatementComponent; 018import org.hl7.fhir.r5.model.Resource; 019import org.hl7.fhir.r5.model.UrlType; 020import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper; 021import org.hl7.fhir.r5.renderers.utils.RenderingContext; 022import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext; 023import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceWithReference; 024import org.hl7.fhir.utilities.Utilities; 025import org.hl7.fhir.utilities.xhtml.XhtmlNode; 026 027public class RequirementsRenderer extends ResourceRenderer { 028 029 public RequirementsRenderer(RenderingContext context) { 030 super(context); 031 } 032 033 public RequirementsRenderer(RenderingContext context, ResourceContext rcontext) { 034 super(context, rcontext); 035 } 036 037 public boolean render(XhtmlNode x, Resource dr) throws FHIRFormatError, DefinitionException, IOException { 038 return render(x, (Requirements) dr); 039 } 040 041 public boolean render(XhtmlNode x, Requirements req) throws FHIRFormatError, DefinitionException, IOException { 042 if (req.hasActor()) { 043 if (req.getActor().size() == 1) { 044 ActorDefinition acd = context.getWorker().fetchResource(ActorDefinition.class, req.getActor().get(0).getValue(), req); 045 XhtmlNode p = x.para(); 046 p.tx(context.formatPhrase(RenderingContext.REQ_ACTOR)+" "); 047 if (acd == null) { 048 p.code(req.getActor().get(0).getValue()); 049 } else { 050 p.ah(acd.getWebPath()).tx(acd.present()); 051 } 052 } else { 053 x.para().tx(context.formatPhrase(RenderingContext.REQ_FOLLOWING_ACTOR)+" "); 054 XhtmlNode ul = x.ul(); 055 for (CanonicalType a : req.getActor()) { 056 ActorDefinition acd = context.getWorker().fetchResource(ActorDefinition.class, a.getValue(), req); 057 if (acd == null) { 058 ul.li().code(a.getValue()); 059 } else { 060 ul.li().ah(acd.getWebPath()).tx(acd.present()); 061 } 062 } 063 } 064 } 065 if (req.hasDerivedFrom()) { 066 if (req.getDerivedFrom().size() == 1) { 067 Requirements reqd = context.getWorker().fetchResource(Requirements.class, req.getDerivedFrom().get(0).getValue(), req); 068 XhtmlNode p = x.para(); 069 p.tx(context.formatPhrase(RenderingContext.REQ_DERIVE)+" "); 070 if (reqd == null) { 071 p.code(req.getDerivedFrom().get(0).getValue()); 072 } else { 073 p.ah(reqd.getWebPath()).tx(reqd.present()); 074 } 075 } else { 076 x.para().tx(context.formatPhrase(RenderingContext.REQ_FOLLOWING_REQ)+" "); 077 XhtmlNode ul = x.ul(); 078 for (CanonicalType a : req.getDerivedFrom()) { 079 Requirements reqd = context.getWorker().fetchResource(Requirements.class, a.getValue(), req); 080 if (reqd == null) { 081 ul.li().code(a.getValue()); 082 } else { 083 ul.li().ah(reqd.getWebPath()).tx(reqd.present()); 084 } 085 } 086 } 087 } 088 if (req.hasReference()) { 089 XhtmlNode p = x.para(); 090 p.tx(context.formatPhrase(RenderingContext.GENERAL_REFS)+" "); 091 int i = 0; 092 for (UrlType c : req.getReference()) { 093 i++; 094 if (i>1) p.tx(", "); 095 String url = c.getValue(); 096 if (url.contains("#")) { 097 url = url.substring(0, url.indexOf("#")); 098 } 099 p.ah(c.getValue()).tx(url); 100 } 101 } 102 XhtmlNode tbl = x.table("grid"); 103 104 for (RequirementsStatementComponent stmt : req.getStatement()) { 105 XhtmlNode tr = tbl.tr(); 106 String lbl = stmt.hasLabel() ? stmt.getLabel() : stmt.getKey(); 107 XhtmlNode td = tr.td(); 108 td.b().an(stmt.getKey()); 109 td.tx(lbl); 110 td = tr.td(); 111 boolean first = true; 112 CodeSystem cs = context.getWorker().fetchCodeSystem("http://hl7.org/fhir/conformance-expectation"); 113 for (Enumeration<ConformanceExpectation> t : stmt.getConformance()) { 114 if (first) first = false; else td.tx(", "); 115 if (cs != null) { 116 td.ah(cs.getWebPath()+"#conformance-expectation-"+t.asStringValue()).tx(t.asStringValue().toUpperCase()); 117 } else { 118 td.tx(t.asStringValue().toUpperCase()); 119 } 120 } 121 td = tr.td(); 122 addMarkdown(td, stmt.getRequirement()); 123 if (stmt.hasDerivedFrom() || stmt.hasSatisfiedBy() || stmt.hasReference() || stmt.hasSource()) { 124 td.para().tx(context.formatPhrase(RenderingContext.REQ_LINKS)+" "); 125 XhtmlNode ul = td.ul(); 126 if (stmt.hasDerivedFrom()) { 127 XhtmlNode li = ul.li(); 128 li.tx(context.formatPhrase(RenderingContext.REQ_DERIVED)+" "); 129 String url = stmt.getDerivedFrom(); 130 String key = url.contains("#") ? url.substring(url.indexOf("#")+1) : ""; 131 if (url.contains("#")) { url = url.substring(0, url.indexOf("#")); }; 132 Requirements reqr = context.getWorker().fetchResource(Requirements.class, url, req); 133 if (reqr != null) { 134 RequirementsStatementComponent stmtr = reqr.findStatement(key); 135 if (stmtr != null) { 136 li.ah(reqr.getWebPath()+"#"+key).tx(reqr.present() + " # " +(stmt.hasLabel() ? stmt.getLabel() : stmt.getKey())); 137 } else { 138 li.ah(reqr.getWebPath()+"#"+key).tx(reqr.present()+" # "+key); 139 } 140 } else { 141 li.code(stmt.getDerivedFrom()); 142 } 143 } 144 if (stmt.hasSatisfiedBy()) { 145 XhtmlNode li = ul.li(); 146 li.tx(context.formatPhrase(RenderingContext.REQ_SATISFIED)+" "); 147 first = true; 148 for (UrlType c : stmt.getSatisfiedBy()) { 149 if (first) first = false; else li.tx(", "); 150 String url = c.getValue(); 151 if (url.contains("#")) { 152 url = url.substring(0, url.indexOf("#")); 153 } 154 Resource r = context.getWorker().fetchResource(Resource.class, url, req); 155 if (r != null) { 156 String desc = getResourceDescription(r, null); 157 li.ah(c.getValue()).tx(desc); 158 } else { 159 li.ah(c.getValue()).tx(url); 160 } 161 } 162 } 163 if (stmt.hasReference()) { 164 XhtmlNode li = ul.li(); 165 li.tx(context.formatPhrase(RenderingContext.GENERAL_REFS)+" "); 166 int i = 0; 167 for (UrlType c : stmt.getReference()) { 168 i++; 169 if (i>1) li.tx(", "); 170 String url = c.getValue(); 171 if (url.contains("#")) { 172 url = url.substring(0, url.indexOf("#")); 173 } 174 li.ah(c.getValue()).tx(url); 175 } 176 } 177 if (stmt.hasSource()) { 178 XhtmlNode li = ul.li(); 179 li.tx(context.formatPhrase(RenderingContext.GENERAL_SRC)+" "); 180 first = true; 181 for (Reference c : stmt.getSource()) { 182 if (first) first = false; else li.tx(", "); 183 if (c.hasReference()) { 184 String url = c.getReference(); 185 if (url.contains("#")) { 186 url = url.substring(0, url.indexOf("#")); 187 } 188 Resource r = context.getWorker().fetchResource(Resource.class, url, req); 189 ResourceWithReference t = null; 190 if (r == null && context.getResolver() != null) { 191 t = context.getResolver().resolve(context, url); 192 } 193 if (r != null) { 194 String desc = getResourceDescription(r, c.getDisplay()); 195 li.ah(c.getReference()).tx(desc); 196 } else if (t != null) { 197 String desc = getResourceDescription(t, c.getDisplay()); 198 li.ah(t.getReference()).tx(desc); 199 } else { 200 li.ah(c.getReference()).tx(url); 201 } 202 } else if (c.hasDisplay()) { 203 li.tx(c.getDisplay()); 204 } else { 205 li.tx("??"); 206 } 207 } 208 } 209 } 210 } 211 return false; 212 } 213 214 private String getResourceDescription(ResourceWithReference res, String display) throws UnsupportedEncodingException, IOException { 215 if (!Utilities.noString(display)) { 216 return display; 217 } 218 return RendererFactory.factory(res.getResource(), context).display(res.getResource()); 219 } 220 221 private String getResourceDescription(Resource res, String display) throws UnsupportedEncodingException, IOException { 222 if (!Utilities.noString(display)) { 223 return display; 224 } 225 if (res instanceof CanonicalResource) { 226 return ((CanonicalResource) res).present(); 227 } 228 return RendererFactory.factory(res, context).display(res); 229 } 230 231 public void describe(XhtmlNode x, Library lib) { 232 x.tx(display(lib)); 233 } 234 235 public String display(Library lib) { 236 return lib.present(); 237 } 238 239 @Override 240 public String display(Resource r) throws UnsupportedEncodingException, IOException { 241 return ((Library) r).present(); 242 } 243 244 @Override 245 public String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException { 246 if (r.has("title")) { 247 return r.children("title").get(0).getBase().primitiveValue(); 248 } 249 return "??"; 250 } 251 252}