Apache FreeMarker CLI Tools
Overview
The implementation of the Apache FreeMarker CLI Tools was inspired by Apache Velocity Tools - a tool is just a POJO (plain old Java object) that is “useful” in a template and is not meant to be rendered in the output.
Let’s have a look at the anatomy and life-cycle of a Apache FreeMarker CLI Tool
- The meta-data, e.g. class name, is read from freemarker-cli.properties
- It provides a default constructor
- Its toString methods prints a short description
- It exposes public methods being used directly by the template
- It is instantiated once and is multi-thread-safe
Available Tools
The following tools are currently implemented
Tool | Description |
---|---|
CSVTool | Process CSV files using Apache Commons CSV |
DataFrameTool | Bridge to nRo/DataFrame |
ExecTool | Execute command line tools using Apache Commons Exec |
ExcelTool | Process Excels files (XLS, XLSX) using Apache POI |
FreeMarkerTool | Expose useful FreeMarker classes |
GrokTool | Process text files using Grok instead of regular expressions |
GsonTool | Process JSON files using GSON |
JsonPathTool | Process JSON file using Java JSON Path |
JsoupTool | Processing HTML files using Jsoup |
PropertiesTool | Process JDK properties files |
SystemTool | System-related utility methods |
UUIDTool | Create UUIDs |
XmlTool | Process XML files using Apache FreeMarker |
YamlTool | Process YAML files using SnakeYAML |
Advanced Topics
Auto-closing Resources
The user can create objects which need to be closed later on to avoid excessive resource usage. This is less of a concern for a short-lived CLI application but if many data sources are processed or the code is used in a different context the problem becomes more severe.
The Excel Tool provides the following code to keep track of Closables
package org.apache.freemarker.generator.tools.excel; public class ExcelTool { public Workbook parse(DataSource dataSource) { try (InputStream is = dataSource.getUnsafeInputStream()) { final Workbook workbook = WorkbookFactory.create(is); // make sure that the workbook is closed together with the data source return dataSource.addClosable(workbook); } catch (IOException e) { throw new RuntimeException("Failed to parse Excel data source: " + dataSource, e); } } }
So what is happening here
- The Workbook is tracked by the originating DataSource
- The DataSource implements the Closable interface
- All DataSources are closed automatically when rendering is done.