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