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 247f3085a..43d47d795 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 @@ -11568,6 +11568,10 @@ When pattern[x] is used to constrain a complex object, it means that each proper public boolean isInlineType() { return getType().size() == 1 && Utilities.existsInList(getType().get(0).getCode(), "Element", "BackboneElement"); + } + + public boolean prohibited() { + return "0".equals(getMax()); } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/DataRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/DataRenderer.java index 1af3777b9..8c56701df 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/DataRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/DataRenderer.java @@ -30,6 +30,7 @@ import org.hl7.fhir.r5.context.IWorkerContext; import org.hl7.fhir.r5.context.IWorkerContext.ValidationResult; import org.hl7.fhir.r5.model.Address; import org.hl7.fhir.r5.model.Annotation; +import org.hl7.fhir.r5.model.BackboneType; import org.hl7.fhir.r5.model.Base; import org.hl7.fhir.r5.model.BaseDateTimeType; import org.hl7.fhir.r5.model.CanonicalResource; @@ -48,6 +49,7 @@ import org.hl7.fhir.r5.model.ContactPoint.ContactPointSystem; import org.hl7.fhir.r5.model.DataType; import org.hl7.fhir.r5.model.DateTimeType; import org.hl7.fhir.r5.model.DateType; +import org.hl7.fhir.r5.model.ElementDefinition; import org.hl7.fhir.r5.model.Enumeration; import org.hl7.fhir.r5.model.Expression; import org.hl7.fhir.r5.model.Extension; @@ -357,8 +359,138 @@ public class DataRenderer extends Renderer { return value.primitiveValue(); } + // -- 6. General purpose extension rendering ---------------------------------------------- - // -- 5. Data type Rendering ---------------------------------------------- + public boolean hasRenderableExtensions(DataType element) { + for (Extension ext : element.getExtension()) { + if (canRender(ext)) { + return true; + } + } + return false; + } + + public boolean hasRenderableExtensions(BackboneType element) { + for (Extension ext : element.getExtension()) { + if (canRender(ext)) { + return true; + } + } + return element.hasModifierExtension(); + } + + private String getExtensionLabel(Extension ext) { + StructureDefinition sd = context.getWorker().fetchResource(StructureDefinition.class, ext.getUrl()); + if (sd != null && ext.getValue().isPrimitive() && sd.hasSnapshot()) { + for (ElementDefinition ed : sd.getSnapshot().getElement()) { + if (Utilities.existsInList(ed.getPath(), "Extension", "Extension.value[x]") && ed.hasLabel()) { + return ed.getLabel(); + } + } + } + return null; + } + + private boolean canRender(Extension ext) { + return getExtensionLabel(ext) != null; + } + + public void renderExtensionsInList(XhtmlNode ul, DataType element) throws FHIRFormatError, DefinitionException, IOException { + for (Extension ext : element.getExtension()) { + if (canRender(ext)) { + String lbl = getExtensionLabel(ext); + XhtmlNode li = ul.li(); + li.tx(lbl); + li.tx(": "); + render(li, ext.getValue()); + } + } + } + + public void renderExtensionsInList(XhtmlNode ul, BackboneType element) throws FHIRFormatError, DefinitionException, IOException { + for (Extension ext : element.getModifierExtension()) { + if (canRender(ext)) { + String lbl = getExtensionLabel(ext); + XhtmlNode li = ul.li(); + li = li.b(); + li.tx(lbl); + li.tx(": "); + render(li, ext.getValue()); + } else { + // somehow have to do better than this + XhtmlNode li = ul.li(); + li.b().tx("WARNING: Unrenderable Modifier Extension!"); + } + } + for (Extension ext : element.getExtension()) { + if (canRender(ext)) { + String lbl = getExtensionLabel(ext); + XhtmlNode li = ul.li(); + li.tx(lbl); + li.tx(": "); + render(li, ext.getValue()); + } + } + } + + public void renderExtensionsInText(XhtmlNode div, DataType element, String sep) throws FHIRFormatError, DefinitionException, IOException { + boolean first = true; + for (Extension ext : element.getExtension()) { + if (canRender(ext)) { + if (first) { + first = false; + } else { + div.tx(sep); + div.tx(" "); + } + + String lbl = getExtensionLabel(ext); + div.tx(lbl); + div.tx(": "); + render(div, ext.getValue()); + } + } + } + + public void renderExtensionsInList(XhtmlNode div, BackboneType element, String sep) throws FHIRFormatError, DefinitionException, IOException { + boolean first = true; + for (Extension ext : element.getModifierExtension()) { + if (first) { + first = false; + } else { + div.tx(sep); + div.tx(" "); + } + if (canRender(ext)) { + String lbl = getExtensionLabel(ext); + XhtmlNode b = div.b(); + b.tx(lbl); + b.tx(": "); + render(div, ext.getValue()); + } else { + // somehow have to do better than this + div.b().tx("WARNING: Unrenderable Modifier Extension!"); + } + } + for (Extension ext : element.getExtension()) { + if (canRender(ext)) { + if (first) { + first = false; + } else { + div.tx(sep); + div.tx(" "); + } + + String lbl = getExtensionLabel(ext); + div.tx(lbl); + div.tx(": "); + render(div, ext.getValue()); + } + } + + } + + // -- 6. Data type Rendering ---------------------------------------------- public static String display(IWorkerContext context, DataType type) { return new DataRenderer(new RenderingContext(context, null, null, "http://hl7.org/fhir/R4", "", null, ResourceRendererMode.END_USER)).display(type); @@ -866,11 +998,11 @@ public class DataRenderer extends Renderer { return s; } - protected void renderCodeableConcept(XhtmlNode x, CodeableConcept cc) { + protected void renderCodeableConcept(XhtmlNode x, CodeableConcept cc) throws FHIRFormatError, DefinitionException, IOException { renderCodeableConcept(x, cc, false); } - protected void renderCodeableReference(XhtmlNode x, CodeableReference e, boolean showCodeDetails) { + protected void renderCodeableReference(XhtmlNode x, CodeableReference e, boolean showCodeDetails) throws FHIRFormatError, DefinitionException, IOException { if (e.hasConcept()) { renderCodeableConcept(x, e.getConcept(), showCodeDetails); } @@ -879,7 +1011,7 @@ public class DataRenderer extends Renderer { } } - protected void renderCodeableConcept(XhtmlNode x, CodeableConcept cc, boolean showCodeDetails) { + protected void renderCodeableConcept(XhtmlNode x, CodeableConcept cc, boolean showCodeDetails) throws FHIRFormatError, DefinitionException, IOException { if (cc.isEmpty()) { return; } @@ -935,6 +1067,12 @@ public class DataRenderer extends Renderer { sp.tx(" \""+c.getDisplay()+"\""); } } + if (hasRenderableExtensions(cc)) { + if (!first) { + sp.tx("; "); + } + renderExtensionsInText(sp, cc, ";"); + } sp.tx(")"); } else { diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/XVerExtensionManager.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/XVerExtensionManager.java index 5d7a69a4f..7d27c4782 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/XVerExtensionManager.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/XVerExtensionManager.java @@ -123,12 +123,12 @@ public class XVerExtensionManager { populateTypes(path, val, verSource, verTarget); } else if (path.has("elements")) { for (JsonElement i : path.getAsJsonArray("elements")) { - String s = i.getAsString(); + String s = i.getAsString().replace("[x]", ""); sd.getDifferential().addElement().setPath("Extension.extension").setSliceName(s); sd.getDifferential().addElement().setPath("Extension.extension.extension").setMax("0"); sd.getDifferential().addElement().setPath("Extension.extension.url").setFixed(new UriType(s)); ElementDefinition val = sd.getDifferential().addElement().setPath("Extension.extension.value[x]").setMin(1); - JsonObject elt = root.getAsJsonObject(e+"."+s); + JsonObject elt = root.getAsJsonObject(e+"."+i.getAsString()); if (!elt.has("types")) { throw new FHIRException("Internal error - nested elements not supported yet"); } diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/HierarchicalTableGenerator.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/HierarchicalTableGenerator.java index 18412cee5..9552a95fa 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/HierarchicalTableGenerator.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/xhtml/HierarchicalTableGenerator.java @@ -403,6 +403,11 @@ public class HierarchicalTableGenerator extends TranslatingUtilities { pieces.add(p); return p; } + public Piece addText(String text) { + Piece p = new Piece(null, text, null); + pieces.add(p); + return p; + } public String text() { StringBuilder b = new StringBuilder(); for (Piece p : pieces)