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.CanonicalType; 
008import org.hl7.fhir.r5.model.CodeType; 
009import org.hl7.fhir.r5.model.Enumeration; 
010import org.hl7.fhir.r5.model.Enumerations.FHIRTypes; 
011import org.hl7.fhir.r5.model.Enumerations.VersionIndependentResourceTypesAll; 
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.OperationDefinition.OperationParameterScope; 
016import org.hl7.fhir.r5.model.Resource; 
017import org.hl7.fhir.r5.model.StructureDefinition; 
018import org.hl7.fhir.r5.renderers.utils.RenderingContext; 
019import org.hl7.fhir.r5.renderers.utils.RenderingContext.KnownLinkType; 
020import org.hl7.fhir.r5.renderers.utils.Resolver.ResourceContext; 
021import org.hl7.fhir.r5.utils.EOperationOutcome; 
022import org.hl7.fhir.r5.utils.ToolingExtensions; 
023import org.hl7.fhir.utilities.CommaSeparatedStringBuilder; 
024import org.hl7.fhir.utilities.StandardsStatus; 
025import org.hl7.fhir.utilities.Utilities; 
026import org.hl7.fhir.utilities.VersionUtilities; 
027import org.hl7.fhir.utilities.xhtml.XhtmlNode; 
028 
029public class OperationDefinitionRenderer extends TerminologyRenderer { 
030 
031  public OperationDefinitionRenderer(RenderingContext context) { 
032    super(context); 
033  } 
034 
035  public OperationDefinitionRenderer(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, OperationDefinition opd) throws IOException, FHIRException, EOperationOutcome { 
044    if (context.isHeader()) { 
045      x.h2().addText(opd.getName()); 
046      x.para().addText(Utilities.capitalize(opd.getKind().toString())+": "+opd.getName());     
047      x.para().tx(context.formatPhrase(RenderingContext.OP_DEF_OFFIC)+" "); 
048      x.pre().tx(opd.getUrl()); 
049      addMarkdown(x, opd.getDescription());} 
050 
051    if (opd.getSystem()) 
052      x.para().tx(context.formatPhrase(RenderingContext.OP_DEF_URLS, opd.getCode())); 
053    for (Enumeration<VersionIndependentResourceTypesAll> c : opd.getResource()) { 
054      if (opd.getType()) 
055        x.para().tx(context.formatPhrase(RenderingContext.OP_DEF_URL, c.getCode()+"/$"+opd.getCode())); 
056      if (opd.getInstance()) 
057        x.para().tx(context.formatPhrase(RenderingContext.OP_DEF_URL, c.getCode()+"/[id]/$"+opd.getCode())); 
058    } 
059 
060    if (opd.hasInputProfile()) { 
061      XhtmlNode p = x.para(); 
062      p.tx(context.formatPhrase(RenderingContext.OP_DEF_INPAR)); 
063      StructureDefinition sd = context.getContext().fetchResource(StructureDefinition.class, opd.getInputProfile(), opd); 
064      if (sd == null) { 
065        p.pre().tx(opd.getInputProfile());         
066      } else { 
067        p.ah(sd.getWebPath()).tx(sd.present());                  
068      }       
069    } 
070    if (opd.hasOutputProfile()) { 
071      XhtmlNode p = x.para(); 
072      p.tx(context.formatPhrase(RenderingContext.OP_DEF_OUTPAR)); 
073      StructureDefinition sd = context.getContext().fetchResource(StructureDefinition.class, opd.getOutputProfile(), opd); 
074      if (sd == null) { 
075        p.pre().tx(opd.getOutputProfile());         
076      } else { 
077        p.ah(sd.getWebPath()).tx(sd.present());                  
078      }       
079    } 
080    x.para().tx(context.formatPhrase(RenderingContext.GENERAL_PARS)); 
081    XhtmlNode tbl = x.table( "grid"); 
082    XhtmlNode tr = tbl.tr(); 
083    tr.td().b().tx(context.formatPhrase(RenderingContext.OP_DEF_USE)); 
084    tr.td().b().tx(context.formatPhrase(RenderingContext.GENERAL_NAME)); 
085    tr.td().b().tx(context.formatPhrase(RenderingContext.OP_DEF_SCO)); 
086    tr.td().b().tx(context.formatPhrase(RenderingContext.GENERAL_CARDINALITY)); 
087    tr.td().b().tx(context.formatPhrase(RenderingContext.GENERAL_TYPE)); 
088    tr.td().b().tx(context.formatPhrase(RenderingContext.GENERAL_BINDING)); 
089    tr.td().b().tx(context.formatPhrase(RenderingContext.GENERAL_DOCUMENTATION)); 
090    for (OperationDefinitionParameterComponent p : opd.getParameter()) { 
091      genOpParam(tbl, "", p, opd); 
092    } 
093    addMarkdown(x, opd.getComment()); 
094    return true; 
095  } 
096 
097  public void describe(XhtmlNode x, OperationDefinition opd) { 
098    x.tx(display(opd)); 
099  } 
100 
101  public String display(OperationDefinition opd) { 
102    return opd.present(); 
103  } 
104 
105  @Override 
106  public String display(Resource r) throws UnsupportedEncodingException, IOException { 
107    return ((OperationDefinition) r).present(); 
108  } 
109 
110  private void genOpParam(XhtmlNode tbl, String path, OperationDefinitionParameterComponent p, Resource opd) throws EOperationOutcome, FHIRException, IOException { 
111    XhtmlNode tr; 
112    tr = tbl.tr(); 
113    tr.td().addText(p.getUse().toString()); 
114    XhtmlNode td = tr.td(); 
115    td.addText(path+p.getName()); 
116    StandardsStatus ss = ToolingExtensions.getStandardsStatus(p); 
117    genStandardsStatus(td, ss); 
118    td = tr.td(); 
119    if (p.hasScope()) { 
120      CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(); 
121      for (Enumeration<OperationParameterScope> s : p.getScope()) { 
122        b.append(s.getCode()); 
123      } 
124      td.tx(b.toString()); 
125    } 
126    tr.td().addText(Integer.toString(p.getMin())+".."+p.getMax()); 
127    td = tr.td(); 
128    String actualType = translateTypeToVersion(p.getTypeElement()); 
129    StructureDefinition sd = actualType != null ? context.getWorker().fetchTypeDefinition(actualType) : null; 
130    if (sd == null) 
131      td.tx(p.hasType() ? actualType : ""); 
132    else if (sd.getAbstract() && p.hasExtension(ToolingExtensions.EXT_ALLOWED_TYPE)) { 
133      boolean first = true; 
134      for (Extension ex : p.getExtensionsByUrl(ToolingExtensions.EXT_ALLOWED_TYPE)) { 
135        if (first) first = false; else td.tx(" | "); 
136        String s = ex.getValue().primitiveValue(); 
137        StructureDefinition sdt = context.getWorker().fetchTypeDefinition(s); 
138        if (sdt == null) 
139          td.tx(p.hasType() ? actualType : ""); 
140        else 
141          td.ah(sdt.getWebPath()).tx(s);          
142      } 
143    } else 
144      td.ah(sd.getWebPath()).tx(actualType); 
145    if (p.hasTargetProfile()) { 
146      td.tx(" ("); 
147      boolean first = true; 
148      for (CanonicalType tp : p.getTargetProfile()) { 
149        if (first) { first = false;} else {td.tx(", ");}; 
150        StructureDefinition sdt = context.getWorker().fetchTypeDefinition(tp.asStringValue()); 
151        if (sdt == null || !sdt.hasWebPath()) { 
152          td.code().tx(tp.asStringValue()); 
153        } else { 
154          td.ah(sdt.getWebPath(), tp.asStringValue()).tx(sdt.present()); 
155        } 
156      } 
157      td.tx(")"); 
158    } 
159    if (p.hasSearchType()) { 
160      td.br(); 
161      td.tx("("); 
162      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());        
163      td.tx(")"); 
164    } 
165    td = tr.td(); 
166    if (p.hasBinding() && p.getBinding().hasValueSet()) { 
167      AddVsRef(p.getBinding().getValueSet(), td, opd); 
168      td.tx(" ("+p.getBinding().getStrength().getDisplay()+")"); 
169    } 
170    addMarkdown(tr.td(), p.getDocumentation()); 
171    if (!p.hasType()) { 
172      for (OperationDefinitionParameterComponent pp : p.getPart()) { 
173        genOpParam(tbl, path+p.getName()+".", pp, opd); 
174      } 
175    } 
176  } 
177   
178  public static final String EXT_OPDEF_ORIGINAL_TYPE = "http://hl7.org/fhir/4.0/StructureDefinition/extension-OperationDefinition.parameter.type"; 
179 
180  private String translateTypeToVersion(Enumeration<FHIRTypes> src) { 
181    if (src.hasExtension(EXT_OPDEF_ORIGINAL_TYPE)) { 
182      return src.getExtensionString(EXT_OPDEF_ORIGINAL_TYPE); 
183    } else { 
184      return src.asStringValue(); 
185    } 
186  } 
187 
188 
189}