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