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