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}