From 75a9d13050fd4750fcb823446e3e0a5501d97d1a Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Mon, 20 May 2024 05:17:03 -0500 Subject: [PATCH] Add importing translations to native resources --- .../fhir/r5/elementmodel/LanguageUtils.java | 66 +++++++++++++++++-- .../hl7/fhir/r5/utils/ToolingExtensions.java | 20 ++++++ 2 files changed, 81 insertions(+), 5 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/LanguageUtils.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/LanguageUtils.java index 3a926422a..928d5a726 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/LanguageUtils.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/elementmodel/LanguageUtils.java @@ -21,6 +21,7 @@ import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionBindingAdditiona import org.hl7.fhir.r5.model.ElementDefinition.ElementDefinitionConstraintComponent; import org.hl7.fhir.r5.model.Extension; import org.hl7.fhir.r5.model.MarkdownType; +import org.hl7.fhir.r5.model.Property; import org.hl7.fhir.r5.model.Resource; import org.hl7.fhir.r5.model.StringType; import org.hl7.fhir.r5.model.StructureDefinition; @@ -128,13 +129,17 @@ public class LanguageUtils { } private String pathForElement(Element element) { + String bp = element.getBasePath(); + return pathForElement(bp, element.getProperty().getStructure().getType()); + } + + private String pathForElement(String path, String type) { // special case support for metadata elements prior to R5: if (crlist == null) { crlist = new ContextUtilities(context).getCanonicalResourceNames(); } - String bp = element.getBasePath(); - if (crlist.contains(element.getProperty().getStructure().getType())) { - String fp = bp.replace(element.getProperty().getStructure().getType()+".", "CanonicalResource."); + if (crlist.contains(type)) { + String fp = path.replace(type+".", "CanonicalResource."); if (Utilities.existsInList(fp, "CanonicalResource.url", "CanonicalResource.identifier", "CanonicalResource.version", "CanonicalResource.name", "CanonicalResource.title", "CanonicalResource.status", "CanonicalResource.experimental", "CanonicalResource.date", @@ -143,7 +148,7 @@ public class LanguageUtils { return fp; } } - return bp; + return path; } @@ -167,6 +172,22 @@ public class LanguageUtils { return r; } + public int importFromTranslations(Resource resource, List translations, List messages) { + Set usedUnits = new HashSet<>(); + int r = 0; + if (resource.fhirType().equals("StructureDefinition")) { + // todo... r = importFromTranslationsForSD(null, resource, translations, usedUnits); + } else { + r = importResourceFromTranslations(null, resource, translations, usedUnits, resource.fhirType()); + } + for (TranslationUnit t : translations) { + if (!usedUnits.contains(t)) { + messages.add(new ValidationMessage(Source.Publisher, IssueType.INFORMATIONAL, t.getId(), "Unused '"+t.getLanguage()+"' translation '"+t.getSrcText()+"' -> '"+t.getTgtText()+"'", IssueSeverity.INFORMATION)); + } + } + return r; + } + /* * */ @@ -224,6 +245,41 @@ public class LanguageUtils { return r; } + private int importResourceFromTranslations(Base parent, Base element, List translations, Set usedUnits, String path) { + int t = 0; + if (element.isPrimitive() && isTranslatable(element, path) && element instanceof org.hl7.fhir.r5.model.Element) { + org.hl7.fhir.r5.model.Element e = (org.hl7.fhir.r5.model.Element) element; + String base = element.primitiveValue(); + if (base != null) { + String epath = pathForElement(path, element.fhirType()); + Set tlist = findTranslations(epath, base, translations); + for (TranslationUnit translation : tlist) { + t++; + if (!handleAsSpecial(parent, element, translation)) { + ToolingExtensions.setLanguageTranslation(e, translation.getLanguage(), translation.getTgtText()); + usedUnits.add(translation); + } + } + } + } + for (Property c : element.children()) { + for (Base v : c.getValues()) { + if (!c.getName().equals("designation")) { + t = t + importResourceFromTranslations(element, v, translations, usedUnits, path+"."+c.getName()); + } + } + } + return t; + } + + private boolean handleAsSpecial(Base parent, Base element, TranslationUnit translation) { + return false; + } + + private boolean isTranslatable(Base element, String path) { + return Utilities.existsInList(element.fhirType(), "string", "markdown"); + } + private int importFromTranslations(Element parent, Element element, List translations, Set usedUnits) { int t = 0; if (element.isPrimitive() && isTranslatable(element)) { @@ -239,7 +295,7 @@ public class LanguageUtils { } } } - for (Element c: element.getChildren()) { + for (Element c : element.getChildren()) { if (!c.getName().equals("designation")) { t = t + importFromTranslations(element, c, translations, usedUnits); } diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ToolingExtensions.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ToolingExtensions.java index 0231aee97..0c4b3eca2 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ToolingExtensions.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/utils/ToolingExtensions.java @@ -845,6 +845,26 @@ public class ToolingExtensions { element.getExtension().add(extension); } + public static void setLanguageTranslation(Element element, String lang, String value) { + if (Utilities.noString(lang) || Utilities.noString(value)) + return; + + for (Extension extension : element.getExtension()) { + if (EXT_TRANSLATION.equals(extension.getUrl())) { + String l = extension.getExtensionString("lang"); + if (lang.equals(l)) { + setStringExtension(extension, "content", value); + return; + } + } + } + + Extension extension = new Extension().setUrl(EXT_TRANSLATION); + extension.addExtension().setUrl("lang").setValue(new CodeType(lang)); + extension.addExtension().setUrl("content").setValue(new StringType(value)); + element.getExtension().add(extension); + } + public static boolean hasAllowedUnits(ElementDefinition eld) { for (Extension e : eld.getExtension()) if (e.getUrl().equals(EXT_ALLOWABLE_UNITS))