001package org.hl7.fhir.r5.renderers; 002 003import java.io.IOException; 004import java.io.UnsupportedEncodingException; 005 006import org.hl7.fhir.exceptions.FHIRException; 007import org.hl7.fhir.r5.model.CodeType; 008import org.hl7.fhir.r5.model.Extension; 009import org.hl7.fhir.r5.model.OperationDefinition; 010import org.hl7.fhir.r5.model.OperationDefinition.OperationDefinitionParameterComponent; 011import org.hl7.fhir.r5.model.Resource; 012import org.hl7.fhir.r5.model.StructureDefinition; 013import org.hl7.fhir.r5.renderers.utils.RenderingContext; 014import org.hl7.fhir.r5.renderers.utils.RenderingContext.KnownLinkType; 015import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext; 016import org.hl7.fhir.r5.utils.EOperationOutcome; 017import org.hl7.fhir.r5.utils.ToolingExtensions; 018import org.hl7.fhir.utilities.Utilities; 019import org.hl7.fhir.utilities.xhtml.XhtmlNode; 020 021public class OperationDefinitionRenderer extends TerminologyRenderer { 022 023 public OperationDefinitionRenderer(RenderingContext context) { 024 super(context); 025 } 026 027 public OperationDefinitionRenderer(RenderingContext context, ResourceContext rcontext) { 028 super(context, rcontext); 029 } 030 031 public boolean render(XhtmlNode x, Resource dr) throws IOException, FHIRException, EOperationOutcome { 032 return render(x, (OperationDefinition) dr); 033 } 034 035 public boolean render(XhtmlNode x, OperationDefinition opd) throws IOException, FHIRException, EOperationOutcome { 036 if (context.isHeader()) { 037 x.h2().addText(opd.getName()); 038 x.para().addText(Utilities.capitalize(opd.getKind().toString())+": "+opd.getName()); 039 x.para().tx("The official URL for this operation definition is: "); 040 x.pre().tx(opd.getUrl()); 041 addMarkdown(x, opd.getDescription());} 042 043 if (opd.getSystem()) 044 x.para().tx("URL: [base]/$"+opd.getCode()); 045 for (CodeType c : opd.getResource()) { 046 if (opd.getType()) 047 x.para().tx("URL: [base]/"+c.getValue()+"/$"+opd.getCode()); 048 if (opd.getInstance()) 049 x.para().tx("URL: [base]/"+c.getValue()+"/[id]/$"+opd.getCode()); 050 } 051 052 if (opd.hasInputProfile()) { 053 XhtmlNode p = x.para(); 054 p.tx("Input parameters Profile: "); 055 StructureDefinition sd = context.getContext().fetchResource(StructureDefinition.class, opd.getInputProfile(), opd); 056 if (sd == null) { 057 p.pre().tx(opd.getInputProfile()); 058 } else { 059 p.ah(sd.getUserString("path")).tx(sd.present()); 060 } 061 } 062 if (opd.hasOutputProfile()) { 063 XhtmlNode p = x.para(); 064 p.tx("Output parameters Profile: "); 065 StructureDefinition sd = context.getContext().fetchResource(StructureDefinition.class, opd.getOutputProfile(), opd); 066 if (sd == null) { 067 p.pre().tx(opd.getOutputProfile()); 068 } else { 069 p.ah(sd.getUserString("path")).tx(sd.present()); 070 } 071 } 072 x.para().tx("Parameters"); 073 XhtmlNode tbl = x.table( "grid"); 074 XhtmlNode tr = tbl.tr(); 075 tr.td().b().tx("Use"); 076 tr.td().b().tx("Name"); 077 tr.td().b().tx("Cardinality"); 078 tr.td().b().tx("Type"); 079 tr.td().b().tx("Binding"); 080 tr.td().b().tx("Documentation"); 081 for (OperationDefinitionParameterComponent p : opd.getParameter()) { 082 genOpParam(tbl, "", p, opd); 083 } 084 addMarkdown(x, opd.getComment()); 085 return true; 086 } 087 088 public void describe(XhtmlNode x, OperationDefinition opd) { 089 x.tx(display(opd)); 090 } 091 092 public String display(OperationDefinition opd) { 093 return opd.present(); 094 } 095 096 @Override 097 public String display(Resource r) throws UnsupportedEncodingException, IOException { 098 return ((OperationDefinition) r).present(); 099 } 100 101 private void genOpParam(XhtmlNode tbl, String path, OperationDefinitionParameterComponent p, Resource opd) throws EOperationOutcome, FHIRException, IOException { 102 XhtmlNode tr; 103 tr = tbl.tr(); 104 tr.td().addText(p.getUse().toString()); 105 tr.td().addText(path+p.getName()); 106 tr.td().addText(Integer.toString(p.getMin())+".."+p.getMax()); 107 XhtmlNode td = tr.td(); 108 StructureDefinition sd = p.getType() != null ? context.getWorker().fetchTypeDefinition(p.getType().toCode()) : null; 109 if (sd == null) 110 td.tx(p.hasType() ? p.getType().toCode() : ""); 111 else if (sd.getAbstract() && p.hasExtension(ToolingExtensions.EXT_ALLOWED_TYPE)) { 112 boolean first = true; 113 for (Extension ex : p.getExtensionsByUrl(ToolingExtensions.EXT_ALLOWED_TYPE)) { 114 if (first) first = false; else td.tx(" | "); 115 String s = ex.getValue().primitiveValue(); 116 StructureDefinition sdt = context.getWorker().fetchTypeDefinition(s); 117 if (sdt == null) 118 td.tx(p.hasType() ? p.getType().toCode() : ""); 119 else 120 td.ah(sdt.getUserString("path")).tx(s); 121 } 122 } else 123 td.ah(sd.getUserString("path")).tx(p.hasType() ? p.getType().toCode() : ""); 124 if (p.hasSearchType()) { 125 td.br(); 126 td.tx("("); 127 td.ah( context.getLink(KnownLinkType.SPEC) == null ? "search.html#"+p.getSearchType().toCode() : Utilities.pathURL(context.getLink(KnownLinkType.SPEC), "search.html#"+p.getSearchType().toCode())).tx(p.getSearchType().toCode()); 128 td.tx(")"); 129 } 130 td = tr.td(); 131 if (p.hasBinding() && p.getBinding().hasValueSet()) { 132 AddVsRef(p.getBinding().getValueSet(), td, opd); 133 td.tx(" ("+p.getBinding().getStrength().getDisplay()+")"); 134 } 135 addMarkdown(tr.td(), p.getDocumentation()); 136 if (!p.hasType()) { 137 for (OperationDefinitionParameterComponent pp : p.getPart()) { 138 genOpParam(tbl, path+p.getName()+".", pp, opd); 139 } 140 } 141 } 142 143}