view content/Maven/gmaven-string-template-engine.md @ 112:cf31bf5fce72 default tip

Author of the blog post as mail header for efficient spam filtering
author Dirk Olmes <dirk.olmes@codedo.de>
date Tue, 06 Sep 2022 07:04:11 +0200
parents ee048ed76ea1
children
line wrap: on
line source

Title: Quick templating with gmaven and GStringTemplateEngine
Date: 2021-06-16
Lang: en

At work I have come across the requirement to generate some files based on the info in a `pom.xml`. Maven's [resource filtering](https://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html) feature would be the first thing that comes to mind but unfortunately it's not powerful enough for my use case. I had to generate a file based on the dependencies that are referenced in the project.

A bit of googling found all kinds of outdated or unsupported maven plugins but nothing that would fit my use case directly. Finally I gave up and started to hack something together in groovy.

As it turns out groovy comes with a templating engine built in: `groovy.text.GStringTemplateEngine`. Using it is fairly straightforward from Maven:

    :::xml
    ....
    <plugin>
        <groupId>org.codehaus.gmaven</groupId>
        <artifactId>groovy-maven-plugin</artifactId>
        <version>2.1.1</version>
        <executions>
            <execution>
                <phase>generate-resources</phase>
                <goals>
                    <goal>execute</goal>
                </goals>
                <configuration>
                    <source>${project.basedir}/templateGenerator.groovy</source>
                </configuration>
            </execution>
        </executions>
    </plugin>

The `templateGenerator.groovy` Script is only a few lines long:

    :::java
    import java.io.File
    import groovy.text.GStringTemplateEngine

    def templateFile = "${project.basedir}/template.file" as File
    def outputFile = "${project.build.directory}/dependencies.html" as File
    outputFile.newWriter("UTF-8").withCloseable { writer ->
        def engine = new GStringTemplateEngine()
        def replacements = [ dependencies: project.dependencies ]
        engine.createTemplate(templateFile).make(replacements).writeTo(writer)
    }

The template file can contain any syntax that the [GStringTemplate](https://docs.groovy-lang.org/latest/html/api/groovy/text/GStringTemplateEngine.html) supports.

IMHO this approach supports the best of both worlds: with only a little groovy scripting magic you get the maximum flexibility of a templating engine that has access to all the internals of your project.