001package org.hl7.fhir.r5.renderers; 002 003import java.io.IOException; 004import java.nio.charset.Charset; 005import java.nio.charset.StandardCharsets; 006import java.util.ArrayList; 007import java.util.List; 008 009import org.hl7.fhir.r5.model.Binary; 010import org.hl7.fhir.utilities.TextFile; 011import org.hl7.fhir.utilities.Utilities; 012import org.hl7.fhir.utilities.xhtml.NodeType; 013import org.hl7.fhir.utilities.xhtml.XhtmlComposer; 014import org.hl7.fhir.utilities.xhtml.XhtmlNode; 015 016public class BinaryRenderer { 017 018 private String folder; 019 private List<String> filenames = new ArrayList<String>(); 020 021 public BinaryRenderer(String folder) { 022 super(); 023 this.folder = folder; 024 } 025 026 public String getFolder() { 027 return folder; 028 } 029 030 public List<String> getFilenames() { 031 return filenames; 032 } 033 034 public static String getBinContentAsString(Binary bin) { 035 // for now, assume UTF8. To do: extract character encoding from mime type if possible (charset) 036 return new String(bin.getContent(), StandardCharsets.UTF_8); 037 } 038 039 public String display(Binary bin) throws IOException { 040 XhtmlNode div = new XhtmlNode(NodeType.Element, "div"); 041 render(div, bin); 042 return new XhtmlComposer(false, true).compose(div); 043 } 044 045 046 public void render(XhtmlNode x, Binary bin) throws IOException { 047 filenames.clear(); 048 if (!bin.hasContentType()) { 049 error(x, "No Content Type"); 050 } else if (bin.getContentType().startsWith("image/")) { 051 image(x, bin); 052 } else if (isXml(bin.getContentType())) { 053 xml(x, bin); 054 } else if (isJson(bin.getContentType())) { 055 json(x, bin); 056 } else if (isTtl(bin.getContentType())) { 057 ttl(x, bin); 058 } else if (isText(bin.getContentType())) { 059 text(x, bin); 060 } else { 061 error(x, "The Content Type '"+bin.getContentType()+"' is not rendered in this context"); 062 } 063 } 064 065 066 private void image(XhtmlNode x, Binary bin) throws IOException { 067 String ext = null; 068 if (bin.getContentType().startsWith("image/png")) { 069 ext = ".png"; 070 } else if (bin.getContentType().startsWith("image/jpeg")) { 071 ext = ".jpg"; 072 } else if (bin.getContentType().startsWith("image/gif")) { 073 ext = ".gif"; 074 } else if (bin.getContentType().startsWith("image/svg")) { 075 ext = ".svg"; 076 } 077 078 if (ext == null) { 079 error(x, "The Image Type '"+bin.getContentType()+"' is not rendered in this context"); 080 } else { 081 String fn = "Binary-Native-"+bin.getId()+ext; 082 TextFile.bytesToFile(bin.getContent(), Utilities.path(folder, fn)); 083 filenames.add(fn); 084 x.img("Binary-Native-"+bin.getId()+ext); 085 } 086 } 087 088 private void error(XhtmlNode x, String message) { 089 x.tx("["+message+"]"); 090 } 091 092 private boolean isXml(String ct) { 093 return ct.startsWith("text/xml") || ct.startsWith("application/xml") || ct.contains("+xml"); 094 } 095 096 private void xml(XhtmlNode x, Binary bin) { 097 String content = "\r\n"+getBinContentAsString(bin); 098 XhtmlNode pre = x.pre("xml"); 099 pre.code(content); 100 } 101 102 private boolean isJson(String ct) { 103 return ct.startsWith("text/json") || ct.startsWith("application/json") || ct.contains("+json"); 104 } 105 106 private void json(XhtmlNode x, Binary bin) { 107 String content = "\r\n"+getBinContentAsString(bin); 108 XhtmlNode pre = x.pre("json"); 109 pre.code(content); 110 } 111 112 private boolean isTtl(String ct) { 113 return ct.startsWith("text/rdf") || ct.contains("+turtle"); 114 } 115 116 private void ttl(XhtmlNode x, Binary bin) { 117 String content = "\r\n"+getBinContentAsString(bin); 118 XhtmlNode pre = x.pre("rdf language-turtle"); 119 pre.code(content); 120 } 121 122 123 private boolean isText(String ct) { 124 return ct.startsWith("text/"); 125 } 126 127 private void text(XhtmlNode x, Binary bin) { 128 String content = "\r\n"+getBinContentAsString(bin); 129 XhtmlNode pre = x.pre(); 130 pre.code(content); 131 } 132 133 134}