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.CanonicalResource; 011import org.hl7.fhir.r5.renderers.utils.RenderingContext; 012import org.hl7.fhir.r5.renderers.utils.ResourceWrapper; 013import org.hl7.fhir.r5.utils.EOperationOutcome; 014import org.hl7.fhir.utilities.Utilities; 015import org.hl7.fhir.utilities.xhtml.XhtmlNode; 016 017public class TestPlanRenderer extends ResourceRenderer { 018 019 020 public TestPlanRenderer(RenderingContext context) { 021 super(context); 022 } 023 024 @Override 025 public String buildSummary(ResourceWrapper r) throws UnsupportedEncodingException, IOException { 026 return canonicalTitle(r); 027 } 028 029 @Override 030 public void buildNarrative(RenderingStatus status, XhtmlNode x, ResourceWrapper tp) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome { 031 renderResourceTechDetails(tp, x); 032 genSummaryTable(status, x, (CanonicalResource) tp.getResourceNative()); 033 XhtmlNode p = null; 034 if (tp.has("contact")) { 035 p = x.para(); 036 p.b().tx(context.formatPhrase(RenderingContext.GENERAL_CONTACT)); 037 p.tx(" ("); 038 boolean firsti = true; 039 for (ResourceWrapper ci : tp.children("contact")) { 040 if (firsti) 041 firsti = false; 042 else 043 p.tx(", "); 044 if (ci.has("name")) 045 p.addText(ci.primitiveValue("name") + ": "); 046 boolean first = true; 047 for (ResourceWrapper c : ci.children("telecom")) { 048 if (first) 049 first = false; 050 else 051 p.tx(", "); 052 addTelecom(p, c); 053 } 054 } 055 p.tx(")"); 056 } 057 058 if (tp.has("category")) { 059 p = x.para(); 060 p.b().tx(context.formatPhrase(RenderingContext.TEST_PLAN_CATEGORY)+" "); 061 boolean first = true; 062 for (ResourceWrapper cc : tp.children("category")) { 063 if (first) 064 first = false; 065 else 066 p.tx(", "); 067 renderCodeableConcept(status, p, cc); 068 } 069 } 070 071 if (tp.has("scope")) { 072 List<ResourceWrapper> scopes = tp.children("scope"); 073 if (scopes.size() == 1) { 074 p = x.para(); 075 p.b().tx(context.formatPhrase(RenderingContext.TEST_PLAN_SCOPE)+" "); 076 renderReference(status, p, scopes.get(0)); 077 } else { 078 x.para().b().tx(context.formatPhrase(RenderingContext.TEST_PLAN_SCOPES)); 079 XhtmlNode ul = x.ul(); 080 for (ResourceWrapper ref : scopes) { 081 renderReference(status, ul.li(), ref); 082 } 083 } 084 } 085 086 if (tp.has("dependency")) { 087 List<ResourceWrapper> deps = tp.children("dependency"); 088 if (deps.size() == 1) { 089 ResourceWrapper dep = deps.get(0); 090 p = x.para(); 091 p.b().tx(context.formatPhrase(RenderingContext.TEST_PLAN_DEP)+" "); 092 XhtmlNode t = x.table("grid"); 093 XhtmlNode tr = t.tr(); 094 if (!Utilities.noString(dep.primitiveValue("description"))) { 095 addMarkdown(tr.td(), dep.primitiveValue("description")); 096 } 097 tr = t.tr(); 098 renderReference(status, tr.td(), dep.child("predecessor")); 099 } else { 100 x.para().b().tx(context.formatPhrase(RenderingContext.TEST_PLAN_DEPEN)); 101 XhtmlNode ul = x.ul(); 102 XhtmlNode li = null; 103 for (ResourceWrapper d : deps) { 104 li = ul.li(); 105 if (!Utilities.noString(d.primitiveValue("description"))) { 106 addMarkdown(li, d.primitiveValue("description")); 107 } 108 else { 109 li.addText(context.formatPhrase(RenderingContext.TEST_PLAN_DESC)); 110 } 111 if (d.has("predecessor")) { 112 XhtmlNode liul = li.ul(); 113 XhtmlNode liulli = liul.li(); 114 renderReference(status, liulli, d.child("predecessor")); 115 } 116 } 117 } 118 } 119 120 if (tp.has("exitCriteria")) { 121 addMarkdown(x, tp.primitiveValue("exitCriteria")); 122 } 123 124 for (ResourceWrapper tc : tp.children("testCase")) { 125 x.h2().addText(tc.has("sequence") ? formatPhrase(RenderingContext.TEST_PLAN_CASE) : formatPhrase(RenderingContext.TEST_PLAN_CASE_SEQ, tc.primitiveValue("sequence"))); 126 127 if (tc.has("scope")) { 128 List<ResourceWrapper> scopes = tc.children("scope"); 129 if (scopes.size() == 1) { 130 p = x.para(); 131 p.b().tx(context.formatPhrase(RenderingContext.TEST_PLAN_SCOPE)+" "); 132 renderReference(status, p, scopes.get(0)); 133 } else { 134 x.para().b().tx(context.formatPhrase(RenderingContext.TEST_PLAN_SCOPES)); 135 XhtmlNode ul = x.ul(); 136 for (ResourceWrapper ref : scopes) { 137 renderReference(status, ul.li(), ref); 138 } 139 } 140 } 141 142 if (tc.has("dependency")) { 143 List<ResourceWrapper> deps = tc.children("dependency"); 144 if (deps.size() == 1) { 145 ResourceWrapper dep = deps.get(0); 146 x.h3().addText(context.formatPhrase(RenderingContext.TEST_PLAN_DEP)); 147 XhtmlNode t = x.table("grid"); 148 XhtmlNode tr = t.tr(); 149 if (!Utilities.noString(dep.primitiveValue("description"))) { 150 addMarkdown(tr.td(), dep.primitiveValue("description")); 151 } 152 tr = t.tr(); 153 renderReference(status, tr.td(), dep.child("predecessor")); 154 155 } else { 156 x.h3().addText(context.formatPhrase(RenderingContext.TEST_PLAN_DEPEN)); 157 XhtmlNode ul = x.ul(); 158 XhtmlNode li = null; 159 for (ResourceWrapper d : deps) { 160 li = ul.li(); 161 if (!Utilities.noString(d.primitiveValue("description"))) { 162 addMarkdown(li, d.primitiveValue("description")); 163 } 164 else { 165 li.addText(context.formatPhrase(RenderingContext.TEST_PLAN_DESC)); 166 } 167 if (d.has("predecessor")) { 168 XhtmlNode liul = li.ul(); 169 XhtmlNode liulli = liul.li(); 170 renderReference(status, liulli, d.child("predecessor")); 171 } 172 } 173 } 174 } 175 176 if (tc.has("testRun")) { 177 List<ResourceWrapper> runs = tc.children("testRun"); 178 if (runs.size() == 1) { 179 x.h3().addText(context.formatPhrase(RenderingContext.TEST_PLAN_RUN)); 180 renderTestRun(status, x, tp, runs.get(0)); 181 } 182 else { 183 int count = 0; 184 for (ResourceWrapper trun : runs) { 185 count++; 186 x.h3().addText(context.formatPhrase(RenderingContext.TEST_PLAN_TEST_RUN, count)+" "); 187 renderTestRun(status, x, tp, trun); 188 } 189 } 190 } 191 192 if (tc.has("testData")) { 193 List<ResourceWrapper> dl = tc.children("testData"); 194 if (dl.size() == 1) { 195 x.h3().addText(context.formatPhrase(RenderingContext.TEST_PLAN_DATA)); 196 renderTestData(status, x, tp, dl.get(0)); 197 } 198 else { 199 int count = 0; 200 for (ResourceWrapper tdata : dl) { 201 count++; 202 x.h3().addText(context.formatPhrase(RenderingContext.TEST_PLAN_TEST_DATA, count)+" "); 203 renderTestData(status, x, tp, tdata); 204 } 205 } 206 } 207 208 if (tc.has("assertion")) { 209 List<ResourceWrapper> al = tc.children("assertion"); 210 if (al.size() == 1) { 211 x.h3().addText(context.formatPhrase(RenderingContext.TEST_PLAN_ASS)); 212 renderAssertion(status, x, tp, al.get(0)); 213 } 214 else { 215 int count = 0; 216 for (ResourceWrapper as : al) { 217 count++; 218 x.h3().addText(context.formatPhrase(RenderingContext.TEST_PLAN_ASSERTION, count)+" "); 219 renderAssertion(status, x, tp, as); 220 } 221 } 222 } 223 } 224 } 225 226 private void renderTestRun(RenderingStatus status, XhtmlNode x, ResourceWrapper tp, ResourceWrapper trun) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome { 227 if (trun.hasNarrative()) { 228 addMarkdown(x, trun.primitiveValue("narrative")); 229 } 230 231 if (trun.has("script")) { 232 ResourceWrapper script = trun.child("script"); 233 XhtmlNode t = x.table("grid"); 234 XhtmlNode tr = t.tr(); 235 tr.td().b().addText(context.formatPhrase(RenderingContext.TEST_PLAN_LANG)); 236 tr.td().b().addText(context.formatPhrase(RenderingContext.TEST_PLAN_SOURCE)); 237 tr = t.tr(); 238 if (script.has("language")) { 239 renderCodeableConcept(status, tr.td(), script.child("language")); 240 } else { 241 tr.td().addText("??"); 242 } 243 if (script.has("source")) { 244 renderDataType(status, tr.td(), script.child("script")); 245 } else { 246 tr.td().addText("??"); 247 } 248 } 249 } 250 251 private void renderTestData(RenderingStatus status, XhtmlNode x, ResourceWrapper tp, ResourceWrapper tdata) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome { 252 XhtmlNode t = x.table("grid"); 253 XhtmlNode tr = t.tr(); 254 tr.td().b().addText(context.formatPhrase(RenderingContext.GENERAL_TYPE)); 255 tr.td().b().addText(context.formatPhrase(RenderingContext.GENERAL_CONTENT)); 256 tr.td().b().addText(context.formatPhrase(RenderingContext.TEST_PLAN_SOURCE)); 257 tr = t.tr(); 258 if (tdata.has("type")) { 259 renderCoding(status, tr.td(), tdata.child("type")); 260 } 261 else { 262 tr.td().addText("??"); 263 } 264 if (tdata.has("content")) { 265 renderReference(status, tr.td(), tdata.child("content")); 266 } 267 else { 268 tr.td().addText("??"); 269 } 270 if (tdata.has("source")) { 271 renderDataType(status, tr.td(), tdata.child("source")); 272 } else { 273 tr.td().addText("??"); 274 } 275 } 276 277 private void renderAssertion(RenderingStatus status, XhtmlNode x, ResourceWrapper tp, ResourceWrapper as) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome { 278 XhtmlNode t = x.table("grid"); 279 XhtmlNode tr = t.tr(); 280 tr.td().b().addText(context.formatPhrase(RenderingContext.GENERAL_TYPE)); 281 tr.td().b().addText(context.formatPhrase(RenderingContext.GENERAL_CONTENT)); 282 tr.td().b().addText(context.formatPhrase(RenderingContext.TEST_PLAN_RESULT)); 283 tr = t.tr(); 284 if (as.has("type")) { 285 XhtmlNode td = tr.td(); 286 XhtmlNode ul = td.ul(); 287 for (ResourceWrapper cc : as.children("type")) { 288 renderCodeableConcept(status, ul.li(), cc); 289 } 290 } 291 else { 292 tr.td().addText("??"); 293 } 294 if (as.has("object")) { 295 XhtmlNode td = tr.td(); 296 XhtmlNode ul = td.ul(); 297 for (ResourceWrapper cr : as.children("object")) { 298 renderCodeableReference(status, ul.li(), cr); 299 } 300 } 301 else { 302 tr.td().addText("??"); 303 } 304 if (as.has("result")) { 305 XhtmlNode td = tr.td(); 306 XhtmlNode ul = td.ul(); 307 for (ResourceWrapper cr : as.children("result")) { 308 renderCodeableReference(status, ul.li(), cr); 309 } 310 } 311 else { 312 tr.td().addText("??"); 313 } 314 } 315 316}