001package org.hl7.fhir.r5.renderers; 002 003import java.io.IOException; 004import java.io.UnsupportedEncodingException; 005import java.util.List; 006 007import org.hl7.fhir.exceptions.FHIRException; 008import org.hl7.fhir.r5.model.CodeType; 009import org.hl7.fhir.r5.model.Enumeration; 010import org.hl7.fhir.r5.model.Enumerations.SearchComparator; 011import org.hl7.fhir.r5.model.Enumerations.SearchModifierCode; 012import org.hl7.fhir.r5.model.Enumerations.VersionIndependentResourceTypesAll; 013import org.hl7.fhir.r5.model.OperationDefinition; 014import org.hl7.fhir.r5.model.Resource; 015import org.hl7.fhir.r5.model.SearchParameter; 016import org.hl7.fhir.r5.model.SearchParameter.SearchParameterComponentComponent; 017import org.hl7.fhir.r5.model.StringType; 018import org.hl7.fhir.r5.model.StructureDefinition; 019import org.hl7.fhir.r5.renderers.utils.RenderingContext; 020import org.hl7.fhir.r5.renderers.utils.RenderingContext.KnownLinkType; 021import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext; 022import org.hl7.fhir.r5.utils.EOperationOutcome; 023import org.hl7.fhir.r5.utils.ToolingExtensions; 024import org.hl7.fhir.utilities.StandardsStatus; 025import org.hl7.fhir.utilities.Utilities; 026import org.hl7.fhir.utilities.xhtml.XhtmlNode; 027 028public class SearchParameterRenderer extends TerminologyRenderer { 029 030 public SearchParameterRenderer(RenderingContext context) { 031 super(context); 032 } 033 034 public SearchParameterRenderer(RenderingContext context, ResourceContext rcontext) { 035 super(context, rcontext); 036 } 037 038 public boolean render(XhtmlNode x, Resource dr) throws IOException, FHIRException, EOperationOutcome { 039 return render(x, (SearchParameter) dr); 040 } 041 042 public boolean render(XhtmlNode x, SearchParameter spd) throws IOException, FHIRException, EOperationOutcome { 043 XhtmlNode h2 = x.h2(); 044 h2.addText(spd.getName()); 045 StandardsStatus ss = ToolingExtensions.getStandardsStatus(spd); 046 if (ss != context.getDefaultStandardsStatus()) { 047 genStandardsStatus(h2, ss); 048 } 049 XhtmlNode p = x.para(); 050 p.tx("Parameter "); 051 p.code().tx(spd.getCode()); 052 p.tx(":"); 053 p.code().tx(spd.getType().toCode()); 054 addMarkdown(x, spd.getDescription()); 055 056 XhtmlNode tbl = x.table("grid"); 057 XhtmlNode tr = tbl.tr(); 058 tr.td().tx(Utilities.pluralize("Resource", spd.getBase().size())); 059 XhtmlNode td = tr.td(); 060 for (Enumeration<VersionIndependentResourceTypesAll> t : spd.getBase()) { 061 StructureDefinition sd = context.getWorker().fetchTypeDefinition(t.getCode()); 062 if (sd != null && sd.hasWebPath()) { 063 td.sep(", "); 064 td.ah(sd.getWebPath()).tx(t.getCode()); 065 } else { 066 td.sep(", "); 067 td.tx(t.getCode()); 068 } 069 } 070 tr = tbl.tr(); 071 tr.td().tx("Expression"); 072 if (spd.hasExpression()) { 073 tr.td().code().tx(spd.getExpression()); 074 } else { 075 tr.td().tx("(none)"); 076 } 077 if (spd.hasProcessingMode()) { 078 tr = tbl.tr(); 079 tr.td().tx("Processing Mode"); 080 tr.td().tx(spd.getProcessingMode().getDisplay()); 081 } 082 if (spd.hasTarget()) { 083 tr = tbl.tr(); 084 tr.td().tx(Utilities.pluralize("Target Resources", spd.getTarget().size())); 085 td = tr.td(); 086 if (isAllConcreteResources(spd.getTarget())) { 087 td.ah(Utilities.pathURL(context.getLink(KnownLinkType.SPEC), "resourcelist.html")).tx("All Resources"); 088 } else { 089 for (Enumeration<VersionIndependentResourceTypesAll> t : spd.getTarget()) { 090 StructureDefinition sd = context.getWorker().fetchTypeDefinition(t.getCode()); 091 if (sd != null && sd.hasWebPath()) { 092 td.sep(", "); 093 td.ah(sd.getWebPath()).tx(t.getCode()); 094 } else { 095 td.sep(", "); 096 td.tx(t.getCode()); 097 } 098 } 099 } 100 } 101 tr = tbl.tr(); 102 tr.td().tx("Multiples"); 103 if (spd.getMultipleAnd() && spd.getMultipleOr()) { 104 tr.td().tx("The parameter can repeat (and) and can have repeating values (or)"); 105 } else if (spd.getMultipleOr()) { 106 tr.td().tx("The parameter can repeat (and) but each repeat can only have one value"); 107 } else if (spd.getMultipleAnd()) { 108 tr.td().tx("The parameter cannot repeat (and) but the single parameter can have multiple values (or)"); 109 } else { 110 tr.td().tx("The parameter cannot repeat or have multiple values"); 111 } 112 if (spd.hasComparator()) { 113 tr = tbl.tr(); 114 tr.td().tx("Comparators"); 115 td = tr.td(); 116 td.tx("Allowed: "); 117 for (Enumeration<SearchComparator> t : spd.getComparator()) { 118 td.sep(", "); 119 td.tx(t.asStringValue()); 120 } 121 } 122 if (spd.hasModifier()) { 123 tr = tbl.tr(); 124 tr.td().tx("Modifiers"); 125 td = tr.td(); 126 td.tx("Allowed: "); 127 for (Enumeration<SearchModifierCode> t : spd.getModifier()) { 128 td.sep(", "); 129 td.tx(t.asStringValue()); 130 } 131 } 132 if (spd.hasChain()) { 133 tr = tbl.tr(); 134 tr.td().tx("Chains"); 135 td = tr.td(); 136 td.tx("Allowed: "); 137 for (StringType t : spd.getChain()) { 138 td.sep(", "); 139 td.tx(t.asStringValue()); 140 } 141 } 142 143 if (spd.hasComponent()) { 144 x.para().b().tx("Components"); 145 tbl = x.table("grid"); 146 for (SearchParameterComponentComponent t : spd.getComponent()) { 147 tr = tbl.tr(); 148 SearchParameter tsp = context.getWorker().fetchResource(SearchParameter.class, t.getDefinition(), spd); 149 if (tsp != null && tsp.hasWebPath()) { 150 tr.td().ah(tsp.getWebPath()).tx(tsp.present()); 151 } else { 152 tr.td().tx(t.getDefinition()); 153 } 154 tr.td().code().tx(t.getExpression()); 155 } 156 } 157 return false; 158 } 159 160 private boolean isAllConcreteResources(List<Enumeration<VersionIndependentResourceTypesAll>> list) { 161 for (String s : context.getWorker().getResourceNames()) { 162 StructureDefinition sd = context.getWorker().fetchTypeDefinition(s); 163 if (!sd.getAbstract() && !Utilities.existsInList(sd.getType(), "Parameters")) { 164 boolean found = false; 165 for (Enumeration<VersionIndependentResourceTypesAll> c : list) { 166 found = found || sd.getName().equals(c.getCode()); 167 } 168 if (!found) { 169 return false; 170 } 171 } 172 } 173 return true; 174 } 175 176 public void describe(XhtmlNode x, OperationDefinition opd) { 177 x.tx(display(opd)); 178 } 179 180 public String display(OperationDefinition opd) { 181 return opd.present(); 182 } 183 184 @Override 185 public String display(Resource r) throws UnsupportedEncodingException, IOException { 186 return ((SearchParameter) r).present(); 187 } 188 189}