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.FHIRFormatError;
008import org.hl7.fhir.r5.model.Annotation;
009import org.hl7.fhir.r5.model.Base;
010import org.hl7.fhir.r5.model.DomainResource;
011import org.hl7.fhir.r5.model.ListResource;
012import org.hl7.fhir.r5.model.ListResource.ListResourceEntryComponent;
013import org.hl7.fhir.r5.model.Reference;
014import org.hl7.fhir.r5.model.Resource;
015import org.hl7.fhir.r5.renderers.utils.BaseWrappers.BaseWrapper;
016import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
017import org.hl7.fhir.r5.renderers.utils.RenderingContext;
018import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext;
019import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceWithReference;
020import org.hl7.fhir.utilities.xhtml.XhtmlNode;
021
022public class ListRenderer extends ResourceRenderer {
023
024  public ListRenderer(RenderingContext context) {
025    super(context);
026  }
027
028  public ListRenderer(RenderingContext context, ResourceContext rcontext) {
029    super(context, rcontext);
030  }
031  
032  public boolean render(XhtmlNode x, Resource dr) throws FHIRFormatError, DefinitionException, IOException {
033    return render(x, (ListResource) dr);
034  }
035
036  public boolean render(XhtmlNode x, ResourceWrapper list) throws FHIRFormatError, DefinitionException, IOException {
037    if (list.has("title")) {
038      x.h2().tx(list.get("title").primitiveValue());
039    }
040    XhtmlNode t = x.table("clstu");
041    XhtmlNode tr = t.tr();
042    XhtmlNode td = tr.td();
043    if (list.has("date")) {
044      td.tx("Date: "+list.get("date").dateTimeValue().toHumanDisplay());
045    }
046    if (list.has("mode")) {
047      td.tx("Mode: "+list.get("mode").primitiveValue());
048    }
049    if (list.has("status")) {
050      td.tx("Status: "+list.get("status").primitiveValue());
051    }
052    if (list.has("code")) {
053      td.tx("Code: "+displayBase(list.get("code")));
054    }    
055    tr = t.tr();
056    td = tr.td();
057    if (list.has("subject")) {
058      td.tx("Subject: ");
059      shortForRef(td, list.get("subject"));
060    }
061    if (list.has("encounter")) {
062      td.tx("Encounter: ");
063      shortForRef(td, list.get("encounter"));
064    }
065    if (list.has("source")) {
066      td.tx("Source: ");
067      shortForRef(td, list.get("encounter"));
068    }
069    if (list.has("orderedBy")) {
070      td.tx("Order: "+displayBase(list.get("orderedBy")));
071    }
072    //    for (Annotation a : list.getNote()) {
073    //      renderAnnotation(a, x);
074    //    }
075    boolean flag = false;
076    boolean deleted = false;
077    boolean date = false;
078    for (BaseWrapper e : list.children("entry")) {
079      flag = flag || e.has("flag");
080      deleted = deleted || e.has("deleted");
081      date = date || e.has("date");
082    }
083    t = x.table("grid");
084    tr = t.tr().style("backgound-color: #eeeeee");
085    tr.td().b().tx("Items");
086    if (date) {
087      tr.td().tx("Date");      
088    }
089    if (flag) {
090      tr.td().tx("Flag");      
091    }
092    if (deleted) {
093      tr.td().tx("Deleted");      
094    }
095    for (BaseWrapper e : list.children("entry")) {
096      tr = t.tr();
097      shortForRef(tr.td(), e.get("item"));
098      if (date) {
099        tr.td().tx(e.has("date") ? e.get("date").dateTimeValue().toHumanDisplay() : "");      
100      }
101      if (flag) {
102        tr.td().tx(e.has("flag") ? displayBase(e.get("flag")) : "");      
103      }
104      if (deleted) {
105        tr.td().tx(e.has("deleted") ? e.get("deleted").primitiveValue() : "");
106      }
107    }    
108    return false;
109  }
110  public boolean render(XhtmlNode x, ListResource list) throws FHIRFormatError, DefinitionException, IOException {
111    if (list.hasTitle()) {
112      x.h2().tx(list.getTitle());
113    }
114    XhtmlNode t = x.table("clstu");
115    XhtmlNode tr = t.tr();
116    if (list.hasDate()) {
117      tr.td().tx("Date: "+list.getDate().toLocaleString());
118    }
119    if (list.hasMode()) {
120      tr.td().tx("Mode: "+list.getMode().getDisplay());
121    }
122    if (list.hasStatus()) {
123      tr.td().tx("Status: "+list.getStatus().getDisplay());
124    }
125    if (list.hasCode()) {
126      tr.td().tx("Code: "+display(list.getCode()));
127    }    
128    tr = t.tr();
129    if (list.hasSubject()) {
130      shortForRef(tr.td().txN("Subject: "), list.getSubject());
131    }
132    if (list.hasEncounter()) {
133      shortForRef(tr.td().txN("Encounter: "), list.getEncounter());
134    }
135    if (list.hasSource()) {
136      shortForRef(tr.td().txN("Source: "), list.getEncounter());
137    }
138    if (list.hasOrderedBy()) {
139      tr.td().tx("Order: "+display(list.getOrderedBy()));
140    }
141    for (Annotation a : list.getNote()) {
142      renderAnnotation(x, a);
143    }
144    boolean flag = false;
145    boolean deleted = false;
146    boolean date = false;
147    for (ListResourceEntryComponent e : list.getEntry()) {
148      flag = flag || e.hasFlag();
149      deleted = deleted || e.hasDeleted();
150      date = date || e.hasDate();
151    }
152    t = x.table("grid");
153    tr = t.tr().style("backgound-color: #eeeeee");
154    tr.td().b().tx("Items");
155    if (date) {
156      tr.td().tx("Date");      
157    }
158    if (flag) {
159      tr.td().tx("Flag");      
160    }
161    if (deleted) {
162      tr.td().tx("Deleted");      
163    }
164    for (ListResourceEntryComponent e : list.getEntry()) {
165      tr = t.tr();
166      shortForRef(tr.td(), e.getItem());
167      if (date) {
168        tr.td().tx(e.hasDate() ? e.getDate().toLocaleString() : "");      
169      }
170      if (flag) {
171        tr.td().tx(e.hasFlag() ? display(e.getFlag()) : "");      
172      }
173      if (deleted) {
174        tr.td().tx(e.hasDeleted() ? Boolean.toString(e.getDeleted()) : "");
175      }
176    }    
177    return false;
178  }
179
180  public void describe(XhtmlNode x, ListResource list) {
181    x.tx(display(list));
182  }
183
184  public String display(ListResource list) {
185    return list.getTitle();
186  }
187
188  @Override
189  public String display(Resource r) throws UnsupportedEncodingException, IOException {
190    return ((ListResource) r).getTitle();
191  }
192
193  @Override
194  public String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException {
195    if (r.has("title")) {
196      return r.children("title").get(0).getBase().primitiveValue();
197    }
198    return "??";
199  }
200
201  private void shortForRef(XhtmlNode x, Reference ref) throws UnsupportedEncodingException, IOException {
202    ResourceWithReference r = context.getResolver().resolve(context, ref.getReference());
203    if (r == null) {
204      x.tx(display(ref));
205    } else {
206      RendererFactory.factory(r.getResource().getName(), context).renderReference(r.getResource(), x, ref);
207    }
208  }
209
210
211  private XhtmlNode shortForRef(XhtmlNode x, Base ref) throws UnsupportedEncodingException, IOException {
212    if (ref == null) {
213      x.tx("(null)");
214    } else {
215      String disp = ref.getChildByName("display") != null && ref.getChildByName("display").hasValues() ? ref.getChildByName("display").getValues().get(0).primitiveValue() : null;
216      if (ref.getChildByName("reference").hasValues()) {
217        String url = ref.getChildByName("reference").getValues().get(0).primitiveValue();
218        ResourceWithReference r = context.getResolver().resolve(context, url);
219        if (r == null) {
220          if (disp == null) {
221            disp = url;
222          }
223          x.tx(disp);
224        } else if (r.getResource() != null) {
225          RendererFactory.factory(r.getResource().getName(), context).renderReference(r.getResource(), x, (Reference) ref);
226        } else {
227          RendererFactory.factory(url, context).renderReference(r.getResource(), x, (Reference) ref);
228        }
229      } else if (disp != null) {
230        x.tx(disp);      
231      } else {
232        x.tx("?ngen-16?");
233      }     
234    }
235    return x;
236  }
237}