From cec8a36d359b82ee3e13b57de52b39e6d0274460 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Sun, 25 Feb 2024 19:20:24 +1100 Subject: [PATCH] Fix wrong URLs rendering Profiles and Questionnaires --- .../r5/renderers/QuestionnaireRenderer.java | 44 ++++++++++++------- .../StructureDefinitionRenderer.java | 19 ++++++-- 2 files changed, 44 insertions(+), 19 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/QuestionnaireRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/QuestionnaireRenderer.java index 58dc01eb1..7a9d55bb4 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/QuestionnaireRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/QuestionnaireRenderer.java @@ -7,6 +7,7 @@ import java.util.List; import org.hl7.fhir.exceptions.FHIRException; import org.hl7.fhir.r5.context.ContextUtilities; +import org.hl7.fhir.r5.model.CanonicalResource; import org.hl7.fhir.r5.model.CanonicalType; import org.hl7.fhir.r5.model.CodeType; import org.hl7.fhir.r5.model.CodeableConcept; @@ -224,14 +225,15 @@ public class QuestionnaireRenderer extends TerminologyRenderer { return Utilities.pathURL(context.getLink(KnownLinkType.SPEC), path); } - private String getSDCLink(String path) { - if (Utilities.isAbsoluteUrl(path)) { - StructureDefinition sd = context.getContext().fetchResource(StructureDefinition.class, path); - if (sd != null) { - return sd.getWebPath(); - } else { - return path.replace("StructureDefinition/", "StructureDefinition-")+".html"; - } + private String getSDCLink(String url, String path) { + StructureDefinition sd = context.getContext().fetchResource(StructureDefinition.class, url); + if (sd == null) { + sd = context.getContext().fetchResource(StructureDefinition.class, path); + } + if (sd != null && sd.hasWebPath()) { + return sd.getWebPath(); + } else if (Utilities.isAbsoluteUrl(path)) { + return path.replace("StructureDefinition/", "StructureDefinition-")+".html"; } else { return Utilities.pathURL("http://hl7.org/fhir/uv/sdc", path); // for now? } @@ -264,16 +266,16 @@ public class QuestionnaireRenderer extends TerminologyRenderer { flags.addPiece(gen.new Piece(Utilities.pathURL(context.getLink(KnownLinkType.SPEC), "questionnaire-definitions.html#Questionnaire.item.readOnly"), null, "Is Readonly").addHtml(new XhtmlNode(NodeType.Element, "img").attribute("alt", "icon").attribute("src", getImgPath("icon-qi-readonly.png")))); } if (ToolingExtensions.readBoolExtension(i, "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-isSubject")) { - flags.addPiece(gen.new Piece(getSDCLink("StructureDefinition-sdc-questionnaire-isSubject.html"), null, "Can change the subject of the questionnaire").addHtml(new XhtmlNode(NodeType.Element, "img").attribute("alt", "icon").attribute("src", getImgPath("icon-qi-subject.png")))); + flags.addPiece(gen.new Piece(getSDCLink("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-isSubject", "StructureDefinition-sdc-questionnaire-isSubject.html"), null, "Can change the subject of the questionnaire").addHtml(new XhtmlNode(NodeType.Element, "img").attribute("alt", "icon").attribute("src", getImgPath("icon-qi-subject.png")))); } if (ToolingExtensions.readBoolExtension(i, ToolingExtensions.EXT_Q_HIDDEN)) { flags.addPiece(gen.new Piece(getSpecLink("extension-questionnaire-hidden.html"), null, "Is a hidden item").addHtml(new XhtmlNode(NodeType.Element, "img").attribute("alt", "icon").attribute("src", getImgPath("icon-qi-hidden.png")))); } if (ToolingExtensions.readBoolExtension(i, ToolingExtensions.EXT_Q_OTP_DISP)) { - flags.addPiece(gen.new Piece(getSDCLink("StructureDefinition-sdc-questionnaire-optionalDisplay.html"), null, "Is optional to display").addHtml(new XhtmlNode(NodeType.Element, "img").attribute("alt", "icon").attribute("src", getImgPath("icon-qi-optional.png")))); + flags.addPiece(gen.new Piece(getSDCLink("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-optionalDisplay", "StructureDefinition-sdc-questionnaire-optionalDisplay.html"), null, "Is optional to display").addHtml(new XhtmlNode(NodeType.Element, "img").attribute("alt", "icon").attribute("src", getImgPath("icon-qi-optional.png")))); } if (i.hasExtension("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-observationLinkPeriod")) { - flags.addPiece(gen.new Piece(getSDCLink("StructureDefinition-sdc-questionnaire-observationLinkPeriod.html"), null, "Is linked to an observation").addHtml(new XhtmlNode(NodeType.Element, "img").attribute("alt", "icon").attribute("src", getImgPath("icon-qi-observation.png")))); + flags.addPiece(gen.new Piece(getSDCLink("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-observationLinkPeriod", "StructureDefinition-sdc-questionnaire-observationLinkPeriod.html"), null, "Is linked to an observation").addHtml(new XhtmlNode(NodeType.Element, "img").attribute("alt", "icon").attribute("src", getImgPath("icon-qi-observation.png")))); } if (i.hasExtension(ToolingExtensions.EXT_Q_CHOICE_ORIENT)) { String code = ToolingExtensions.readStringExtension(i, ToolingExtensions.EXT_Q_CHOICE_ORIENT); @@ -447,7 +449,12 @@ public class QuestionnaireRenderer extends TerminologyRenderer { private void addExpression(Piece p, Expression exp, String label, String url) { XhtmlNode x = new XhtmlNode(NodeType.Element, "li").style("font-size: 11px"); p.addHtml(x); - x.ah(url).tx(label); + CanonicalResource cr = (CanonicalResource) context.getContext().fetchResource(Resource.class, url); + if (cr != null && cr.hasWebPath()) { + x.ah(cr.getWebPath()).tx(label); + } else { + x.ah(url).tx(label); + } x.tx(": "); x.code(exp.getExpression()); } @@ -712,7 +719,7 @@ public class QuestionnaireRenderer extends TerminologyRenderer { if (ToolingExtensions.readBoolExtension(i, "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-isSubject")) { hasFlag = true; - flags.ah(getSDCLink("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-isSubject"), "Can change the subject of the questionnaire").img(getImgPath("icon-qi-subject.png"), "icon"); + flags.ah(getSDCLink("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-isSubject", "StructureDefinition-sdc-questionnaire-isSubject.html"), "Can change the subject of the questionnaire").img(getImgPath("icon-qi-subject.png"), "icon"); } if (ToolingExtensions.readBoolExtension(i, ToolingExtensions.EXT_Q_HIDDEN)) { hasFlag = true; @@ -721,11 +728,11 @@ public class QuestionnaireRenderer extends TerminologyRenderer { } if (ToolingExtensions.readBoolExtension(i, ToolingExtensions.EXT_Q_OTP_DISP)) { hasFlag = true; - flags.ah(getSDCLink(ToolingExtensions.EXT_Q_OTP_DISP), "Is optional to display").img(getImgPath("icon-qi-optional.png"), "icon"); + flags.ah(getSDCLink("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-optionalDisplay", "StructureDefinition-sdc-questionnaire-optionalDisplay.html"), "Is optional to display").img(getImgPath("icon-qi-optional.png"), "icon"); } if (i.hasExtension("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-observationLinkPeriod")) { hasFlag = true; - flags.ah(getSDCLink("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-observationLinkPeriod"), "Is linked to an observation").img(getImgPath("icon-qi-observation.png"), "icon"); + flags.ah(getSDCLink("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-observationLinkPeriod", "StructureDefinition-sdc-questionnaire-observationLinkPeriod.html"), "Is linked to an observation").img(getImgPath("icon-qi-observation.png"), "icon"); } if (i.hasExtension(ToolingExtensions.EXT_Q_DISPLAY_CAT)) { CodeableConcept cc = i.getExtensionByUrl(ToolingExtensions.EXT_Q_DISPLAY_CAT).getValueCodeableConcept(); @@ -1031,7 +1038,12 @@ public class QuestionnaireRenderer extends TerminologyRenderer { } if (qi.hasExtension("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-observationLinkPeriod")) { XhtmlNode tr = tbl.tr(); - tr.td().ah("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-observationLinkPeriod").tx("Observation Link Period"); + StructureDefinition sd = context.getContext().fetchResource(StructureDefinition.class, ToolingExtensions.EXT_O_LINK_PERIOD); + if (sd != null && sd.hasWebPath()) { + tr.td().ah(sd.getWebPath()).tx("Observation Link Period"); + } else { + tr.td().ah("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-observationLinkPeriod").tx("Observation Link Period"); + } render(tr.td(), qi.getExtensionByUrl("http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-observationLinkPeriod").getValue()); } 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 9c8a65411..76b90df45 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 @@ -1581,7 +1581,8 @@ public class StructureDefinitionRenderer extends ResourceRenderer { abr.render(gen, c); } for (ElementDefinitionConstraintComponent inv : definition.getConstraint()) { - if (!inv.hasSource() || profile == null || inv.getSource().equals(profile.getUrl()) || allInvariants) { +// if (!inv.hasSource() || profile == null || inv.getSource().equals(profile.getUrl()) || allInvariants) { + if (!inv.hasSource() || profile == null || allInvariants || (!isAbstractBaseProfile(inv.getSource()) && !"http://hl7.org/fhir/StructureDefinition/Extension".equals(inv.getSource()))) { if (!c.getPieces().isEmpty()) c.addPiece(gen.new Piece("br")); c.getPieces().add(checkForNoChange(inv, gen.new Piece(null, inv.getKey()+": ", null).addStyle("font-weight:bold"))); @@ -1668,6 +1669,11 @@ public class StructureDefinitionRenderer extends ResourceRenderer { return c; } + private boolean isAbstractBaseProfile(String source) { + StructureDefinition sd = context.getContext().fetchResource(StructureDefinition.class, source); + return (sd != null) && sd.getAbstract() && sd.hasUrl() && sd.getUrl().startsWith("http://hl7.org/fhir/StructureDefinition/"); + } + private Piece checkAddExternalFlag(BindingResolution br, Piece piece) { if (br.external) { piece.setTagImg("external.png"); @@ -2564,15 +2570,22 @@ public class StructureDefinitionRenderer extends ResourceRenderer { } public String listConstraintsAndConditions(ElementDefinition element) { + Set ids = new HashSet<>(); CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(); for (ElementDefinitionConstraintComponent con : element.getConstraint()) { if (!isBaseConstraint(con)) { - b.append(con.getKey()); + if (!ids.contains(con.getKey())) { + ids.add(con.getKey()); + b.append(con.getKey()); + } } } for (IdType id : element.getCondition()) { if (!isBaseCondition(id)) { - b.append(id.asStringValue()); + if (!ids.contains(id.asStringValue())) { + ids.add(id.asStringValue()); + b.append(id.asStringValue()); + } } } return b.toString();