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(context.formatPhrase(RenderingContext.GENERAL_PAR)+" "); 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(context.formatPhrase(RenderingContext.GENERAL_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(context.formatPhrase(RenderingContext.SEARCH_PAR_EXP)); 072 if (spd.hasExpression()) { 073 tr.td().code().tx(spd.getExpression()); 074 } else { 075 tr.td().tx(context.formatPhrase(RenderingContext.SEARCH_PAR_NONE)); 076 } 077 if (spd.hasProcessingMode()) { 078 tr = tbl.tr(); 079 tr.td().tx(context.formatPhrase(RenderingContext.SEARCH_PAR_PROC)); 080 tr.td().tx(spd.getProcessingMode().getDisplay()); 081 } 082 if (spd.hasTarget()) { 083 tr = tbl.tr(); 084 tr.td().tx(Utilities.pluralize(context.formatPhrase(RenderingContext.SEARCH_PAR_REND_TARGET), spd.getTarget().size())); 085 td = tr.td(); 086 if (isAllConcreteResources(spd.getTarget())) { 087 td.ah(Utilities.pathURL(context.getLink(KnownLinkType.SPEC), "resourcelist.html")).tx(context.formatPhrase(RenderingContext.SEARCH_PAR_RES)); 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(context.formatPhrase(RenderingContext.SEARCH_PAR_MULTIPLES)); 103 XhtmlNode ul = tr.td().ul(); 104 if (!spd.hasMultipleAnd()) { 105 ul.li().tx(context.formatPhrase(RenderingContext.SEARCH_PAR_MULTIPLE_AND_SERVER)); 106 } else if (spd.getMultipleAnd()) { 107 ul.li().tx(context.formatPhrase(RenderingContext.SEARCH_PAR_MULTIPLE_AND_REPEAT)); 108 } else { 109 ul.li().tx(context.formatPhrase(RenderingContext.SEARCH_PAR_MULTIPLE_AND_APPEAR)); 110 } 111 if (!spd.hasMultipleOr()) { 112 ul.li().tx(context.formatPhrase(RenderingContext.SEARCH_PAR_MULTIPLE_OR_SERVER)); 113 } else if (spd.getMultipleOr()) { 114 ul.li().tx(context.formatPhrase(RenderingContext.SEARCH_PAR_MULTIPLE_OR_MULTIPLE)); 115 } else { 116 ul.li().tx(context.formatPhrase(RenderingContext.SEARCH_PAR_MULTIPLE_OR_ONE)); 117 } 118 119 if (spd.hasComparator()) { 120 tr = tbl.tr(); 121 tr.td().tx(context.formatPhrase(RenderingContext.GENERAL_COMPARATORS)); 122 td = tr.td(); 123 td.tx(context.formatPhrase(RenderingContext.SEARCH_PAR_ALLOWED)+" "); 124 for (Enumeration<SearchComparator> t : spd.getComparator()) { 125 td.sep(", "); 126 td.tx(t.asStringValue()); 127 } 128 } 129 if (spd.hasModifier()) { 130 tr = tbl.tr(); 131 tr.td().tx(context.formatPhrase(RenderingContext.GENERAL_MODIFIERS)); 132 td = tr.td(); 133 td.tx(context.formatPhrase(RenderingContext.SEARCH_PAR_ALLOWED)+" "); 134 for (Enumeration<SearchModifierCode> t : spd.getModifier()) { 135 td.sep(", "); 136 td.tx(t.asStringValue()); 137 } 138 } 139 if (spd.hasChain()) { 140 tr = tbl.tr(); 141 tr.td().tx(context.formatPhrase(RenderingContext.SEARCH_PAR_CHAIN)); 142 td = tr.td(); 143 td.tx(context.formatPhrase(RenderingContext.SEARCH_PAR_ALLOWED)+" "); 144 for (StringType t : spd.getChain()) { 145 td.sep(", "); 146 td.tx(t.asStringValue()); 147 } 148 } 149 150 if (spd.hasComponent()) { 151 x.para().b().tx(context.formatPhrase(RenderingContext.GENERAL_COMPARATORS)); 152 tbl = x.table("grid"); 153 for (SearchParameterComponentComponent t : spd.getComponent()) { 154 tr = tbl.tr(); 155 SearchParameter tsp = context.getWorker().fetchResource(SearchParameter.class, t.getDefinition(), spd); 156 if (tsp != null && tsp.hasWebPath()) { 157 tr.td().ah(tsp.getWebPath()).tx(tsp.present()); 158 } else { 159 tr.td().tx(t.getDefinition()); 160 } 161 tr.td().code().tx(t.getExpression()); 162 } 163 } 164 return false; 165 } 166 167 private boolean isAllConcreteResources(List<Enumeration<VersionIndependentResourceTypesAll>> list) { 168 for (String s : context.getWorker().getResourceNames()) { 169 StructureDefinition sd = context.getWorker().fetchTypeDefinition(s); 170 if (!sd.getAbstract() && !Utilities.existsInList(sd.getType(), context.formatPhrase(RenderingContext.GENERAL_PAR))) { 171 boolean found = false; 172 for (Enumeration<VersionIndependentResourceTypesAll> c : list) { 173 found = found || sd.getName().equals(c.getCode()); 174 } 175 if (!found) { 176 return false; 177 } 178 } 179 } 180 return true; 181 } 182 183 public void describe(XhtmlNode x, OperationDefinition opd) { 184 x.tx(display(opd)); 185 } 186 187 public String display(OperationDefinition opd) { 188 return opd.present(); 189 } 190 191 @Override 192 public String display(Resource r) throws UnsupportedEncodingException, IOException { 193 return ((SearchParameter) r).present(); 194 } 195 196}