From 93e7e01c66b630d0cf6fe6e794cace43de6397ea Mon Sep 17 00:00:00 2001 From: Ruth Alkema Date: Fri, 2 Mar 2018 14:41:24 +0100 Subject: [PATCH] Allow slotting in own IMessageResolver This is useful in case we want to define our own way of translating the codes in the thymeleaf templates. --- .../BaseThymeleafNarrativeGenerator.java | 13 +++++ ...tThymeleafNarrativeGeneratorDstu3Test.java | 53 +++++++++++++++++++ .../src/test/resources/TestPatient.html | 4 ++ .../test/resources/testnarrative.properties | 2 + 4 files changed, 72 insertions(+) create mode 100644 hapi-fhir-structures-dstu3/src/test/resources/TestPatient.html create mode 100644 hapi-fhir-structures-dstu3/src/test/resources/testnarrative.properties diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/narrative/BaseThymeleafNarrativeGenerator.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/narrative/BaseThymeleafNarrativeGenerator.java index b9769cb99f0..9ab0c192c8e 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/narrative/BaseThymeleafNarrativeGenerator.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/narrative/BaseThymeleafNarrativeGenerator.java @@ -34,6 +34,7 @@ import org.thymeleaf.cache.ICacheEntryValidity; import org.thymeleaf.context.Context; import org.thymeleaf.context.ITemplateContext; import org.thymeleaf.engine.AttributeName; +import org.thymeleaf.messageresolver.IMessageResolver; import org.thymeleaf.model.IProcessableElementTag; import org.thymeleaf.processor.IProcessor; import org.thymeleaf.processor.element.AbstractAttributeTagProcessor; @@ -65,6 +66,8 @@ public abstract class BaseThymeleafNarrativeGenerator implements INarrativeGener private HashMap myNameToNarrativeTemplate; private TemplateEngine myProfileTemplateEngine; + private IMessageResolver resolver; + /** * Constructor */ @@ -166,11 +169,21 @@ public abstract class BaseThymeleafNarrativeGenerator implements INarrativeGener }; myProfileTemplateEngine.setDialect(dialect); + if (this.resolver != null) { + myProfileTemplateEngine.setMessageResolver(this.resolver); + } } myInitialized = true; } + public void setMessageResolver(IMessageResolver resolver) { + this.resolver = resolver; + if (myProfileTemplateEngine != null && resolver != null) { + myProfileTemplateEngine.setMessageResolver(resolver); + } + } + /** * If set to true (which is the default), most whitespace will be trimmed from the generated narrative * before it is returned. diff --git a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/narrative/DefaultThymeleafNarrativeGeneratorDstu3Test.java b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/narrative/DefaultThymeleafNarrativeGeneratorDstu3Test.java index 62b9f81d527..aa427a35a67 100644 --- a/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/narrative/DefaultThymeleafNarrativeGeneratorDstu3Test.java +++ b/hapi-fhir-structures-dstu3/src/test/java/ca/uhn/fhir/narrative/DefaultThymeleafNarrativeGeneratorDstu3Test.java @@ -5,7 +5,12 @@ import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import java.util.Date; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import org.apache.commons.collections.Transformer; +import org.apache.commons.collections.map.LazyMap; import org.hamcrest.core.StringContains; import org.hl7.fhir.dstu3.model.CodeableConcept; import org.hl7.fhir.dstu3.model.Coding; @@ -28,6 +33,8 @@ import org.junit.AfterClass; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; +import org.thymeleaf.messageresolver.StandardMessageResolver; +import org.thymeleaf.templateresource.ITemplateResource; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.parser.DataFormatException; @@ -77,6 +84,52 @@ public class DefaultThymeleafNarrativeGeneratorDstu3Test { } + @Test + public void testTranslations() throws DataFormatException { + CustomThymeleafNarrativeGenerator customGen = new CustomThymeleafNarrativeGenerator("classpath:/testnarrative.properties"); + customGen.setIgnoreFailures(false); + customGen.setIgnoreMissingTemplates(false); + + FhirContext ctx = FhirContext.forDstu3(); + ctx.setNarrativeGenerator(customGen); + + Patient value = new Patient(); + + value.addIdentifier().setSystem("urn:names").setValue("123456"); + value.addName().setFamily("blow").addGiven("joe").addGiven((String) null).addGiven("john"); + //@formatter:off + value.addAddress() + .addLine("123 Fake Street").addLine("Unit 1") + .setCity("Toronto").setState("ON").setCountry("Canada"); + //@formatter:on + + value.setBirthDate(new Date()); + + Transformer transformer = new Transformer() { + + @Override + public Object transform(Object input) { + return "UNTRANSLATED:" + input; + }}; + + Map translations = new HashMap<>(); + translations.put("some_text", "Some beautiful proze"); + + customGen.setMessageResolver(new StandardMessageResolver() { + @Override + protected Map resolveMessagesForTemplate(String template, + ITemplateResource templateResource, Locale locale) { + return LazyMap.decorate(translations, transformer); + } + }); + + Narrative narrative = new Narrative(); + customGen.generateNarrative(ctx, value, narrative); + String output = narrative.getDiv().getValueAsString(); + ourLog.info(output); + assertThat(output, StringContains.containsString("Some beautiful proze")); + assertThat(output, StringContains.containsString("UNTRANSLATED:other_text")); + } @Test public void testGenerateDiagnosticReport() throws DataFormatException { diff --git a/hapi-fhir-structures-dstu3/src/test/resources/TestPatient.html b/hapi-fhir-structures-dstu3/src/test/resources/TestPatient.html new file mode 100644 index 00000000000..88d60488a3e --- /dev/null +++ b/hapi-fhir-structures-dstu3/src/test/resources/TestPatient.html @@ -0,0 +1,4 @@ +
+

Some Text

+

Some Text

+
diff --git a/hapi-fhir-structures-dstu3/src/test/resources/testnarrative.properties b/hapi-fhir-structures-dstu3/src/test/resources/testnarrative.properties new file mode 100644 index 00000000000..22f3b3c51b0 --- /dev/null +++ b/hapi-fhir-structures-dstu3/src/test/resources/testnarrative.properties @@ -0,0 +1,2 @@ +patient.class=org.hl7.fhir.dstu3.model.Patient +patient.narrative=classpath:/TestPatient.html