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