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}