I am integrating a FMPP transformation into our Java code base. For this, I am using the FMPP Java API. For practical reasons, I have two separate directories:
- one which contains the template:
<absolute path template>/template.ftlx
- one which contains the data:
<absolute path data>/data.xml
This somehow complicates things, as I have to work with absolute paths here. Typically, the data is inside the template directory (together with a ignoredir.fmpp
file). However, in our application, the data is coming from an external source (it is uploadable via a REST API), while the template is in the classpath. This also means that the data directory isn't static.
I am struggling to define all this and get the transformation happening via the Java API. Currently, I have the following:
Settings s = new Settings(new File("."));
s.set(Settings.NAME_SOURCES, new File("<absolute path template>/template.ftlx").getAbsolutePath());
s.set(Settings.NAME_OUTPUT_FILE, new File("<absolute path output>/output.xml").getAbsolutePath());
s.execute();
The code snippet above is not complete, as I have to add the data. There are the Settings.NAME_DATA
and Settings.NAME_DATA_ROOT
properties, but I can't get it working. I tried setting Settings.NAME_DATA_ROOT
as following:
s.set(Settings.NAME_DATA_ROOT, new File("<absolute path data>").getAbsolutePath());
Then, I get the exception that FreeMarker cannot find my data:
The following has evaluated to null or missing:
==> d [in template "template.ftlx" at line 4, column 12]
In the template, I simply do:
<#list d.items>...</#list>
This makes sense that this would not work, as I did nowhere define that the data should be accessible via the d.
hash (which I am doing below in config.fmpp
). But I don't know how to define that properly via Settings.NAME_DATA
and/or Settings.NAME_DATA_ROOT
.
How can I inject my data file into all this? It should get the key d
, so I can refer to d.
in the template.
reference
Just as reference, if I create the following config.fmpp
file in <absolute path config>
, put the data.xml
data file in directory <absolute path data>
and call s.load(new File("<absolute path config>/config.fmpp"))
before s.execute()
above, everything is working fine.
data: {
d: xml(<absolute path data>/data.xml)
}
All I have to figure out is doing this in a dynamic fashion via the Java API. I cannot use config.fmpp
for this, as the location of the data isn't static (and, as far as I know, config.fmpp
is not parametrizable).
working solution, with doubts
After some code reading, I got it working if I do the following:
Settings s = new Settings(new File("."));
s.set(Settings.NAME_SOURCES, new File("<absolute path template>/template.ftlx").getAbsolutePath());
s.set(Settings.NAME_OUTPUT_FILE, new File("<absolute path output>/output.xml").getAbsolutePath());
s.set(Settings.NAME_DATA, "{d:xml(<absolute path output>/data.xml)}");
s.execute();
Here, we pass {configuration:xml(<absolute path output>/data.xml)}
as a TDD to the NAME_DATA
property. Is this the way to go? It "feels" strange to construct a textual definition in our code. Is there a way to do this in pure Java?