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