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