From bd52aa527749900f668cc5188db0bb0260e90826 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Fri, 29 Sep 2023 13:35:15 +1000 Subject: [PATCH] Fix problem rendering additional bindings in R5 --- .../renderers/AdditionalBindingsRenderer.java | 48 ++++++++++++++++ .../StructureDefinitionRenderer.java | 57 +++++++++++++++++++ 2 files changed, 105 insertions(+) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/AdditionalBindingsRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/AdditionalBindingsRenderer.java index 92a5651fe..836745fb5 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/AdditionalBindingsRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/AdditionalBindingsRenderer.java @@ -186,6 +186,18 @@ public class AdditionalBindingsRenderer { return abr; } + protected AdditionalBindingDetail additionalBinding(ElementDefinitionBindingAdditionalComponent ab) { + AdditionalBindingDetail abr = new AdditionalBindingDetail(); + abr.purpose = ab.getPurpose().toCode(); + abr.valueSet = ab.getValueSet(); + abr.doco = ab.getDocumentation(); + abr.docoShort = ab.getShortDoco(); + abr.usage = ab.hasUsage() ? ab.getUsageFirstRep() : null; + abr.any = ab.getAny(); + abr.isUnchanged = ab.hasUserData(ProfileUtilities.UD_DERIVATION_EQUALS); + return abr; + } + public String render() throws IOException { if (bindings.isEmpty()) { return ""; @@ -455,4 +467,40 @@ public class AdditionalBindingsRenderer { } + public void seeAdditionalBindings(ElementDefinition definition, ElementDefinition compDef, boolean compare) { + HashMap compBindings = new HashMap(); + if (compare && compDef.getBinding().getAdditional() != null) { + for (ElementDefinitionBindingAdditionalComponent ab : compDef.getBinding().getAdditional()) { + AdditionalBindingDetail abr = additionalBinding(ab); + if (compBindings.containsKey(abr.getKey())) { + abr.incrementCount(); + } + compBindings.put(abr.getKey(), abr); + } + } + + for (ElementDefinitionBindingAdditionalComponent ab : definition.getBinding().getAdditional()) { + AdditionalBindingDetail abr = additionalBinding(ab); + if (compare && compDef != null) { + AdditionalBindingDetail match = null; + do { + match = compBindings.get(abr.getKey()); + if (abr.alreadyMatched()) + abr.incrementCount(); + } while (match!=null && abr.alreadyMatched()); + if (match!=null) + abr.setCompare(match); + bindings.add(abr); + if (abr.compare!=null) + compBindings.remove(abr.compare.getKey()); + } else + bindings.add(abr); + } + for (AdditionalBindingDetail b: compBindings.values()) { + b.removed = true; + bindings.add(b); + } + + } + } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/StructureDefinitionRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/StructureDefinitionRenderer.java index 011161f2c..3be82060c 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/StructureDefinitionRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/StructureDefinitionRenderer.java @@ -68,6 +68,7 @@ import org.hl7.fhir.r5.model.UriType; import org.hl7.fhir.r5.model.ValueSet; import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper; import org.hl7.fhir.r5.renderers.StructureDefinitionRenderer.InternalMarkdownProcessor; +import org.hl7.fhir.r5.renderers.StructureDefinitionRenderer.SourcedElementDefinition; import org.hl7.fhir.r5.renderers.utils.RenderingContext; import org.hl7.fhir.r5.renderers.utils.RenderingContext.GenerationRules; import org.hl7.fhir.r5.renderers.utils.RenderingContext.KnownLinkType; @@ -157,6 +158,25 @@ public class StructureDefinitionRenderer extends ResourceRenderer { // // } + public class SourcedElementDefinition { + private StructureDefinition profile; + private ElementDefinition definition; + + + protected SourcedElementDefinition(StructureDefinition profile, ElementDefinition definition) { + super(); + this.profile = profile; + this.definition = definition; + } + public StructureDefinition getProfile() { + return profile; + } + public ElementDefinition getDefinition() { + return definition; + } + + } + public class InternalMarkdownProcessor implements IMarkdownProcessor { @Override @@ -1320,6 +1340,22 @@ public class StructureDefinitionRenderer extends ResourceRenderer { } } } + if (logicalModel) { + List ancestors = new ArrayList<>(); + getAncestorElements(profile, ancestors); + if (ancestors.size() > 0) { + c.addPiece(gen.new Piece("br")); + c.addPiece(gen.new Piece(null, "Elements defined in Ancestors: ", null)); + boolean first = true; + for (SourcedElementDefinition ed : ancestors) { + if (first) + first = false; + else + c.addPiece(gen.new Piece(null, ", ", null)); + c.addPiece(gen.new Piece(ed.getProfile().getWebPath(), (isAttr(ed) ? "@" : "")+ed.getDefinition().getName(), ed.getDefinition().getDefinition())); + } + } + } } if (definition.getPath().endsWith("url") && definition.hasFixed()) { c.getPieces().add(checkForNoChange(definition.getFixed(), gen.new Piece(null, "\""+buildJson(definition.getFixed())+"\"", null).addStyle("color: darkgreen"))); @@ -1552,6 +1588,7 @@ public class StructureDefinitionRenderer extends ResourceRenderer { } AdditionalBindingsRenderer abr = new AdditionalBindingsRenderer(context.getPkp(), corePath, profile, definition.getPath(), rc, null, this); + abr.seeAdditionalBindings(definition, null, false); if (binding.hasExtension(ToolingExtensions.EXT_MAX_VALUESET)) { abr.seeMaxBinding(ToolingExtensions.getExtension(binding, ToolingExtensions.EXT_MAX_VALUESET)); } @@ -1651,6 +1688,26 @@ public class StructureDefinitionRenderer extends ResourceRenderer { return c; } + private boolean isAttr(SourcedElementDefinition ed) { + for (Enumeration t : ed.getDefinition().getRepresentation()) { + if (t.getValue() == PropertyRepresentation.XMLATTR) { + return true; + } + } + return false; + } + + private void getAncestorElements(StructureDefinition profile, List ancestors) { + StructureDefinition base = context.getContext().fetchResource(StructureDefinition.class, profile.getBaseDefinition()); + if (base != null) { + getAncestorElements(base, ancestors); + for (ElementDefinition ed : base.getDifferential().getElement()) { + if (Utilities.charCount(ed.getPath(), '.') == 1) { + ancestors.add(new SourcedElementDefinition(base, ed)); + } + } + } + } private void addCanonicalListExt(HierarchicalTableGenerator gen, Cell c, List list, String start, boolean bold) { List clist = new ArrayList<>();