Skip to content

Commit

Permalink
First implementation of templates (#193)
Browse files Browse the repository at this point in the history
* APP-3008: implemented Template API and added a freemarker specific implementation
  • Loading branch information
symphony-elias authored Sep 4, 2020
1 parent cbe02e8 commit 77e4c97
Show file tree
Hide file tree
Showing 21 changed files with 674 additions and 0 deletions.
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@
<module>symphony-bdk-core-invokers</module>
<module>symphony-bdk-examples</module>
<module>symphony-bdk-spring</module>
<module>symphony-bdk-template</module>
</modules>
</profile>

Expand Down
10 changes: 10 additions & 0 deletions symphony-bdk-bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,16 @@
<artifactId>symphony-bdk-core-spring-boot-starter</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.symphony.platformsolutions</groupId>
<artifactId>symphony-bdk-template-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.symphony.platformsolutions</groupId>
<artifactId>symphony-bdk-template-freemarker</artifactId>
<version>${project.version}</version>
</dependency>

<!-- API Guardian -->
<dependency>
Expand Down
49 changes: 49 additions & 0 deletions symphony-bdk-examples/bdk-template-examples/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<artifactId>symphony-bdk-examples</artifactId>
<groupId>com.symphony.platformsolutions</groupId>
<version>1.2.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>symphony-bdk-template-examples</artifactId>
<name>Symphony Java BDK Examples - Template</name>
<description>Symphony Java BDK Examples for the Template module</description>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.symphony.platformsolutions</groupId>
<artifactId>symphony-bdk-bom</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>com.symphony.platformsolutions</groupId>
<artifactId>symphony-bdk-template-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>

</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.symphony.template.examples;

import com.symphony.bdk.template.api.Template;
import com.symphony.bdk.template.api.TemplateEngine;
import com.symphony.bdk.template.api.TemplateException;

import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;

/**
* Sample class showing usage of FreeMarker templates.
*/
@Slf4j
public class FreeMarkerExample {
public static void main(String[] args) throws TemplateException {
log.info("String generated from built-in template: {}", getStringFromBuiltInTemplate());
log.info("String generated from custom template: {}", getStringFromCustomTemplate());
}

private static String getStringFromBuiltInTemplate() throws TemplateException {
Template template = TemplateEngine.getDefaultImplementation().newBuiltInTemplate("simpleMML");
final String message = template.process(new HashMap<String, String>() {{
put("message", "Hello World !");
}});
return message;
}

private static String getStringFromCustomTemplate() throws TemplateException {
Template template = TemplateEngine.getDefaultImplementation()
.newTemplateFromClasspath("templates/customTemplate.ftl");
final String message = template.process(new HashMap<String, String>() {{
put("message", "Hello World");
}});
return message;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
${message} from custom template !
1 change: 1 addition & 0 deletions symphony-bdk-examples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<modules>
<module>bdk-core-examples</module>
<module>bdk-spring-boot-example</module>
<module>bdk-template-examples</module>
</modules>

</project>
22 changes: 22 additions & 0 deletions symphony-bdk-template/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>

<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>
<parent>
<artifactId>symphony-api-client-java-parent</artifactId>
<groupId>com.symphony.platformsolutions</groupId>
<version>1.2.0-SNAPSHOT</version>
</parent>

<artifactId>symphony-bdk-template</artifactId>
<name>Symphony Java BDK Template</name>
<description>Symphony Java BDK Template Module</description>
<packaging>pom</packaging>

<modules>
<module>symphony-bdk-template-api</module>
<module>symphony-bdk-template-freemarker</module>
</modules>

</project>
45 changes: 45 additions & 0 deletions symphony-bdk-template/symphony-bdk-template-api/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<artifactId>symphony-bdk-template</artifactId>
<groupId>com.symphony.platformsolutions</groupId>
<version>1.2.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>symphony-bdk-template-api</artifactId>
<name>Symphony Java BDK Template API</name>
<description>Symphony Java BDK Template API module</description>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.symphony.platformsolutions</groupId>
<artifactId>symphony-bdk-bom</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>org.apiguardian</groupId>
<artifactId>apiguardian-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>


</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.symphony.bdk.template.api;

import org.apiguardian.api.API;

/**
* Interface to represent a template.
* A template takes parameters in input and outputs a string.
*/
@API(status = API.Status.STABLE)
public interface Template {

/**
* Produces the string from this template using the given parameters passed in input.
* @param parameters the object which contains the parameters to be used by the template.
* The actual type depends on the concrete implementation.
* Checking the actual type passed in parameter will be the responsibility of each concrete implementation.
* @return the generated string where each parameter is replaced by its value provided in the map
* @throws TemplateException in case of issues during the string generation, e.g. missing parameter
*/
String process(Object parameters) throws TemplateException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.symphony.bdk.template.api;

import org.apiguardian.api.API;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

/**
* Interface to represent a specific template engine backed by a specific technology.
* It creates {@link Template} instances based on a file provided in the file system, in the classpath or as a URL
*/
@API(status = API.Status.STABLE)
public interface TemplateEngine {

/**
* Returns the names of built-in templates which can be retrieved by calling {@link #newBuiltInTemplate(String)}
* @return the names of available built-in templates
*/
Set<String> getBuiltInTemplates();

/**
* Creates a new {@link Template} from the built-in template name.
* @param template the name of one of the built-in templates returned by {@link #getBuiltInTemplates()}
* @return a new {@link Template} instantiated from the provided template name
* @throws TemplateException if template not found
*/
Template newBuiltInTemplate(String template) throws TemplateException;

/**
* Create a {@link Template} instance from a file on the file system
* @param templatePath path to a template file on the file system
* @return a new {@link Template} instantiated from the provided file
* @throws TemplateException when template cannot be loaded, e.g. file not accessible
*/
Template newTemplateFromFile(String templatePath) throws TemplateException;

/**
* Create a {@link Template} instance from a file in the classpath
* @param templatePath full path to a template file in the classpath
* @returna a new {@link Template} instantiated from the provided classpath resource
* @throws TemplateException when template cannot be loaded, e.g. resource not accessible
*/
Template newTemplateFromClasspath(String templatePath) throws TemplateException;

/**
* Creates a template from a URL to a template file
* @param url the url where to fetch the template file
* @return a new {@link Template} instantiated from the provided url, should be a valid {@link java.net.URL} string.
* @throws TemplateException when template cannot be loaded, e.g. url not accessible
*/
Template newTemplateFromUrl(String url) throws TemplateException;

static TemplateEngine getDefaultImplementation() {
final ServiceLoader<TemplateEngine> engineServiceLoader = ServiceLoader.load(TemplateEngine.class);

final List<TemplateEngine> templateEngines = StreamSupport.stream(engineServiceLoader.spliterator(), false)
.collect(Collectors.toList());

if (templateEngines.isEmpty()) {
throw new IllegalStateException("No TemplateEngine implementation found in classpath.");
} else if (templateEngines.size() > 1) {
LoggerFactory.getLogger(TemplateEngine.class)
.warn("More than 1 TemplateEngine implementation found in classpath, will use : {}",
templateEngines.stream().findFirst().get());
}
return templateEngines.stream().findFirst().get();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.symphony.bdk.template.api;

import org.apiguardian.api.API;


/**
* Exception thrown when instantiating a {@link Template} through {@link TemplateEngine}
* or when calling {@link Template#process(Object)}.
* This can be triggered when template cannot be loaded,
* if template is malformed or if some parameters are missing when calling {@link Template#process(Object)}
*/
@API(status = API.Status.STABLE)
public class TemplateException extends Exception {
public TemplateException(String message, Throwable cause) {
super(message, cause);
}
}
53 changes: 53 additions & 0 deletions symphony-bdk-template/symphony-bdk-template-freemarker/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<artifactId>symphony-bdk-template</artifactId>
<groupId>com.symphony.platformsolutions</groupId>
<version>1.2.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>symphony-bdk-template-freemarker</artifactId>
<name>Symphony Java BDK Template Freemarker</name>
<description>Symphony Java BDK Template Freemarker Module</description>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.symphony.platformsolutions</groupId>
<artifactId>symphony-bdk-bom</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.30</version>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.12</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
<groupId>com.symphony.platformsolutions</groupId>
<artifactId>symphony-bdk-template-api</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Loading

0 comments on commit 77e4c97

Please sign in to comment.