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.DomainResource; 010import org.hl7.fhir.r5.model.Resource; 011import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper; 012import org.hl7.fhir.r5.renderers.utils.RenderingContext; 013import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext; 014import org.hl7.fhir.r5.utils.EOperationOutcome; 015import org.hl7.fhir.r5.utils.LiquidEngine; 016import org.hl7.fhir.r5.utils.LiquidEngine.LiquidDocument; 017import org.hl7.fhir.utilities.xhtml.NodeType; 018import org.hl7.fhir.utilities.xhtml.XhtmlNode; 019import org.hl7.fhir.utilities.xhtml.XhtmlParser; 020 021public class LiquidRenderer extends ResourceRenderer { 022 023 private String liquidTemplate; 024 025 public LiquidRenderer(RenderingContext context, String liquidTemplate) { 026 super(context); 027 this.liquidTemplate = liquidTemplate; 028 } 029 030 public LiquidRenderer(RenderingContext context, ResourceContext rcontext, String liquidTemplate) { 031 super(context); 032 this.rcontext = rcontext; 033 this.liquidTemplate = liquidTemplate; 034 } 035 036 @Override 037 public boolean render(XhtmlNode x, Resource r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome { 038 LiquidEngine engine = new LiquidEngine(context.getWorker(), context.getServices()); 039 XhtmlNode xn; 040 try { 041 LiquidDocument doc = engine.parse(liquidTemplate, "template"); 042 String html = engine.evaluate(doc, r, rcontext); 043 xn = new XhtmlParser().parseFragment(html); 044 if (!x.getName().equals("div")) 045 throw new FHIRException("Error in template: Root element is not 'div'"); 046 } catch (FHIRException | IOException e) { 047 xn = new XhtmlNode(NodeType.Element, "div"); 048 xn.para().b().style("color: maroon").tx("Exception generating Narrative: "+e.getMessage()); 049 } 050 x.getChildNodes().addAll(xn.getChildNodes()); 051 return true; 052 } 053 054 @Override 055 public String display(Resource r) throws UnsupportedEncodingException, IOException { 056 return "not done yet"; 057 } 058 059 public String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException { 060 if (r.has("title")) { 061 return r.children("title").get(0).getBase().primitiveValue(); 062 } 063 if (r.has("name")) { 064 return r.children("name").get(0).getBase().primitiveValue(); 065 } 066 return "??"; 067 } 068 069 @Override 070 public boolean render(XhtmlNode x, ResourceWrapper r) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome { 071 LiquidEngine engine = new LiquidEngine(context.getWorker(), context.getServices()); 072 XhtmlNode xn; 073 try { 074 LiquidDocument doc = engine.parse(liquidTemplate, "template"); 075 String html = engine.evaluate(doc, r.getBase(), rcontext); 076 xn = new XhtmlParser().parseFragment(html); 077 if (!x.getName().equals("div")) 078 throw new FHIRException("Error in template: Root element is not 'div'"); 079 } catch (FHIRException | IOException e) { 080 xn = new XhtmlNode(NodeType.Element, "div"); 081 xn.para().b().style("color: maroon").tx("Exception generating Narrative: "+e.getMessage()); 082 } 083 x.getChildNodes().addAll(xn.getChildNodes()); 084 return true; 085 } 086 087}