
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}