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      shortForRef(tr.td().txN("Subject: "), list.getSubject());
130    }
131    if (list.hasEncounter()) {
132      shortForRef(tr.td().txN("Encounter: "), list.getEncounter());
133    }
134    if (list.hasSource()) {
135      shortForRef(tr.td().txN("Source: "), list.getEncounter());
136    }
137    if (list.hasOrderedBy()) {
138      tr.td().tx("Order: "+display(list.getOrderedBy()));
139    }
140    for (Annotation a : list.getNote()) {
141      renderAnnotation(x, a);
142    }
143    boolean flag = false;
144    boolean deleted = false;
145    boolean date = false;
146    for (ListResourceEntryComponent e : list.getEntry()) {
147      flag = flag || e.hasFlag();
148      deleted = deleted || e.hasDeleted();
149      date = date || e.hasDate();
150    }
151    t = x.table("grid");
152    tr = t.tr().style("backgound-color: #eeeeee");
153    tr.td().b().tx("Items");
154    if (date) {
155      tr.td().tx("Date");      
156    }
157    if (flag) {
158      tr.td().tx("Flag");      
159    }
160    if (deleted) {
161      tr.td().tx("Deleted");      
162    }
163    for (ListResourceEntryComponent e : list.getEntry()) {
164      tr = t.tr();
165      shortForRef(tr.td(), e.getItem());
166      if (date) {
167        tr.td().tx(e.hasDate() ? e.getDate().toLocaleString() : "");      
168      }
169      if (flag) {
170        tr.td().tx(e.hasFlag() ? display(e.getFlag()) : "");      
171      }
172      if (deleted) {
173        tr.td().tx(e.hasDeleted() ? Boolean.toString(e.getDeleted()) : "");
174      }
175    }    
176    return false;
177  }
178
179  public void describe(XhtmlNode x, ListResource list) {
180    x.tx(display(list));
181  }
182
183  public String display(ListResource list) {
184    return list.getTitle();
185  }
186
187  @Override
188  public String display(Resource r) throws UnsupportedEncodingException, IOException {
189    return ((ListResource) r).getTitle();
190  }
191
192  @Override
193  public String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException {
194    if (r.has("title")) {
195      return r.children("title").get(0).getBase().primitiveValue();
196    }
197    return "??";
198  }
199
200  private void shortForRef(XhtmlNode x, Reference ref) throws UnsupportedEncodingException, IOException {
201    ResourceWithReference r = context.getResolver().resolve(context, ref.getReference());
202    if (r == null) {
203      x.tx(display(ref));
204    } else {
205      RendererFactory.factory(r.getResource().getName(), context).renderReference(r.getResource(), x, ref);
206    }
207  }
208
209  private XhtmlNode shortForRef(XhtmlNode x, Base ref) throws UnsupportedEncodingException, IOException {
210    if (ref == null) {
211      x.tx("(null)");
212    } else {
213      String disp = ref.getChildByName("display") != null && ref.getChildByName("display").hasValues() ? ref.getChildByName("display").getValues().get(0).primitiveValue() : null;
214      if (ref.getChildByName("reference").hasValues()) {
215        String url = ref.getChildByName("reference").getValues().get(0).primitiveValue();
216        if (url.startsWith("#")) {
217          x.tx("?ngen-16a?");
218        } else {
219          ResourceWithReference r = context.getResolver().resolve(context, url);
220          if (r == null) {
221            if (disp == null) {
222              disp = url;
223            }
224            x.tx(disp);
225          } else if (r.getResource() != null) {
226            RendererFactory.factory(r.getResource().getName(), context).renderReference(r.getResource(), x, (Reference) ref);
227          } else {
228            x.ah(r.getReference()).tx(url);
229          }
230        }
231      } else if (disp != null) {
232        x.tx(disp);      
233      } else {
234        x.tx("?ngen-16?");
235      }     
236    }
237    return x;
238  }
239}