
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.DomainResource; 009import org.hl7.fhir.r5.model.Resource; 010import org.hl7.fhir.r5.model.CapabilityStatement; 011import org.hl7.fhir.r5.model.CapabilityStatement.CapabilityStatementRestComponent; 012import org.hl7.fhir.r5.model.CapabilityStatement.CapabilityStatementRestResourceComponent; 013import org.hl7.fhir.r5.model.CapabilityStatement.ResourceInteractionComponent; 014import org.hl7.fhir.r5.model.CapabilityStatement.SystemInteractionComponent; 015import org.hl7.fhir.r5.model.CapabilityStatement.SystemRestfulInteraction; 016import org.hl7.fhir.r5.model.CapabilityStatement.TypeRestfulInteraction; 017import org.hl7.fhir.r5.model.CanonicalType; 018import org.hl7.fhir.r5.renderers.utils.RenderingContext; 019import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper; 020import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext; 021import org.hl7.fhir.utilities.xhtml.NodeType; 022import org.hl7.fhir.utilities.xhtml.XhtmlNode; 023 024public class CapabilityStatementRenderer extends ResourceRenderer { 025 026 public CapabilityStatementRenderer(RenderingContext context) { 027 super(context); 028 } 029 030 public CapabilityStatementRenderer(RenderingContext context, ResourceContext rcontext) { 031 super(context, rcontext); 032 } 033 034 public boolean render(XhtmlNode x, Resource dr) throws FHIRFormatError, DefinitionException, IOException { 035 return render(x, (CapabilityStatement) dr); 036 } 037 038 public boolean render(XhtmlNode x, CapabilityStatement conf) throws FHIRFormatError, DefinitionException, IOException { 039 x.h2().addText(conf.getName()); 040 addMarkdown(x, conf.getDescription()); 041 if (conf.getRest().size() > 0) { 042 CapabilityStatementRestComponent rest = conf.getRest().get(0); 043 XhtmlNode t = x.table(null); 044 addTableRow(t, "Mode", rest.getMode().toString()); 045 addMarkdown(addTableRow(t, "Description"), rest.getDocumentation()); 046 047 addTableRow(t, "Transaction", showOp(rest, SystemRestfulInteraction.TRANSACTION)); 048 addTableRow(t, "System History", showOp(rest, SystemRestfulInteraction.HISTORYSYSTEM)); 049 addTableRow(t, "System Search", showOp(rest, SystemRestfulInteraction.SEARCHSYSTEM)); 050 051 boolean hasVRead = false; 052 boolean hasPatch = false; 053 boolean hasDelete = false; 054 boolean hasHistory = false; 055 boolean hasUpdates = false; 056 for (CapabilityStatementRestResourceComponent r : rest.getResource()) { 057 hasVRead = hasVRead || hasOp(r, TypeRestfulInteraction.VREAD); 058 hasPatch = hasPatch || hasOp(r, TypeRestfulInteraction.PATCH); 059 hasDelete = hasDelete || hasOp(r, TypeRestfulInteraction.DELETE); 060 hasHistory = hasHistory || hasOp(r, TypeRestfulInteraction.HISTORYTYPE); 061 hasUpdates = hasUpdates || hasOp(r, TypeRestfulInteraction.HISTORYINSTANCE); 062 } 063 064 t = x.table(null); 065 XhtmlNode tr = t.tr(); 066 tr.th().b().tx("Resource Type"); 067 tr.th().b().tx("Profile"); 068 tr.th().b().attribute("title", "GET a resource (read interaction)").tx("Read"); 069 if (hasVRead) 070 tr.th().b().attribute("title", "GET past versions of resources (vread interaction)").tx("V-Read"); 071 tr.th().b().attribute("title", "GET all set of resources of the type (search interaction)").tx("Search"); 072 tr.th().b().attribute("title", "PUT a new resource version (update interaction)").tx("Update"); 073 if (hasPatch) 074 tr.th().b().attribute("title", "PATCH a new resource version (patch interaction)").tx("Patch"); 075 tr.th().b().attribute("title", "POST a new resource (create interaction)").tx("Create"); 076 if (hasDelete) 077 tr.th().b().attribute("title", "DELETE a resource (delete interaction)").tx("Delete"); 078 if (hasUpdates) 079 tr.th().b().attribute("title", "GET changes to a resource (history interaction on instance)").tx("Updates"); 080 if (hasHistory) 081 tr.th().b().attribute("title", "GET changes for all resources of the type (history interaction on type)").tx("History"); 082 083 XhtmlNode profCell = null; 084 boolean hasProf = false; 085 boolean hasSupProf = false; 086 for (CapabilityStatementRestResourceComponent r : rest.getResource()) { 087 tr = t.tr(); 088 tr.td().addText(r.getType()); 089 090 //Show profiles 091 profCell = tr.td(); 092 hasProf = r.hasProfile(); 093 hasSupProf = r.hasSupportedProfile(); 094 if ((!hasProf) && (!hasSupProf)) { 095 profCell.nbsp(); 096 } 097 else if (hasProf) { 098 profCell.ah(r.getProfile()).addText(r.getProfile()); 099 if (hasSupProf) { 100 profCell.br(); 101 profCell.addText("Additional supported profiles:"); 102 for (CanonicalType sp: r.getSupportedProfile()) { 103 profCell.br(); 104 profCell.nbsp().nbsp(); 105 profCell.ah(sp.getValue()).addText(sp.getValue()); 106 } 107 } 108 } 109 else { //Case of only supported profiles 110 profCell.addText("Supported profiles:"); 111 for (CanonicalType sp: r.getSupportedProfile()) { 112 profCell.br(); 113 profCell.nbsp().nbsp(); 114 profCell.ah(sp.getValue()).addText(sp.getValue()); 115 } 116 } 117 //Show capabilities 118 tr.td().addText(showOp(r, TypeRestfulInteraction.READ)); 119 if (hasVRead) 120 tr.td().addText(showOp(r, TypeRestfulInteraction.VREAD)); 121 tr.td().addText(showOp(r, TypeRestfulInteraction.SEARCHTYPE)); 122 tr.td().addText(showOp(r, TypeRestfulInteraction.UPDATE)); 123 if (hasPatch) 124 tr.td().addText(showOp(r, TypeRestfulInteraction.PATCH)); 125 tr.td().addText(showOp(r, TypeRestfulInteraction.CREATE)); 126 if (hasDelete) 127 tr.td().addText(showOp(r, TypeRestfulInteraction.DELETE)); 128 if (hasUpdates) 129 tr.td().addText(showOp(r, TypeRestfulInteraction.HISTORYINSTANCE)); 130 if (hasHistory) 131 tr.td().addText(showOp(r, TypeRestfulInteraction.HISTORYTYPE)); 132 } 133 } 134 135 return true; 136 } 137 138 public void describe(XhtmlNode x, CapabilityStatement cs) { 139 x.tx(display(cs)); 140 } 141 142 public String display(CapabilityStatement cs) { 143 return cs.present(); 144 } 145 146 @Override 147 public String display(Resource r) throws UnsupportedEncodingException, IOException { 148 return ((CapabilityStatement) r).present(); 149 } 150 151 152 private boolean hasOp(CapabilityStatementRestResourceComponent r, TypeRestfulInteraction on) { 153 for (ResourceInteractionComponent op : r.getInteraction()) { 154 if (op.getCode() == on) 155 return true; 156 } 157 return false; 158 } 159 160 private String showOp(CapabilityStatementRestResourceComponent r, TypeRestfulInteraction on) { 161 for (ResourceInteractionComponent op : r.getInteraction()) { 162 if (op.getCode() == on) 163 return "y"; 164 } 165 return ""; 166 } 167 168 private String showOp(CapabilityStatementRestComponent r, SystemRestfulInteraction on) { 169 for (SystemInteractionComponent op : r.getInteraction()) { 170 if (op.getCode() == on) 171 return "y"; 172 } 173 return ""; 174 } 175 176 private XhtmlNode addTableRow(XhtmlNode t, String name) { 177 XhtmlNode tr = t.tr(); 178 tr.td().addText(name); 179 return tr.td(); 180 } 181 182 private void addTableRow(XhtmlNode t, String name, String value) { 183 XhtmlNode tr = t.tr(); 184 tr.td().addText(name); 185 tr.td().addText(value); 186 } 187 188 public String display(ResourceWrapper r) throws UnsupportedEncodingException, IOException { 189 if (r.has("title")) { 190 return r.children("title").get(0).getBase().primitiveValue(); 191 } 192 if (r.has("name")) { 193 return r.children("name").get(0).getBase().primitiveValue(); 194 } 195 return "??"; 196 } 197 198}