From af75c51fea4d2836ee58e95ed6d225eaf034d021 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Fri, 23 Aug 2024 21:50:53 +0800 Subject: [PATCH] Improve complex extension rendering when rendering by profile --- .../hl7/fhir/r5/model/ElementDefinition.java | 5 ++ .../fhir/r5/model/StructureDefinition.java | 5 ++ .../r5/renderers/ProfileDrivenRenderer.java | 52 ++++++++++++++----- .../r5/renderers/utils/ResourceWrapper.java | 14 ++++- .../hl7/fhir/r5/utils/ToolingExtensions.java | 1 + 5 files changed, 63 insertions(+), 14 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/ElementDefinition.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/ElementDefinition.java index a2ea355d4..e81d72850 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/ElementDefinition.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/ElementDefinition.java @@ -5625,6 +5625,11 @@ public boolean hasTarget() { @Block() public static class ElementDefinitionMappingComponent extends Element implements IBaseDatatypeElement { + @Override + public String toString() { + return identity+"=" + map; + } + /** * An internal reference to the definition of a mapping. */ diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/StructureDefinition.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/StructureDefinition.java index 7b5589721..e8876fa31 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/StructureDefinition.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/StructureDefinition.java @@ -397,6 +397,11 @@ public class StructureDefinition extends CanonicalResource { @Block() public static class StructureDefinitionMappingComponent extends BackboneElement implements IBaseBackboneElement { + @Override + public String toString() { + return identity + "=" + uri + " (\""+name+"\")"; + } + /** * An Internal id that is used to identify this mapping set when specific mappings are made. */ diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ProfileDrivenRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ProfileDrivenRenderer.java index 60ad608cd..09c9b1e90 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ProfileDrivenRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ProfileDrivenRenderer.java @@ -27,6 +27,7 @@ import org.hl7.fhir.r5.utils.ToolingExtensions; import org.hl7.fhir.r5.utils.XVerExtensionManager; import org.hl7.fhir.r5.utils.XVerExtensionManager.XVerExtensionStatus; import org.hl7.fhir.utilities.CommaSeparatedStringBuilder; +import org.hl7.fhir.utilities.DebugUtilities; import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.xhtml.NodeType; import org.hl7.fhir.utilities.xhtml.XhtmlNode; @@ -41,6 +42,9 @@ public class ProfileDrivenRenderer extends ResourceRenderer { @Override public void buildNarrative(RenderingStatus status, XhtmlNode x, ResourceWrapper r) throws FHIRFormatError, DefinitionException, IOException { + if ("medicationrequest-coded-oral-axid".equals(r.getId())) { + DebugUtilities.breakpoint(); + } renderResourceTechDetails(r, x); try { StructureDefinition sd = context.getContext().fetchTypeDefinition(r.fhirType()); @@ -332,13 +336,14 @@ public class ProfileDrivenRenderer extends ResourceRenderer { } } } else if (!round2 && !exemptFromRendering(child)) { - if (isExtension(p)) { + boolean isExt = isExtension(p); + if (isExt) { status.setExtensions(true); } List grandChildren = getChildrenForPath(profile, allElements, path+"."+p.getName()); filterGrandChildren(grandChildren, path+"."+p.getName(), p); if (p.getValues().size() > 0) { - if (isSimple(child)) { + if (isSimple(child) && !isExt) { XhtmlNode para = x.isPara() ? para = x : x.para(); String name = p.getName(); if (name.endsWith("[x]")) @@ -383,22 +388,40 @@ public class ProfileDrivenRenderer extends ResourceRenderer { x.add(tbl); } } else if (isExtension(p)) { + StructureDefinition sd = context.getContext().fetchResource(StructureDefinition.class, p.getUrl()); for (ResourceWrapper v : p.getValues()) { if (v != null) { ResourceWrapper vp = v.child("value"); List ev = v.children("extension"); if (vp != null) { XhtmlNode para = x.para(); - para.b().addText(labelforExtension(p.getName())); + para.b().addText(labelforExtension(sd, p.getUrl())); para.tx(": "); renderLeaf(status, res, vp, profile, child, x, para, false, showCodeDetails, displayHints, path, indent); } else if (!ev.isEmpty()) { - XhtmlNode bq = x.addTag("blockquote"); - bq.para().b().addText(labelforExtension(p.getName())); + XhtmlNode bq = x.addTag("blockquote"); + bq.para().b().addText(labelforExtension(sd, p.getUrl())); + // what happens now depends. If all the children are simple extensions, they'll be rendered as properties + boolean allSimple = true; for (ResourceWrapper vv : ev) { - StructureDefinition ex = context.getWorker().fetchTypeDefinition("Extension"); - List children = getChildrenForPath(profile, ex.getSnapshot().getElement(), "Extension"); - generateByProfile(status, res, ex, vv, allElements, child, children, bq, "Extension", showCodeDetails, indent+1); + if (!vv.has("value")) { + allSimple = false; + } + } + if (allSimple) { + XhtmlNode ul = bq.ul(); + for (ResourceWrapper vv : ev) { + XhtmlNode li = ul.li(); + li.tx(labelForSubExtension(vv.primitiveValue("url"), sd)); + li.tx(": "); + renderLeaf(status, res, vv.child("value"), sd, child, x, li, isExt, showCodeDetails, displayHints, path, indent); + } + } else { + for (ResourceWrapper vv : ev) { + StructureDefinition ex = context.getWorker().fetchTypeDefinition("Extension"); + List children = getChildrenForPath(profile, ex.getSnapshot().getElement(), "Extension"); + generateByProfile(status, res, ex, vv, allElements, child, children, bq, "Extension", showCodeDetails, indent+1); + } } } } @@ -417,8 +440,11 @@ public class ProfileDrivenRenderer extends ResourceRenderer { } - private String labelforExtension(String url) { - StructureDefinition sd = context.getContext().fetchResource(StructureDefinition.class, url); + private String labelForSubExtension(String url, StructureDefinition sd) { + return url; + } + + private String labelforExtension(StructureDefinition sd, String url) { if (sd == null) { return tail(url); } else { @@ -467,7 +493,7 @@ public class ProfileDrivenRenderer extends ResourceRenderer { } public boolean isExtension(NamedResourceWrapperList p) { - return p.getName().contains("extension["); + return p.getUrl() != null; } @@ -571,12 +597,12 @@ public class ProfileDrivenRenderer extends ResourceRenderer { // 2. Park it NamedResourceWrapperList nl = null; for (NamedResourceWrapperList t : results) { - if (t.getName().equals(url)) { + if (t.getUrl() != null && t.getUrl().equals(url)) { nl = t; } } if (nl == null) { - nl = new NamedResourceWrapperList(url); + nl = new NamedResourceWrapperList(p.getName(), url); results.add(nl); } nl.getValues().add(v); diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/utils/ResourceWrapper.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/utils/ResourceWrapper.java index 4ca925231..5bcf1bc2f 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/utils/ResourceWrapper.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/utils/ResourceWrapper.java @@ -31,16 +31,28 @@ public abstract class ResourceWrapper { public static class NamedResourceWrapperList { private String name; + private String url; // for extension definitions private List values = new ArrayList(); - + public NamedResourceWrapperList(String name) { super(); this.name = name; } + + public NamedResourceWrapperList(String name, String url) { + super(); + this.name = name; + this.url = url; + } public String getName() { return name; } + + public String getUrl() { + return url; + } + public List getValues() { return values; } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ToolingExtensions.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ToolingExtensions.java index d4c845bcf..8f38aa2f4 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ToolingExtensions.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ToolingExtensions.java @@ -275,6 +275,7 @@ public class ToolingExtensions { public static final String EXT_VS_CS_SUPPL_NEEDED = "http://hl7.org/fhir/StructureDefinition/valueset-supplement"; public static final String EXT_TYPE_PARAMETER = "http://hl7.org/fhir/tools/StructureDefinition/type-parameter"; public static final String EXT_ALTERNATE_CANONICAL = "http://hl7.org/fhir/StructureDefinition/alternate-canonical"; + public static final String EXT_SUPPRESSED = "http://hl7.org/fhir/StructureDefinition/elementdefinition-suppress"; // specific extension helpers