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.Enumeration; 012import org.hl7.fhir.r5.model.Extension; 013import org.hl7.fhir.r5.model.OperationDefinition; 014import org.hl7.fhir.r5.model.OperationDefinition.OperationDefinitionParameterComponent; 015import org.hl7.fhir.r5.model.Resource; 016import org.hl7.fhir.r5.model.SearchParameter; 017import org.hl7.fhir.r5.model.SearchParameter.SearchComparator; 018import org.hl7.fhir.r5.model.SearchParameter.SearchModifierCode; 019import org.hl7.fhir.r5.model.SearchParameter.SearchParameterComponentComponent; 020import org.hl7.fhir.r5.model.StringType; 021import org.hl7.fhir.r5.model.StructureDefinition; 022import org.hl7.fhir.r5.renderers.utils.RenderingContext; 023import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext; 024import org.hl7.fhir.r5.utils.EOperationOutcome; 025import org.hl7.fhir.r5.utils.ToolingExtensions; 026import org.hl7.fhir.utilities.Utilities; 027import org.hl7.fhir.utilities.xhtml.XhtmlNode; 028 029public class SearchParameterRenderer extends TerminologyRenderer { 030 031 public SearchParameterRenderer(RenderingContext context) { 032 super(context); 033 } 034 035 public SearchParameterRenderer(RenderingContext context, ResourceContext rcontext) { 036 super(context, rcontext); 037 } 038 039 public boolean render(XhtmlNode x, Resource dr) throws IOException, FHIRException, EOperationOutcome { 040 return render(x, (OperationDefinition) dr); 041 } 042 043 public boolean render(XhtmlNode x, SearchParameter spd) throws IOException, FHIRException, EOperationOutcome { 044 x.h2().addText(spd.getName()); 045 XhtmlNode p = x.para(); 046 p.tx("Parameter "); 047 p.code().tx(spd.getCode()); 048 p.tx(":"); 049 p.code().tx(spd.getType().toCode()); 050 addMarkdown(x, spd.getDescription()); 051 052 XhtmlNode tbl = x.table("grid"); 053 XhtmlNode tr = tbl.tr(); 054 tr.td().tx(Utilities.pluralize("Resource", spd.getBase().size())); 055 XhtmlNode td = tr.td(); 056 for (CodeType t : spd.getBase()) { 057 StructureDefinition sd = context.getWorker().fetchTypeDefinition(t.toString()); 058 if (sd != null && sd.hasUserData("path")) { 059 td.sep(", ").ah(sd.getUserString("path")).tx(t.getCode()); 060 } else { 061 td.sep(", ").tx(t.getCode()); 062 } 063 } 064 tr = tbl.tr(); 065 tr.td().tx("Expression"); 066 if (spd.hasExpression()) { 067 tr.td().code().tx(spd.getExpression()); 068 } else { 069 tr.td().tx("(none)"); 070 } 071 if (spd.hasXpathUsage()) { 072 tr = tbl.tr(); 073 tr.td().tx("Usage"); 074 tr.td().tx(spd.getXpathUsage().getDisplay()); 075 } 076 if (spd.hasXpath()) { 077 tr = tbl.tr(); 078 tr.td().tx("XPath"); 079 tr.td().code().tx(spd.getXpath()); 080 } 081 if (spd.hasTarget()) { 082 tr = tbl.tr(); 083 tr.td().tx(Utilities.pluralize("Target Resources", spd.getTarget().size())); 084 td = tr.td(); 085 for (CodeType t : spd.getTarget()) { 086 StructureDefinition sd = context.getWorker().fetchTypeDefinition(t.toString()); 087 if (sd != null && sd.hasUserData("path")) { 088 td.sep(", ").ah(sd.getUserString("path")).tx(t.getCode()); 089 } else { 090 td.sep(", ").tx(t.getCode()); 091 } 092 } 093 } 094 tr = tbl.tr(); 095 tr.td().tx("Multiples"); 096 if (spd.getMultipleAnd() && spd.getMultipleOr()) { 097 tr.td().tx("The parameter can repeat (and) and can have repeating values (or)"); 098 } else if (spd.getMultipleOr()) { 099 tr.td().tx("The parameter can repeat (and) but each repeat can only have one value"); 100 } else if (spd.getMultipleAnd()) { 101 tr.td().tx("The parameter cannot repeat (and) but the single parameter can have multiple values (or)"); 102 } else { 103 tr.td().tx("The parameter cannot repeat or have multiple values"); 104 } 105 if (spd.hasComparator()) { 106 tr = tbl.tr(); 107 tr.td().tx("Comparators"); 108 td = tr.td().tx("Allowed: "); 109 for (Enumeration<SearchComparator> t : spd.getComparator()) { 110 td.sep(", ").tx(t.asStringValue()); 111 } 112 } 113 if (spd.hasModifier()) { 114 tr = tbl.tr(); 115 tr.td().tx("Modifiers"); 116 td = tr.td().tx("Allowed: "); 117 for (Enumeration<SearchModifierCode> t : spd.getModifier()) { 118 td.sep(", ").tx(t.asStringValue()); 119 } 120 } 121 if (spd.hasChain()) { 122 tr = tbl.tr(); 123 tr.td().tx("Chains"); 124 td = tr.td().tx("Allowed: "); 125 for (StringType t : spd.getChain()) { 126 td.sep(", ").tx(t.asStringValue()); 127 } 128 } 129 130 if (spd.hasComponent()) { 131 x.para().b().tx("Components"); 132 tbl = x.table("grid"); 133 for (SearchParameterComponentComponent t : spd.getComponent()) { 134 tr = tbl.tr(); 135 SearchParameter tsp = context.getWorker().fetchResource(SearchParameter.class, t.getDefinition()); 136 if (tsp != null && tsp.hasUserData("path")) { 137 tr.td().ah(tsp.getUserString("path")).tx(tsp.present()); 138 } else { 139 tr.td().tx(t.getDefinition()); 140 } 141 tr.td().code().tx(t.getExpression()); 142 } 143 } 144 return false; 145 } 146 147 public void describe(XhtmlNode x, OperationDefinition opd) { 148 x.tx(display(opd)); 149 } 150 151 public String display(OperationDefinition opd) { 152 return opd.present(); 153 } 154 155 @Override 156 public String display(Resource r) throws UnsupportedEncodingException, IOException { 157 return ((OperationDefinition) r).present(); 158 } 159 160}