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