Fix SCT link to include version and point to the right place

This commit is contained in:
Grahame Grieve 2024-09-23 09:12:01 -04:00
parent f868576840
commit 98373c1fd5
3 changed files with 90 additions and 25 deletions

View File

@ -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.RenderingContext.ResourceRendererMode;
import org.hl7.fhir.r5.renderers.utils.ResourceWrapper; import org.hl7.fhir.r5.renderers.utils.ResourceWrapper;
import org.hl7.fhir.r5.terminologies.JurisdictionUtilities; 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.terminologies.utilities.ValidationResult;
import org.hl7.fhir.r5.utils.ToolingExtensions; import org.hl7.fhir.r5.utils.ToolingExtensions;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder; import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
@ -1198,11 +1199,7 @@ public class DataRenderer extends Renderer implements CodeResolver {
protected String getLinkForCode(String system, String version, String code) { protected String getLinkForCode(String system, String version, String code) {
if ("http://snomed.info/sct".equals(system)) { if ("http://snomed.info/sct".equals(system)) {
if (!Utilities.noString(code)) { return SnomedUtilities.getSctLink(version, code, context.getContext().getExpansionParameters());
return "http://snomed.info/id/"+code;
} else {
return "https://browser.ihtsdotools.org/";
}
} else if ("http://loinc.org".equals(system)) { } else if ("http://loinc.org".equals(system)) {
if (!Utilities.noString(code)) { if (!Utilities.noString(code)) {
return "https://loinc.org/"+code; return "https://loinc.org/"+code;

View File

@ -51,6 +51,7 @@ import org.hl7.fhir.r5.terminologies.CodeSystemUtilities;
import org.hl7.fhir.r5.terminologies.ValueSetUtilities; import org.hl7.fhir.r5.terminologies.ValueSetUtilities;
import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome; import org.hl7.fhir.r5.terminologies.expansion.ValueSetExpansionOutcome;
import org.hl7.fhir.r5.terminologies.utilities.CodingValidationRequest; 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.terminologies.utilities.ValidationResult;
import org.hl7.fhir.r5.utils.EOperationOutcome; import org.hl7.fhir.r5.utils.EOperationOutcome;
import org.hl7.fhir.r5.utils.ToolingExtensions; import org.hl7.fhir.r5.utils.ToolingExtensions;
@ -825,7 +826,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
} }
String s = Utilities.padLeft("", '\u00A0', i*2); String s = Utilities.padLeft("", '\u00A0', i*2);
td.attribute("style", "white-space:nowrap").addText(s); 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 = tr.td();
td.addText(c.getSystem()); td.addText(c.getSystem());
td = tr.td(); td = tr.td();
@ -863,7 +864,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
first = false; first = false;
XhtmlNode span = td.span(null, mapping.comp.getRelationship().toString()); XhtmlNode span = td.span(null, mapping.comp.getRelationship().toString());
span.addText(getCharForRelationship(mapping.comp)); 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())) if (!Utilities.noString(mapping.comp.getComment()))
td.i().tx("("+mapping.comp.getComment()+")"); td.i().tx("("+mapping.comp.getComment()+")");
} }
@ -900,13 +901,13 @@ public class ValueSetRenderer extends TerminologyRenderer {
return true; 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); 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 (e == null || (e.getContent() != org.hl7.fhir.r5.model.Enumerations.CodeSystemContentMode.COMPLETE && e.getContent() != org.hl7.fhir.r5.model.Enumerations.CodeSystemContentMode.FRAGMENT)) {
if (isAbstract) if (isAbstract)
td.i().setAttribute("title", context.formatPhrase(RenderingContext.VS_ABSTRACT_CODE_HINT)).addText(code); td.i().setAttribute("title", context.formatPhrase(RenderingContext.VS_ABSTRACT_CODE_HINT)).addText(code);
else if ("http://snomed.info/sct".equals(system)) { 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)) { } else if ("http://loinc.org".equals(system)) {
td.ah(context.prefixLocalHref(LoincLinker.getLinkForCode(code))).addText(code); td.ah(context.prefixLocalHref(LoincLinker.getLinkForCode(code))).addText(code);
} else } else
@ -928,15 +929,8 @@ public class ValueSetRenderer extends TerminologyRenderer {
} }
} }
private void addRefToCode(XhtmlNode td, String target, String vslink, String code, String version) {
public String sctLink(String code) { addCodeToTable(false, target, version, code, null, td);
// 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);
// CodeSystem cs = getContext().getWorker().fetchCodeSystem(target); // CodeSystem cs = getContext().getWorker().fetchCodeSystem(target);
// String cslink = getCsRef(cs); // String cslink = getCsRef(cs);
// String link = cslink != null ? cslink+"#"+cs.getId()+"-"+code : vslink+"#"+code; // 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); addMapHeaders(addTableHeaderRowStandard(t, false, true, hasDefinition, hasComments, false, false, null, langs, designations, doDesignations), maps);
for (ConceptReferenceComponent c : inc.getConcept()) { 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" )) { 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) { if (inc.getFilter().size() > 0) {
@ -1312,11 +1306,11 @@ public class ValueSetRenderer extends TerminologyRenderer {
private void renderConcept(ConceptSetComponent inc, List<String> langs, boolean doDesignations, private void renderConcept(ConceptSetComponent inc, List<String> langs, boolean doDesignations,
List<UsedConceptMap> maps, Map<String, String> designations, Map<String, ConceptDefinitionComponent> definitions, List<UsedConceptMap> maps, Map<String, String> designations, Map<String, ConceptDefinitionComponent> definitions,
XhtmlNode t, boolean hasComments, boolean hasDefinition, ConceptReferenceComponent c) { XhtmlNode t, boolean hasComments, boolean hasDefinition, ConceptReferenceComponent c, String version) {
XhtmlNode tr = t.tr(); XhtmlNode tr = t.tr();
XhtmlNode td = renderStatusRow(c, t, tr); XhtmlNode td = renderStatusRow(c, t, tr);
ConceptDefinitionComponent cc = definitions == null ? null : definitions.get(c.getCode()); 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(); td = tr.td();
if (!Utilities.noString(c.getDisplay())) if (!Utilities.noString(c.getDisplay()))
@ -1355,7 +1349,7 @@ public class ValueSetRenderer extends TerminologyRenderer {
first = false; first = false;
XhtmlNode span = td.span(null, mapping.comp.getRelationship().toString()); XhtmlNode span = td.span(null, mapping.comp.getRelationship().toString());
span.addText(getCharForRelationship(mapping.comp)); 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())) if (!Utilities.noString(mapping.comp.getComment()))
td.i().tx("("+mapping.comp.getComment()+")"); td.i().tx("("+mapping.comp.getComment()+")");
} }

View File

@ -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/";
}
}
}