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.DefinitionException;
008import org.hl7.fhir.exceptions.FHIRException;
009import org.hl7.fhir.exceptions.FHIRFormatError;
010import org.hl7.fhir.r5.extensions.ExtensionDefinitions;
011import org.hl7.fhir.r5.model.OperationOutcome;
012import org.hl7.fhir.r5.model.OperationOutcome.OperationOutcomeIssueComponent;
013import org.hl7.fhir.r5.renderers.utils.RenderingContext;
014import org.hl7.fhir.r5.renderers.utils.ResourceWrapper;
015import org.hl7.fhir.r5.utils.EOperationOutcome;
016
017import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
018import org.hl7.fhir.utilities.MarkedToMoveToAdjunctPackage;
019import org.hl7.fhir.utilities.xhtml.XhtmlNode; 
020 
021@MarkedToMoveToAdjunctPackage
022public class OperationOutcomeRenderer extends ResourceRenderer { 
023
024
025  public OperationOutcomeRenderer(RenderingContext context) { 
026    super(context); 
027  } 
028 
029  
030  @Override
031  public String buildSummary(ResourceWrapper r) throws UnsupportedEncodingException, IOException {
032    List<ResourceWrapper> issues = r.children("issue");
033    int hint = 0;
034    int warn = 0;
035    int err = 0;
036    for (ResourceWrapper issue : issues) {
037      switch (issue.primitiveValue("severity")) {
038      case "information" : 
039        hint++; 
040        break;
041      case "warning" : 
042        warn++; 
043        break;
044      case "error" : 
045      case "fatal" : 
046        err++; 
047        break;
048      }
049    }
050    if (hint + warn + err == 0) {
051      return context.formatPhrase(RenderingContext.OP_OUT_SUMM_ALL_OK);
052    } else if (hint == 0) {
053      return context.formatPhrase(RenderingContext.OP_OUT_SUMM_NOHINT, err, warn);
054    } else {
055      return context.formatPhrase(RenderingContext.OP_OUT_SUMM, err, warn, hint);
056    }
057  }
058
059  @Override
060  public void buildNarrative(RenderingStatus status, XhtmlNode x, ResourceWrapper op) throws FHIRFormatError, DefinitionException, IOException, FHIRException, EOperationOutcome {
061    renderResourceTechDetails(op, x);
062    boolean hasSource = false; 
063    boolean success = true; 
064    for (ResourceWrapper i : op.children("issue")) { 
065      success = success && "information".equals(i.primitiveValue("severity")); 
066      hasSource = hasSource || i.hasExtension(ExtensionDefinitions.EXT_ISSUE_SOURCE);
067    } 
068    if (success) { 
069      x.para().tx(context.formatPhrase(RenderingContext.OP_OUT_OK));
070    }
071    if (op.has("issue")) { 
072      XhtmlNode tbl = x.table("grid", false); // on the basis that we'll most likely be rendered using the standard fhir css, but it doesn't really matter 
073      XhtmlNode tr = tbl.tr(); 
074      tr.td().b().tx(context.formatPhrase(RenderingContext.OP_OUT_SEV)); 
075      tr.td().b().tx(context.formatPhrase(RenderingContext.GENERAL_LOCATION)); 
076      tr.td().b().tx(context.formatPhrase(RenderingContext.GENERAL_CODE)); 
077      tr.td().b().tx(context.formatPhrase(RenderingContext.GENERAL_DETAILS)); 
078      tr.td().b().tx(context.formatPhrase(RenderingContext.OP_OUT_DIAG)); 
079      if (hasSource) {
080        tr.td().b().tx(context.formatPhrase(RenderingContext.OP_OUT_SRC));
081      }
082      for (ResourceWrapper i : op.children("issue")) { 
083        tr = tbl.tr(); 
084        tr.td().addText(getTranslatedCode(i.child("severity"))); 
085        XhtmlNode td = tr.td(); 
086        boolean d = false; 
087        for (ResourceWrapper s : i.has("expression") ? i.children("expression") : i.children("location")) { 
088          if (d) 
089            td.tx(", "); 
090          else 
091            d = true; 
092          td.addText(s.primitiveValue()); 
093        } 
094        tr.td().addText(getTranslatedCode(i.child("code")));
095        if (i.has("details"))
096          tr.td().addText(i.child("details").primitiveValue("text"));
097        tr.td().addTextWithLineBreaks(i.primitiveValue("diagnostics")); 
098        if (hasSource) { 
099          ResourceWrapper ext = i.extension(ExtensionDefinitions.EXT_ISSUE_SOURCE); 
100          tr.td().addText(ext == null || !ext.has("value") ? "" : displayDataType(ext.child("value"))); 
101        } 
102      } 
103    } 
104  } 
105
106
107  public void describe(XhtmlNode x, OperationOutcome oo) { 
108    x.tx(display(oo)); 
109  } 
110 
111  public String display(OperationOutcome oo) { 
112    return (context.formatPhrase(RenderingContext.GENERAL_TODO)); 
113  } 
114 
115  public static String toString(OperationOutcome oo) { 
116    CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(); 
117    for (OperationOutcomeIssueComponent issue : oo.getIssue()) { 
118      b.append(issue.getSeverity().toCode()+": "+issue.getDetails().getText()); 
119    } 
120    return b.toString(); 
121  } 
122}