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.FHIRException; 008import org.hl7.fhir.exceptions.FHIRFormatError; 009import org.hl7.fhir.r5.model.CodeableConcept; 010import org.hl7.fhir.r5.model.CodeableReference; 011import org.hl7.fhir.r5.model.ContactDetail; 012import org.hl7.fhir.r5.model.ContactPoint; 013import org.hl7.fhir.r5.model.Reference; 014import org.hl7.fhir.r5.model.Resource; 015import org.hl7.fhir.r5.model.TestPlan; 016import org.hl7.fhir.r5.model.TestPlan.TestCaseDependencyComponent; 017import org.hl7.fhir.r5.model.TestPlan.TestPlanDependencyComponent; 018import org.hl7.fhir.r5.model.TestPlan.TestPlanTestCaseAssertionComponent; 019import org.hl7.fhir.r5.model.TestPlan.TestPlanTestCaseComponent; 020import org.hl7.fhir.r5.model.TestPlan.TestPlanTestCaseTestDataComponent; 021import org.hl7.fhir.r5.model.TestPlan.TestPlanTestCaseTestRunComponent; 022import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper; 023import org.hl7.fhir.r5.renderers.utils.RenderingContext; 024import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext; 025import org.hl7.fhir.r5.utils.EOperationOutcome; 026import org.hl7.fhir.utilities.Utilities; 027import org.hl7.fhir.utilities.xhtml.XhtmlNode; 028 029public class TestPlanRenderer extends ResourceRenderer { 030 031 public TestPlanRenderer(RenderingContext context) { 032 super(context); 033 } 034 035 public TestPlanRenderer(RenderingContext context, ResourceContext rcontext) { 036 super(context, rcontext); 037 } 038 039 @Override 040 public boolean render(XhtmlNode x, Resource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome { 041 return render(x, (TestPlan) r); 042 } 043 044 public boolean render(XhtmlNode x, TestPlan tp) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome { 045 XhtmlNode p = null; 046 if (!tp.getContact().isEmpty()) { 047 p = x.para(); 048 p.b().tx("Contact:"); 049 p.tx(" ("); 050 boolean firsti = true; 051 for (ContactDetail ci : tp.getContact()) { 052 if (firsti) 053 firsti = false; 054 else 055 p.tx(", "); 056 if (ci.hasName()) 057 p.addText(ci.getName() + ": "); 058 boolean first = true; 059 for (ContactPoint c : ci.getTelecom()) { 060 if (first) 061 first = false; 062 else 063 p.tx(", "); 064 addTelecom(p, c); 065 } 066 } 067 p.tx(")"); 068 } 069 070 if (tp.hasCategory()) { 071 p = x.para(); 072 p.b().tx("Category: "); 073 boolean first = true; 074 for (CodeableConcept cc : tp.getCategory()) { 075 if (first) 076 first = false; 077 else 078 p.tx(", "); 079 renderCodeableConcept(p, cc, false); 080 } 081 } 082 083 if (tp.hasScope()) { 084 if (tp.getScope().size() == 1) { 085 p = x.para(); 086 p.b().tx("Test Plan Scope: "); 087 renderReference(tp, p, tp.getScopeFirstRep()); 088 } else { 089 x.para().b().tx("Test Plan Scopes:"); 090 XhtmlNode ul = x.ul(); 091 for (Reference ref : tp.getScope()) { 092 renderReference(tp, ul.li(), ref); 093 } 094 } 095 } 096 097 if (tp.hasDependency()) { 098 if (tp.getDependency().size() == 1) { 099 p = x.para(); 100 p.b().tx("Test Plan Dependency: "); 101 XhtmlNode t = x.table("grid"); 102 XhtmlNode tr = t.tr(); 103 if (!Utilities.noString(tp.getDependencyFirstRep().getDescription())) { 104 addMarkdown(tr.td(), tp.getDependencyFirstRep().getDescription()); 105 } 106 tr = t.tr(); 107 renderReference(tp, tr.td(), tp.getDependencyFirstRep().getPredecessor()); 108 } else { 109 x.para().b().tx("Test Plan Dependencies:"); 110 XhtmlNode ul = x.ul(); 111 XhtmlNode li = null; 112 for (TestPlanDependencyComponent d : tp.getDependency()) { 113 li = ul.li(); 114 if (!Utilities.noString(d.getDescription())) { 115 addMarkdown(li, d.getDescription()); 116 } 117 else { 118 li.addText("Dependency - no description"); 119 } 120 if (d.hasPredecessor()) { 121 XhtmlNode liul = li.ul(); 122 XhtmlNode liulli = liul.li(); 123 renderReference(tp, liulli, d.getPredecessor()); 124 } 125 } 126 } 127 } 128 129 if (tp.hasExitCriteria()) { 130 addMarkdown(x, tp.getExitCriteria()); 131 } 132 133 if (tp.hasTestCase()) { 134 for (TestPlanTestCaseComponent tc : tp.getTestCase()) { 135 x.h2().addText("Test Case" + (tc.hasSequence() ? " - Sequence" + tc.getSequence() : "")); 136 137 if (tc.hasScope()) { 138 if (tc.getScope().size() == 1) { 139 p = x.para(); 140 p.b().tx("Test Case Scope: "); 141 renderReference(tp, p, tc.getScopeFirstRep()); 142 } else { 143 x.para().b().tx("Test Case Scopes:"); 144 XhtmlNode ul = x.ul(); 145 for (Reference ref : tc.getScope()) { 146 renderReference(tp, ul.li(), ref); 147 } 148 } 149 } 150 151 if (tc.hasDependency()) { 152 if (tc.getDependency().size() == 1) { 153 x.h3().addText("Test Case Dependency"); 154 XhtmlNode t = x.table("grid"); 155 XhtmlNode tr = t.tr(); 156 if (!Utilities.noString(tc.getDependencyFirstRep().getDescription())) { 157 addMarkdown(tr.td(), tc.getDependencyFirstRep().getDescription()); 158 } 159 tr = t.tr(); 160 renderReference(tp, tr.td(), tc.getDependencyFirstRep().getPredecessor()); 161 } else { 162 x.h3().addText("Test Case Dependencies"); 163 XhtmlNode ul = x.ul(); 164 XhtmlNode li = null; 165 for (TestCaseDependencyComponent d : tc.getDependency()) { 166 li = ul.li(); 167 if (!Utilities.noString(d.getDescription())) { 168 addMarkdown(li, d.getDescription()); 169 } 170 else { 171 li.addText("Dependency - no description"); 172 } 173 if (d.hasPredecessor()) { 174 XhtmlNode liul = li.ul(); 175 XhtmlNode liulli = liul.li(); 176 renderReference(tp, liulli, d.getPredecessor()); 177 } 178 } 179 } 180 } 181 182 if (tc.hasTestRun()) { 183 if (tc.getTestRun().size() == 1) { 184 x.h3().addText("Test Run"); 185 renderTestRun(x, tp, tc.getTestRunFirstRep()); 186 } 187 else { 188 int count = 0; 189 for (TestPlanTestCaseTestRunComponent trun : tc.getTestRun()) { 190 count++; 191 x.h3().addText("Test Run " + count); 192 renderTestRun(x, tp, trun); 193 } 194 } 195 } 196 197 if (tc.hasTestData()) { 198 if (tc.getTestData().size() == 1) { 199 x.h3().addText("Test Data"); 200 renderTestData(x, tp, tc.getTestDataFirstRep()); 201 } 202 else { 203 int count = 0; 204 for (TestPlanTestCaseTestDataComponent tdata : tc.getTestData()) { 205 count++; 206 x.h3().addText("Test Data " + count); 207 renderTestData(x, tp, tdata); 208 } 209 } 210 } 211 212 if (tc.hasAssertion()) { 213 if (tc.getAssertion().size() == 1) { 214 x.h3().addText("Assertion"); 215 renderAssertion(x, tp, tc.getAssertionFirstRep()); 216 } 217 else { 218 int count = 0; 219 for (TestPlanTestCaseAssertionComponent as : tc.getAssertion()) { 220 count++; 221 x.h3().addText("Assertion " + count); 222 renderAssertion(x, tp, as); 223 } 224 } 225 } 226 } 227 } 228 229 return false; 230 } 231 232 private void renderTestRun(XhtmlNode x, TestPlan tp, TestPlanTestCaseTestRunComponent trun) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome { 233 if (trun.hasNarrative()) { 234 addMarkdown(x, trun.getNarrative()); 235 } 236 237 if (trun.hasScript()) { 238 XhtmlNode t = x.table("grid"); 239 XhtmlNode tr = t.tr(); 240 tr.td().b().addText("Language"); 241 tr.td().b().addText("Source[x]"); 242 tr = t.tr(); 243 if (trun.getScript().hasLanguage()) { 244 renderCodeableConcept(tr.td(), trun.getScript().getLanguage(), false); 245 } 246 else { 247 tr.td().addText("??"); 248 } 249 if (trun.getScript().hasSourceReference()) { 250 renderReference(tp, tr.td(), trun.getScript().getSourceReference()); 251 } 252 else if(trun.getScript().hasSourceStringType()) { 253 tr.td().addText(trun.getScript().getSourceStringType().asStringValue()); 254 } 255 else { 256 tr.td().addText("??"); 257 } 258 } 259 } 260 261 private void renderTestData(XhtmlNode x, TestPlan tp, TestPlanTestCaseTestDataComponent tdata) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome { 262 XhtmlNode t = x.table("grid"); 263 XhtmlNode tr = t.tr(); 264 tr.td().b().addText("Type"); 265 tr.td().b().addText("Content"); 266 tr.td().b().addText("Source[x]"); 267 tr = t.tr(); 268 if (tdata.hasType()) { 269 renderCoding(tr.td(), tdata.getType()); 270 } 271 else { 272 tr.td().addText("??"); 273 } 274 if (tdata.hasContent()) { 275 renderReference(tp, tr.td(), tdata.getContent()); 276 } 277 else { 278 tr.td().addText("??"); 279 } 280 if (tdata.hasSourceReference()) { 281 renderReference(tp, tr.td(), tdata.getSourceReference()); 282 } 283 else if(tdata.hasSourceStringType()) { 284 tr.td().addText(tdata.getSourceStringType().asStringValue()); 285 } 286 else { 287 tr.td().addText("??"); 288 } 289 } 290 291 private void renderAssertion(XhtmlNode x, TestPlan tp, TestPlanTestCaseAssertionComponent as) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome { 292 XhtmlNode t = x.table("grid"); 293 XhtmlNode tr = t.tr(); 294 tr.td().b().addText("Type"); 295 tr.td().b().addText("Content"); 296 tr.td().b().addText("Result"); 297 tr = t.tr(); 298 if (as.hasType()) { 299 XhtmlNode td = tr.td(); 300 XhtmlNode ul = td.ul(); 301 for (CodeableConcept cc : as.getType()) { 302 renderCodeableConcept(ul.li(), cc, false); 303 } 304 } 305 else { 306 tr.td().addText("??"); 307 } 308 if (as.hasObject()) { 309 XhtmlNode td = tr.td(); 310 XhtmlNode ul = td.ul(); 311 for (CodeableReference cr : as.getObject()) { 312 renderCodeableReference(ul.li(), cr, false); 313 } 314 } 315 else { 316 tr.td().addText("??"); 317 } 318 if (as.hasResult()) { 319 XhtmlNode td = tr.td(); 320 XhtmlNode ul = td.ul(); 321 for (CodeableReference cr : as.getResult()) { 322 renderCodeableReference(ul.li(), cr, false); 323 } 324 } 325 else { 326 tr.td().addText("??"); 327 } 328 } 329 330 @Override 331 public String display(Resource r) throws UnsupportedEncodingException, IOException { 332 return null; 333 } 334 335 @Override 336 public String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException { 337 if (r.has("title")) { 338 return r.children("title").get(0).getBase().primitiveValue(); 339 } 340 return "??"; 341 } 342 343}