All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.hl7.fhir.r4b.conformance.AdditionalBindingsRenderer Maven / Gradle / Ivy

The newest version!
package org.hl7.fhir.r4b.conformance;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.hl7.fhir.exceptions.DefinitionException;
import org.hl7.fhir.exceptions.FHIRFormatError;
import org.hl7.fhir.r4b.conformance.AdditionalBindingsRenderer.AdditionalBindingDetail;
import org.hl7.fhir.r4b.conformance.ProfileUtilities.ProfileKnowledgeProvider;
import org.hl7.fhir.r4b.conformance.ProfileUtilities.ProfileKnowledgeProvider.BindingResolution;
import org.hl7.fhir.r4b.model.Extension;
import org.hl7.fhir.r4b.model.StructureDefinition;
import org.hl7.fhir.r4b.model.UsageContext;
import org.hl7.fhir.r4b.renderers.DataRenderer;
import org.hl7.fhir.r4b.renderers.IMarkdownProcessor;
import org.hl7.fhir.r4b.renderers.utils.RenderingContext;
import org.hl7.fhir.r4b.utils.PublicationHacker;
import org.hl7.fhir.r4b.model.ElementDefinition.ElementDefinitionBindingComponent;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator;
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Cell;
import org.hl7.fhir.utilities.xhtml.HierarchicalTableGenerator.Piece;
import org.hl7.fhir.utilities.xhtml.NodeType;
import org.hl7.fhir.utilities.xhtml.XhtmlComposer;
import org.hl7.fhir.utilities.xhtml.XhtmlNode;

public class AdditionalBindingsRenderer {
  public class AdditionalBindingDetail {
    private String purpose;
    private String valueSet;
    private String doco;
    private UsageContext usage;
    private boolean any;
    private boolean unchanged;
  }

  private List bindings = new ArrayList<>();
  private ProfileKnowledgeProvider pkp;
  private String corePath;
  private StructureDefinition profile;
  private String path;
  private RenderingContext context;
  private IMarkdownProcessor md;

  public AdditionalBindingsRenderer(ProfileKnowledgeProvider pkp, String corePath, StructureDefinition profile,
      String path, RenderingContext context, IMarkdownProcessor md) {
    this.pkp = pkp;
    this.corePath = corePath;
    this.profile = profile;
    this.path = path;
    this.context = context;
    this.md = md;
  }

  public void seeMaxBinding(Extension ext) {
    AdditionalBindingDetail abr = new AdditionalBindingDetail();
    abr.purpose = "maximum";
    abr.valueSet = ext.getValue().primitiveValue();
    abr.unchanged = ext.hasUserData(ProfileUtilities.DERIVATION_EQUALS);
    bindings.add(abr);
  }

  public void seeMinBinding(Extension ext) {
    AdditionalBindingDetail abr = new AdditionalBindingDetail();
    abr.purpose = "minimum";
    abr.valueSet = ext.getValue().primitiveValue();
    abr.unchanged = ext.hasUserData(ProfileUtilities.DERIVATION_EQUALS);
    bindings.add(abr);
  }

  public void seeAdditionalBindings(List list) {
    for (Extension ext : list) {
      AdditionalBindingDetail abr = new AdditionalBindingDetail();
      abr.purpose = ext.getExtensionString("purpose");
      abr.valueSet = ext.getExtensionString("valueSet");
      abr.doco = ext.getExtensionString("documentation");
      abr.usage = (ext.hasExtension("usage")) && ext.getExtensionByUrl("usage").hasValueUsageContext()
          ? ext.getExtensionByUrl("usage").getValueUsageContext()
          : null;
      abr.any = "any".equals(ext.getExtensionString("scope"));
      abr.unchanged = ext.hasUserData(ProfileUtilities.DERIVATION_EQUALS);
      bindings.add(abr);
    }
  }

  public String render() throws IOException {
    if (bindings.isEmpty()) {
      return "";
    } else {
      XhtmlNode tbl = new XhtmlNode(NodeType.Element, "table");
      tbl.attribute("class", "grid");
      render(tbl.getChildNodes(), true);
      return new XhtmlComposer(false).compose(tbl);
    }
  }

  public void render(HierarchicalTableGenerator gen, Cell c) throws FHIRFormatError, DefinitionException, IOException {
    if (bindings.isEmpty()) {
      return;
    } else {
      Piece piece = gen.new Piece("table").attr("class", "grid");
      c.getPieces().add(piece);
      render(piece.getChildren(), false);
    }
  }

  private void render(List children, boolean doDoco)
      throws FHIRFormatError, DefinitionException, IOException {
    boolean doco = false;
    boolean usage = false;
    boolean any = false;
    for (AdditionalBindingDetail binding : bindings) {
      doco = doco || (doDoco && binding.doco != null);
      usage = usage || binding.usage != null;
      any = any || binding.any;
    }

    XhtmlNode tr = new XhtmlNode(NodeType.Element, "tr");
    children.add(tr);
    tr.td().style("font-size: 11px").b().tx("Additional Bindings");
    tr.td().style("font-size: 11px").tx("Purpose");
    if (usage) {
      tr.td().style("font-size: 11px").tx("Usage");
    }
    if (any) {
      tr.td().style("font-size: 11px").tx("Any");
    }
    if (doco) {
      tr.td().style("font-size: 11px").tx("Documentation");
    }
    for (AdditionalBindingDetail binding : bindings) {
      tr = new XhtmlNode(NodeType.Element, "tr");
      if (binding.unchanged) {
        tr.style("opacity: 0.5");
      }
      children.add(tr);
      BindingResolution br = pkp == null ? makeNullBr(binding) : pkp.resolveBinding(profile, binding.valueSet, path);

      if (br.url != null) {
        tr.td().style("font-size: 11px")
            .ah(Utilities.isAbsoluteUrl(br.url) || !pkp.prependLinks() ? br.url : corePath + br.url, binding.valueSet)
            .tx(br.display);
      } else {
        tr.td().style("font-size: 11px").span(null, binding.valueSet).tx(br.display);
      }
      renderPurpose(tr.td().style("font-size: 11px"), binding.purpose);
      if (usage) {
        if (binding.usage != null) {
          new DataRenderer(context).render(tr.td(), binding.usage);
        } else {
          tr.td();
        }
      }
      if (any) {
        if (binding.any) {
          tr.td().style("font-size: 11px").tx("Any repeat");
        } else {
          tr.td().style("font-size: 11px").tx("All repeats");
        }
      }
      if (doco) {
        if (binding.doco != null) {
          String d = md.processMarkdown("Binding.description", binding.doco);
          tr.td().style("font-size: 11px").innerHTML(d);
        } else {
          tr.td().style("font-size: 11px");
        }
      }
    }
  }

  private void renderPurpose(XhtmlNode td, String purpose) {
    switch (purpose) {
    case "maximum":
      td.ah(corePath + "extension-elementdefinition-maxvalueset.html",
          "A required binding, for use when the binding strength is 'extensible' or 'preferred'").tx("Max Binding");
      break;
    case "minimum":
      td.ah(corePath + "extension-elementdefinition-minvalueset.html",
          "The minimum allowable value set - any conformant system SHALL support all these codes").tx("Min Binding");
      break;
    case "conformance":
      td.ah(corePath + "terminologies.html#strength", "Validators will check this binding (strength = required)")
          .tx("Validation Criteria");
      break;
    case "current":
      td.span(null, "New records are required to use this value set, but legacy records may use other codes")
          .tx("Required");
      break;
    case "recommended":
      td.span(null, "This is the value set that is recommended (documentation should explain why)").tx("Recommended");
      break;
    case "ui":
      td.span(null, "This value set is provided to user look up in a given context").tx("UI");
      break;
    case "starter":
      td.span(null, "This value set is a good set of codes to start with when designing your system").tx("Starter");
      break;
    case "component":
      td.span(null, "This value set is a component of the base value set").tx("Component");
      break;
    default:
      td.span(null, "Unknown code for purpose").tx(purpose);
    }
  }

  private BindingResolution makeNullBr(AdditionalBindingDetail binding) {
    BindingResolution br = new BindingResolution();
    br.url = "http://none.none/none";
    br.display = "todo";
    return br;
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy