diff --git a/build.gradle b/build.gradle index 6b9042b8..3fb291e7 100644 --- a/build.gradle +++ b/build.gradle @@ -9,6 +9,7 @@ plugins { group 'com.docutools' version = '1.3.1' +version = '1.4.0-alpha.2' sourceCompatibility = 17 targetCompatibility = 17 @@ -71,6 +72,7 @@ javadoc { } test { + environment 'DT_JT_RR_PLACEHOLDER_MAPPINGS', 'src/test/resources/mappings.txt' useJUnitPlatform() } diff --git a/src/main/java/com/docutools/jocument/PlaceholderMapper.java b/src/main/java/com/docutools/jocument/PlaceholderMapper.java new file mode 100644 index 00000000..43330027 --- /dev/null +++ b/src/main/java/com/docutools/jocument/PlaceholderMapper.java @@ -0,0 +1,5 @@ +package com.docutools.jocument; + +public interface PlaceholderMapper { + String map(String placeholder); +} diff --git a/src/main/java/com/docutools/jocument/impl/PlaceholderMapperImpl.java b/src/main/java/com/docutools/jocument/impl/PlaceholderMapperImpl.java new file mode 100644 index 00000000..319c185e --- /dev/null +++ b/src/main/java/com/docutools/jocument/impl/PlaceholderMapperImpl.java @@ -0,0 +1,48 @@ +package com.docutools.jocument.impl; + +import com.docutools.jocument.PlaceholderMapper; +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class PlaceholderMapperImpl implements PlaceholderMapper { + private static final Logger logger = LogManager.getLogger(); + private static Map placeholderMappings = new HashMap<>(); + + static { + var pathString = System.getenv("DT_JT_RR_PLACEHOLDER_MAPPINGS"); + if (pathString != null) { + var path = Path.of(pathString); + var file = path.toFile(); + if (file.exists() && file.canRead()) { + try { + var reader = new BufferedReader(new FileReader(file)); + placeholderMappings = reader.lines() + .filter(line -> !line.isEmpty()) + .filter(line -> !line.startsWith("//")) + .map(line -> line.split(":")) + .collect(Collectors.toMap(strings -> strings[0], strings -> strings[1])); + } catch (IOException e) { + logger.error(e); + } + } else if (!file.exists()) { + logger.error("Mappings file {} does not exist", pathString); + } else if (!file.canRead()) { + logger.error("Mappings file {} can not be read", pathString); + } + } else { + logger.info("No mapper found"); + } + } + + @Override + public String map(String placeholder) { + return placeholderMappings.getOrDefault(placeholder, placeholder); + } +} diff --git a/src/main/java/com/docutools/jocument/impl/ReflectionResolver.java b/src/main/java/com/docutools/jocument/impl/ReflectionResolver.java index bbf7412c..e6561a1f 100644 --- a/src/main/java/com/docutools/jocument/impl/ReflectionResolver.java +++ b/src/main/java/com/docutools/jocument/impl/ReflectionResolver.java @@ -2,6 +2,7 @@ import com.docutools.jocument.CustomPlaceholderRegistry; import com.docutools.jocument.PlaceholderData; +import com.docutools.jocument.PlaceholderMapper; import com.docutools.jocument.PlaceholderResolver; import com.docutools.jocument.annotations.Format; import com.docutools.jocument.annotations.Image; @@ -41,6 +42,7 @@ * @since 2020-02-19 */ public class ReflectionResolver extends PlaceholderResolver { + private final PlaceholderMapper placeholderMapper = new PlaceholderMapperImpl(); private static final String SELF_REFERENCE = "this"; @@ -125,6 +127,7 @@ private static DateTimeFormatter toDateTimeFormatter(Format format) { @Override public Optional resolve(String placeholderName, Locale locale) { logger.debug("Trying to resolve placeholder {}", placeholderName); + placeholderName = placeholderMapper.map(placeholderName); Optional result = Optional.empty(); for (String property : placeholderName.split("\\.")) { result = result.isEmpty() diff --git a/src/test/java/com/docutools/jocument/impl/word/WordGeneratorTest.java b/src/test/java/com/docutools/jocument/impl/word/WordGeneratorTest.java index 74715893..1923a8b9 100644 --- a/src/test/java/com/docutools/jocument/impl/word/WordGeneratorTest.java +++ b/src/test/java/com/docutools/jocument/impl/word/WordGeneratorTest.java @@ -191,4 +191,35 @@ void shouldApplyForeignCustomWordPlaceholder() throws InterruptedException, IOEx assertThat(documentWrapper.bodyElement(0).asParagraph().run(0).text(), equalTo("Live your life not celebrating victories, but overcoming defeats.")); } + + + @Test + @DisplayName("Resolve legacy placeholder") + void shouldResolveLegacy() throws IOException, InterruptedException { + // Assemble + Template template = Template.fromClassPath("/templates/word/LegacyCollectionsTemplate.docx") + .orElseThrow(); + PlaceholderResolver resolver = new ReflectionResolver(SampleModelData.PICARD); + + // Act + Document document = template.startGeneration(resolver); + document.blockUntilCompletion(60000L); // 1 minute + + // Assert + assertThat(document.completed(), is(true)); + xwpfDocument = TestUtils.getXWPFDocumentFromDocument(document); + var documentWrapper = new XWPFDocumentWrapper(xwpfDocument); + assertThat(documentWrapper.bodyElement(0).asParagraph().text(), equalTo("Captain: Jean-Luc Picard")); + assertThat(documentWrapper.bodyElement(2).asParagraph().text(), equalTo("First Officer")); + assertThat(documentWrapper.bodyElement(3).asTable().row(0).cell(0).bodyElement(0).asParagraph().text(), equalTo("Name")); + assertThat(documentWrapper.bodyElement(3).asTable().row(0).cell(1).bodyElement(0).asParagraph().text(), equalTo("Rank")); + assertThat(documentWrapper.bodyElement(3).asTable().row(0).cell(2).bodyElement(0).asParagraph().text(), equalTo("Uniform")); + assertThat(documentWrapper.bodyElement(3).asTable().row(1).cell(0).bodyElement(0).asParagraph().text(), equalTo("Riker")); + assertThat(documentWrapper.bodyElement(3).asTable().row(1).cell(1).bodyElement(0).asParagraph().text(), equalTo("3")); + assertThat(documentWrapper.bodyElement(3).asTable().row(1).cell(2).bodyElement(0).asParagraph().text(), equalTo("Red")); + assertThat(documentWrapper.bodyElement(6).asParagraph().text(), equalTo("Services")); + assertThat(documentWrapper.bodyElement(8).asParagraph().text(), equalTo("USS Enterprise")); + assertThat(documentWrapper.bodyElement(9).asParagraph().text(), equalTo("US Defiant")); + assertThat(documentWrapper.bodyElement(11).asParagraph().text(), equalTo("And that’s that.")); + } } \ No newline at end of file diff --git a/src/test/resources/log4j2.xml b/src/test/resources/log4j2.xml index f40400e4..14fae016 100644 --- a/src/test/resources/log4j2.xml +++ b/src/test/resources/log4j2.xml @@ -6,7 +6,7 @@ - + diff --git a/src/test/resources/mappings.txt b/src/test/resources/mappings.txt new file mode 100644 index 00000000..6162fc62 --- /dev/null +++ b/src/test/resources/mappings.txt @@ -0,0 +1,5 @@ +captain-name:name +officer-name:name +officer-rank:rank +officer-uniform:uniform +service-ship-name:shipName \ No newline at end of file diff --git a/src/test/resources/templates/word/LegacyCollectionsTemplate.docx b/src/test/resources/templates/word/LegacyCollectionsTemplate.docx new file mode 100644 index 00000000..b79ddfb4 Binary files /dev/null and b/src/test/resources/templates/word/LegacyCollectionsTemplate.docx differ