Skip to content
Permalink
Browse files
Merge commit 'refs/pull/2/head' of https://github.com/apache/freemark…
  • Loading branch information
ddekany committed Oct 9, 2018
2 parents 4bf3262 + 60f6243 commit 22ca18476f8004d4028fe04f9aaa6fb8ea1f897b
Showing 25 changed files with 1,850 additions and 0 deletions.
147 README.md
@@ -28,6 +28,153 @@ Currently it can be invoked as a Maven plug-in, but in the future it might
will be callable on other ways (say, from Gradle, or as a standalone command
line tool).

freemarker-generator-maven-plugin
---------------------------------
## Table of contents

- [Background](#background)
- [Install](#install)
- [Usage](#usage)
- [FreeMarker Template Files](#freemarker-template-files)
- [JSON Generator Files](#json-generator-files)
- [Using POM Properties During Generation](#using-pom-properties-during-generation)
- [FreeMarker Configuration](#freemarker-configuration)
- [Incremental Builds](#incremental-builds)
- [Code Coverage](#code-coverage)
- [Contributing](#contributing)
- [License](#license)

## Background
This plugin generates source files from FreeMarker templates with a flexible process that includes the ability to:

- Generate multiple source files from a single template,
- Generate source files during multiple steps in the build process such as testing, and
- Specify distinct locations for the templates and data models for different stages of the build.

## Install
### pom.xml

Add the following snippet within the `<plugins>` tag of your pom.xml:

```xml
<plugin>
<groupId>com.oath</groupId>
<artifactId>freemarker-maven-plugin</artifactId>
<version>${freemarker-maven-plugin.version}</version>
<configuration>
<!-- Required. Specifies the compatibility version for template processing -->
<freeMarkerVersion>2.3.23</freeMarkerVersion>
</configuration>
<executions>
<!-- If you want to generate files during other phases, just add more execution
tags and specify appropriate phase, sourceDirectory and outputDirectory values.
-->
<execution>
<id>freemarker</id>
<!-- Optional, defaults to generate-sources -->
<phase>generate-sources</phase>
<goals>
<!-- Required, must be generate -->
<goal>generate</goal>
</goals>
<configuration>
<!-- Optional, defaults to src/main/freemarker/generator -->
<sourceDirectory>src/main/freemarker</templateDirectory>
<!-- Optional, defaults to src/main/freemarker/generator/template -->
<templateDirectory>src/main/freemarker/template</templateDirectory>
<!-- Optional, defaults to src/main/freemarker/generator -->
<generatorDirectory>src/main/freemarker/generator/generator</generatorDirectory>
<!-- Optional, defaults to target/generated-sources/freemarker -->
<outputDirectory>target/generated-sources/freemarker/generator</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
```

## Usage

### FreeMarker Template Files
FreeMarker template files must reside in the `templateDirectory`. For the default configuration,
this is: `src/main/freemarker/generator/template`.

By convention, file names for FreeMarker template files use the .ftl extension. For details on the FreeMarker
template syntax, see: [Getting Started](https://freemarker.apache.org/docs/dgui_quickstart.html) and
[Template Language Reference](https://freemarker.apache.org/docs/ref.html).

### JSON Generator Files
The JSON generator files must reside in the `generatorDirectory`. For the default
configuration, this is: `src/main/freemarker/generator/generator`.

For each JSON generator file, freemarker-maven-plugin will generate a file under the outputDirectory.
The name of the generated file will be based on the name of the JSON data file. For example,
the following JSON file:
```
<sourceDirectory>/data/my/package/MyClass.java.json
```
will result in the following file being generated:
```
<outputDirectory>/my/package/MyClass.java
```

This plugin parses the JSON generator file's `dataModel` field into a `Map<String, Object>` instance (hereafter, referred
to as the data model). If the dataModel field is empty, an empty map will be created.

Here are some additional details you need to know.

- This plugin *requires* one top-level field in the JSON data file: `templateName`. This field is used to locate the template file under `<sourceDirectory>/template` that is used to generate the file. This plugin provides the data model to FreeMarker as the data model to process the template identified by `templateName`.
- The parser allows for comments.
- This plugin currently assumes that the JSON data file encoded using UTF-8.

Here is an example JSON data file:
```json
{
// An end-of-line comment.
# Another end-of-line comment
"templateName": "my-template.ftl", #Required
"dataModel": { #Optional
/* A multi-line
comment */
"myString": "a string",
"myNumber": 1,
"myListOfStrings": ["s1", "s2"],
"myListOfNumbers": [1, 2],
"myMap": {
"key1": "value1",
"key2": 2
}
}
}
```

### Using POM Properties During Generation
After parsing the JSON file, the plugin will add
a `pomProperties` entry into the data model, which is a map itself, that contains the properties defined in the pom. Thus, your template can reference the pom property `my_property` using `${pomProperties.my_property}`. If you have a period or dash in the property name, use `${pomProperties["my.property"]}`.



### FreeMarker Configuration

Typically, users of this plugin do not need to mess with the FreeMarker configuration. This plugin explicitly sets two FreeMarker configurations:

1. the default encoding is set to UTF-8
2. the template loader is set to be a FileTemplateLoader that reads from `templateDirectory`.

If you need to override these configs or set your own, you can put them in a
`<sourceDirectory>/freemarker.properties` file. If that file exists, this plugin will read it into a java Properties instance and pass it to freemarker.core.Configurable.setSettings() to establish the FreeMarker configuration. See this [javadoc](https://freemarker.apache.org/docs/api/freemarker/template/Configuration.html#setSetting-java.lang.String-java.lang.String-) for configuration details.


### Incremental Builds
This plugin supports incremental builds; it only generates sources if the generator file, template file, or pom file have timestamps newer than any existing output file. To force a rebuild if these conditions are not met (for example, if you pass in a model parameter on the command line), first run `mvn clean`.

## Code Coverage

By default, the code coverage report is not generated. It is generated by screwdriver jobs. You can generate code coverage on your dev machine with the following maven command:
```bash
mvn clean initialize -Dclover-phase=initialize
```
Bring up the coverage report by pointing your browser to target/site/clover/dashboard.html under the root directory of the local repository.


Licensing
---------
172 pom.xml
@@ -0,0 +1,172 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.apache.freemarker</groupId>
<artifactId>freemarker-generator-maven-plugin</artifactId>
<version>1.0.${build}</version>
<packaging>maven-plugin</packaging>

<name>Freemarker Generator Maven Plugin</name>
<url>http://freemarker.apache.org/</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven-core.version>3.5.2</maven-core.version>
<maven-plugin-api.version>3.5.2</maven-plugin-api.version>
<maven-plugin-annotations.version>3.5</maven-plugin-annotations.version>
<fastutil.version>8.1.0</fastutil.version>
<freemarker.version>2.3.23</freemarker.version>
<gson.version>2.8.2</gson.version>
<jmockit.version>1.32</jmockit.version>
<org.testng.version>6.8</org.testng.version>
<assertj-core.version>3.8.0</assertj-core.version>
<clover-target-percentage>100</clover-target-percentage>
<clover-phase>pre-site</clover-phase>
<target-jdk-version>1.8</target-jdk-version>
</properties>

<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
<version>${maven-core.version}</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
<exclusion>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>${maven-plugin-api.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>${maven-plugin-annotations.version}</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>org.apache.maven</groupId>
<artifactId>maven-artifact</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.eclipse.sisu</groupId>
<artifactId>org.eclipse.sisu.plexus</artifactId>
<version>0.3.3</version>
<exclusions>
<exclusion>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.jmockit</groupId>
<artifactId>jmockit</artifactId>
<version>${jmockit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson.version}</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>${freemarker.version}</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>${org.testng.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj-core.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.5</version>
<configuration>
<goalPrefix>freemarker</goalPrefix>
</configuration>
<executions>
<execution>
<id>default-descriptor</id>
<goals>
<goal>descriptor</goal>
</goals>
<phase>process-classes</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.openclover</groupId>
<artifactId>clover-maven-plugin</artifactId>
<version>4.2.0</version>
<executions>
<execution>
<id>clover</id>
<phase>${clover-phase}</phase>
<goals>
<goal>instrument-test</goal>
<goal>clover</goal>
<goal>check</goal>
</goals>
<configuration>
<targetPercentage>${clover-target-percentage}</targetPercentage>
<generateHtml>true</generateHtml>
<generateXml>true</generateXml>
<jdk>${target-jdk-version}</jdk>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,50 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.apache.freemarker.generator;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

import freemarker.template.Configuration;
import freemarker.template.Version;

/**
* Simple utility class to call various constructors.
* Needed because some jmockit features don't work well with constructors.
*/
public class FactoryUtil {

public static Configuration createConfiguration(String freeMarkerVersion) {
return new Configuration(new Version(freeMarkerVersion));
}

public static File createFile(File parent, String child) {
return new File(parent, child);
}

public static FileInputStream createFileInputStream(File file) throws FileNotFoundException {
return new FileInputStream(file);
}

public static File createFile(String name) {
return new File(name);
}
}

0 comments on commit 22ca184

Please sign in to comment.