From 98373c1fd5d6c39432cef8581bba0e2456bc0a66 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Mon, 23 Sep 2024 09:12:01 -0400 Subject: [PATCH] Fix SCT link to include version and point to the right place --- .../hl7/fhir/r5/renderers/DataRenderer.java | 11 +-- .../fhir/r5/renderers/ValueSetRenderer.java | 30 +++----- .../utilities/SnomedUtilities.java | 74 +++++++++++++++++++ 3 files changed, 90 insertions(+), 25 deletions(-) create mode 100644 org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/utilities/SnomedUtilities.java 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 4edaebc1f..839648e4d 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 @@ -46,6 +46,7 @@ import org.hl7.fhir.r5.renderers.utils.RenderingContext.GenerationRules; import org.hl7.fhir.r5.renderers.utils.RenderingContext.ResourceRendererMode; import org.hl7.fhir.r5.renderers.utils.ResourceWrapper; import org.hl7.fhir.r5.terminologies.JurisdictionUtilities; +import org.hl7.fhir.r5.terminologies.utilities.SnomedUtilities; import org.hl7.fhir.r5.terminologies.utilities.ValidationResult; import org.hl7.fhir.r5.utils.ToolingExtensions; import org.hl7.fhir.utilities.CommaSeparatedStringBuilder; @@ -1177,8 +1178,8 @@ public class DataRenderer extends Renderer implements CodeResolver { } private String getLinkForSystem(String system, String version) { - if ("http://snomed.info/sct".equals(system)) { - return "https://browser.ihtsdotools.org/"; + if ("http://snomed.info/sct".equals(system)) { + return "https://browser.ihtsdotools.org/"; } else if ("http://loinc.org".equals(system)) { return "https://loinc.org/"; } else if ("http://unitsofmeasure.org".equals(system)) { @@ -1198,11 +1199,7 @@ public class DataRenderer extends Renderer implements CodeResolver { protected String getLinkForCode(String system, String version, String code) { if ("http://snomed.info/sct".equals(system)) { - if (!Utilities.noString(code)) { - return "http://snomed.info/id/"+code; - } else { - return "https://browser.ihtsdotools.org/"; - } + return SnomedUtilities.getSctLink(version, code, context.getContext().getExpansionParameters()); } else if ("http://loinc.org".equals(system)) { if (!Utilities.noString(code)) { return "https://loinc.org/"+code; diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ValueSetRenderer.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ValueSetRenderer.java index 16adae09a..729e5ae42 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ValueSetRenderer.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/renderers/ValueSetRenderer.java @@ -51,6 +51,7 @@ import org.hl7.fhir.r5.terminologies.CodeSystemUtilities; import org.hl7.fhir.r5.terminologies.ValueSetUtilities; import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome; import org.hl7.fhir.r5.terminologies.utilities.CodingValidationRequest; +import org.hl7.fhir.r5.terminologies.utilities.SnomedUtilities; import org.hl7.fhir.r5.terminologies.utilities.ValidationResult; import org.hl7.fhir.r5.utils.EOperationOutcome; import org.hl7.fhir.r5.utils.ToolingExtensions; @@ -825,7 +826,7 @@ public class ValueSetRenderer extends TerminologyRenderer { } String s = Utilities.padLeft("", '\u00A0', i*2); td.attribute("style", "white-space:nowrap").addText(s); - addCodeToTable(c.getAbstract(), c.getSystem(), c.getCode(), c.getDisplay(), td); + addCodeToTable(c.getAbstract(), c.getSystem(), c.getVersion(), c.getCode(), c.getDisplay(), td); td = tr.td(); td.addText(c.getSystem()); td = tr.td(); @@ -863,7 +864,7 @@ public class ValueSetRenderer extends TerminologyRenderer { first = false; XhtmlNode span = td.span(null, mapping.comp.getRelationship().toString()); span.addText(getCharForRelationship(mapping.comp)); - addRefToCode(td, mapping.group.getTarget(), m.getLink(), mapping.comp.getCode()); + addRefToCode(td, mapping.group.getTarget(), null, m.getLink(), mapping.comp.getCode()); if (!Utilities.noString(mapping.comp.getComment())) td.i().tx("("+mapping.comp.getComment()+")"); } @@ -900,13 +901,13 @@ public class ValueSetRenderer extends TerminologyRenderer { return true; } - private void addCodeToTable(boolean isAbstract, String system, String code, String display, XhtmlNode td) { + private void addCodeToTable(boolean isAbstract, String system, String version, String code, String display, XhtmlNode td) { CodeSystem e = getContext().getWorker().fetchCodeSystem(system); if (e == null || (e.getContent() != org.hl7.fhir.r5.model.Enumerations.CodeSystemContentMode.COMPLETE && e.getContent() != org.hl7.fhir.r5.model.Enumerations.CodeSystemContentMode.FRAGMENT)) { if (isAbstract) td.i().setAttribute("title", context.formatPhrase(RenderingContext.VS_ABSTRACT_CODE_HINT)).addText(code); else if ("http://snomed.info/sct".equals(system)) { - td.ah(context.prefixLocalHref(sctLink(code))).addText(code); + td.ah(context.prefixLocalHref(SnomedUtilities.getSctLink(version, code, context.getContext().getExpansionParameters()))).addText(code); } else if ("http://loinc.org".equals(system)) { td.ah(context.prefixLocalHref(LoincLinker.getLinkForCode(code))).addText(code); } else @@ -928,15 +929,8 @@ public class ValueSetRenderer extends TerminologyRenderer { } } - - public String sctLink(String code) { -// if (snomedEdition != null) -// http://browser.ihtsdotools.org/?perspective=full&conceptId1=428041000124106&edition=us-edition&release=v20180301&server=https://prod-browser-exten.ihtsdotools.org/api/snomed&langRefset=900000000000509007 - return "http://snomed.info/id/"+code; - } - - private void addRefToCode(XhtmlNode td, String target, String vslink, String code) { - addCodeToTable(false, target, code, null, td); + private void addRefToCode(XhtmlNode td, String target, String vslink, String code, String version) { + addCodeToTable(false, target, version, code, null, td); // CodeSystem cs = getContext().getWorker().fetchCodeSystem(target); // String cslink = getCsRef(cs); // String link = cslink != null ? cslink+"#"+cs.getId()+"-"+code : vslink+"#"+code; @@ -1212,10 +1206,10 @@ public class ValueSetRenderer extends TerminologyRenderer { } addMapHeaders(addTableHeaderRowStandard(t, false, true, hasDefinition, hasComments, false, false, null, langs, designations, doDesignations), maps); for (ConceptReferenceComponent c : inc.getConcept()) { - renderConcept(inc, langs, doDesignations, maps, designations, definitions, t, hasComments, hasDefinition, c); + renderConcept(inc, langs, doDesignations, maps, designations, definitions, t, hasComments, hasDefinition, c, inc.getVersion()); } for (Base b : VersionComparisonAnnotation.getDeleted(inc, "concept" )) { - renderConcept(inc, langs, doDesignations, maps, designations, definitions, t, hasComments, hasDefinition, (ConceptReferenceComponent) b); + renderConcept(inc, langs, doDesignations, maps, designations, definitions, t, hasComments, hasDefinition, (ConceptReferenceComponent) b, inc.getVersion()); } } if (inc.getFilter().size() > 0) { @@ -1312,11 +1306,11 @@ public class ValueSetRenderer extends TerminologyRenderer { private void renderConcept(ConceptSetComponent inc, List langs, boolean doDesignations, List maps, Map designations, Map definitions, - XhtmlNode t, boolean hasComments, boolean hasDefinition, ConceptReferenceComponent c) { + XhtmlNode t, boolean hasComments, boolean hasDefinition, ConceptReferenceComponent c, String version) { XhtmlNode tr = t.tr(); XhtmlNode td = renderStatusRow(c, t, tr); ConceptDefinitionComponent cc = definitions == null ? null : definitions.get(c.getCode()); - addCodeToTable(false, inc.getSystem(), c.getCode(), c.hasDisplay()? c.getDisplay() : cc != null ? cc.getDisplay() : "", td); + addCodeToTable(false, inc.getSystem(), version, c.getCode(), c.hasDisplay()? c.getDisplay() : cc != null ? cc.getDisplay() : "", td); td = tr.td(); if (!Utilities.noString(c.getDisplay())) @@ -1355,7 +1349,7 @@ public class ValueSetRenderer extends TerminologyRenderer { first = false; XhtmlNode span = td.span(null, mapping.comp.getRelationship().toString()); span.addText(getCharForRelationship(mapping.comp)); - addRefToCode(td, mapping.group.getTarget(), m.getLink(), mapping.comp.getCode()); + addRefToCode(td, mapping.group.getTarget(), m.getLink(), mapping.comp.getCode(), version); if (!Utilities.noString(mapping.comp.getComment())) td.i().tx("("+mapping.comp.getComment()+")"); } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/utilities/SnomedUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/utilities/SnomedUtilities.java new file mode 100644 index 000000000..07f009626 --- /dev/null +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/terminologies/utilities/SnomedUtilities.java @@ -0,0 +1,74 @@ +package org.hl7.fhir.r5.terminologies.utilities; + +import org.hl7.fhir.r5.model.Parameters; +import org.hl7.fhir.r5.model.Parameters.ParametersParameterComponent; +import org.hl7.fhir.utilities.Utilities; + + +//URL: http://snomed.info/sct/[module]/version/[e.g. 20150131]' +//International: 900000000000207008 +//US: 731000124108 +//Australia: 32506021000036107 +//Belgium: 11000172109 +//Canada: 20611000087101 +//Spain: 449081005 +//Denmark: 554471000005108 +//Netherlands: 11000146104 +//Sweden: 45991000052106 +//Switzerland: 2011000195101 +//UK: 83821000000107 +//IPS: 827022005 + +public class SnomedUtilities { + + public static String getVersionFromParameters(Parameters p, String version) { + for (ParametersParameterComponent pp : p.getParameter()) { + switch (pp.getName()) { + case "system-version" : + if (version == null) { + return pp.getValue().primitiveValue(); + } + case "force-system-version": + return pp.getValue().primitiveValue(); + } + } + return version; + } + + public static String getEditionFromVersion(String version) { + if (version == null) { + return null; + } + if (version.startsWith("http://snomed.info/sct/")) { + version = version.substring(23); + } + if (version.contains("/")) { + version = version.substring(0, version.indexOf("/")); + } + if (Utilities.existsInList(version, "900000000000207008", "731000124108", "32506021000036107", "11000172109", "20611000087101", + "449081005", "554471000005108", "11000146104", "45991000052106", "2011000195101", "83821000000107", "827022005")) { + return version; + } else { + return null; + } + } + + public static String getSctLink(String version, String code, Parameters p) { + if (!Utilities.noString(code)) { + version = SnomedUtilities.getVersionFromParameters(p, version); + String edId = SnomedUtilities.getEditionFromVersion(version); + if (edId != null) { + // if there's a version that's an edition, then: + // http://snomed.info/sct/11000172109/id//371305003 + return "http://snomed.info/sct/"+edId+"/id/"+code; + } else { + // no, version: + return "http://snomed.info/id/"+code; + } + } else { + return "https://browser.ihtsdotools.org/"; + } + } +} + +