Skip to content

Commit

Permalink
Template service accepts template names with no extension
Browse files Browse the repository at this point in the history
  • Loading branch information
robertotru committed Apr 10, 2017
1 parent aed31d8 commit 862a3ed
Show file tree
Hide file tree
Showing 13 changed files with 135 additions and 47 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).

### Changed
- `SchedulerService` has now a more semantic name, i.e. `EmailSchedulerService`. This change breaks backward compatibility.
- Template engines now accept template names with no extension.

### Fixed
- Fixed bug in the email logger due to null collections.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package it.ozimov.springboot.mail.service;

import it.ozimov.springboot.mail.service.exception.TemplateException;
import lombok.NonNull;

import java.io.IOException;
import java.util.Map;
Expand All @@ -43,6 +44,11 @@ String mergeTemplateIntoString(String templateReference, Map<String, Object> mod
throws IOException, TemplateException;


/**
* Return the expected template file extension. The String must not start with '.'.
*
* @return The expected extension of thr accepted template file
*/
String expectedTemplateExtension();

}
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
* <p>
* Main logic for the thread wait-notify mechanism comes from {@see http://stackoverflow.com/a/8980307/1339429 }
*/
@Service("priorityQueueSchedulerService")
@Service("priorityQueueEmailSchedulerService")
@ConditionalOnExpression(SCHEDULER_IS_ENABLED)
@Slf4j
public class PriorityQueueEmailSchedulerService implements EmailSchedulerService {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ public EmailEmbeddedRedis emailEmbeddedRedis() throws IOException {
}

@Bean
public EmailSchedulerProperties schedulerProperties() {
public EmailSchedulerProperties emailSchedulerProperties() {
return EmailSchedulerProperties.builder()
.priorityLevels(1)
.persistence(EmailSchedulerProperties.Persistence.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@ public static class EmailSchedulerServiceDisabledContextBasedTest implements Con
private MimeMessage mimeMessage;

@Autowired(required = false)
private EmailSchedulerService schedulerService;
private EmailSchedulerService emailSchedulerService;

@Test
public void shouldSchedulerServiceNotBeAutowired() throws Exception {
//Assert
assertions.assertThat(schedulerService).isNull();
assertions.assertThat(emailSchedulerService).isNull();
}

}
Expand All @@ -96,7 +96,7 @@ public static class EmailEmailSchedulerPropertiesWithPersistenceContextBasedTest
public final JUnitSoftAssertions assertions = new JUnitSoftAssertions();

@Autowired
private EmailSchedulerProperties schedulerProperties;
private EmailSchedulerProperties emailSchedulerProperties;

@MockBean
private EmailService emailService;
Expand All @@ -105,12 +105,12 @@ public static class EmailEmailSchedulerPropertiesWithPersistenceContextBasedTest
private MimeMessage mimeMessage;

@Autowired
private EmailSchedulerService schedulerService;
private EmailSchedulerService emailSchedulerService;

@Test
public void shouldSchedulerBeAutowired() throws Exception {
//Assert
assertions.assertThat(schedulerService).isNotNull();
assertions.assertThat(emailSchedulerService).isNotNull();
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,18 @@ public class FreemarkerTemplateService implements TemplateService {
public String mergeTemplateIntoString(final @NonNull String templateReference,
final @NonNull Map<String, Object> model)
throws IOException, TemplateException {
checkArgument(!isNullOrEmpty(templateReference.trim()), "The given template is null, empty or blank");
checkArgument(Objects.equals(getFileExtension(templateReference), expectedTemplateExtension()),
"Expected a Freemarker template file with extension 'ftl', while '%s' was given",
getFileExtension(templateReference));
final String trimmedTemplateReference = templateReference.trim();
checkArgument(!isNullOrEmpty(trimmedTemplateReference), "The given template is null, empty or blank");
if (trimmedTemplateReference.contains("."))
checkArgument(Objects.equals(getFileExtension(trimmedTemplateReference), expectedTemplateExtension()),
"Expected a Freemarker template file with extension 'ftl', while '%s' was given",
getFileExtension(trimmedTemplateReference));

try {
final String normalizedTemplateReference = trimmedTemplateReference.endsWith(expectedTemplateExtension()) ?
trimmedTemplateReference : trimmedTemplateReference + '.' + expectedTemplateExtension();
return FreeMarkerTemplateUtils.processTemplateIntoString(
freemarkerConfiguration.getTemplate(templateReference, Charset.forName("UTF-8").name()), model);
freemarkerConfiguration.getTemplate(normalizedTemplateReference, Charset.forName("UTF-8").name()), model);
} catch (Exception e) {
throw new TemplateException(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,7 @@
import java.util.Map;
import java.util.UUID;

import static it.ozimov.cirneco.hamcrest.java7.AssertFluently.given;
import static junit.framework.TestCase.fail;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsInstanceOf.instanceOf;

@RunWith(SpringRunner.class)
Expand All @@ -54,12 +52,30 @@ public class FreemarkerTemplateServiceTest {
public void shouldMergeTemplateIntoString() throws Exception {
//Arrange
final String expectedBody = TemplatingTestUtils.getExpectedBody();
final String templateWithExtension = TemplatingTestUtils.TEMPLATE;
assertions.assertThat(templateWithExtension).endsWith(".ftl");

//Act
final String body = templateService.mergeTemplateIntoString(TemplatingTestUtils.TEMPLATE, TemplatingTestUtils.MODEL_OBJECT);

//Assert
given(body).assertThat(is(expectedBody));
assertions.assertThat(body).isEqualTo(expectedBody);
}

@Test
public void shouldMergeTemplateIntoStringWhenNoDotsIsAvailable() throws Exception {
//Arrange
final String expectedBody = TemplatingTestUtils.getExpectedBody();

final String templateWithNoExtension = TemplatingTestUtils.TEMPLATE.replace(".ftl", "");
assertions.assertThat(templateWithNoExtension).doesNotEndWith(".ftl");

//Act
final String body = templateService.mergeTemplateIntoString(templateWithNoExtension,
TemplatingTestUtils.MODEL_OBJECT);

//Assert
assertions.assertThat(body).isEqualTo(expectedBody);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,18 @@ public class MustacheTemplateService implements TemplateService {
String mergeTemplateIntoString(final @NonNull String templateReference,
final @NonNull Map<String, Object> model)
throws IOException, TemplateException {
checkArgument(!isNullOrEmpty(templateReference.trim()), "The given templateName is null, empty or blank");
checkArgument(Objects.equals(getFileExtension(templateReference), expectedTemplateExtension()),
"Expected a Mustache template file with extension '%s', while '%s' was given. To check " +
"the default extension look at 'spring.mustache.suffix' in your application.properties file",
expectedTemplateExtension(), getFileExtension(templateReference));
final String trimmedTemplateReference = templateReference.trim();
checkArgument(!isNullOrEmpty(trimmedTemplateReference), "The given templateName is null, empty or blank");
if (trimmedTemplateReference.contains("."))
checkArgument(Objects.equals(getFileExtension(trimmedTemplateReference), expectedTemplateExtension()),
"Expected a Mustache template file with extension '%s', while '%s' was given. To check " +
"the default extension look at 'spring.mustache.suffix' in your application.properties file",
expectedTemplateExtension(), getFileExtension(trimmedTemplateReference));


try {
final Reader template = mustacheAutoConfiguration.mustacheTemplateLoader()
.getTemplate(normalizeTemplateReference(templateReference));
.getTemplate(normalizeTemplateReference(trimmedTemplateReference));

return mustacheAutoConfiguration.mustacheCompiler(mustacheAutoConfiguration.mustacheTemplateLoader())
.compile(template)
Expand All @@ -73,8 +75,12 @@ public String expectedTemplateExtension() {
}

private String normalizeTemplateReference(final String templateReference) {
final String expectedSuffix = ("." + mustacheSuffix).replace("..", ".");
return templateReference.substring(0, templateReference.lastIndexOf(expectedSuffix));
if (templateReference.endsWith(mustacheSuffix)) {
final String expectedSuffix = ("." + mustacheSuffix).replace("..", ".");
return templateReference.substring(0, templateReference.lastIndexOf(expectedSuffix));
} else {
return templateReference;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,31 @@ public class MustacheTemplateServiceTest {
public void shouldMergeTemplateIntoString() throws Exception {
//Arrange
final String expectedBody = TemplatingTestUtils.getExpectedBody();
final String templateWithExtension = TemplatingTestUtils.TEMPLATE;
assertions.assertThat(templateWithExtension).endsWith(".html");

//Act
final String body = templateService.mergeTemplateIntoString(TemplatingTestUtils.TEMPLATE, TemplatingTestUtils.MODEL_OBJECT);
final String body = templateService.mergeTemplateIntoString(templateWithExtension, TemplatingTestUtils.MODEL_OBJECT);

//Assert
given(body).assertThat(is(expectedBody));
}

@Test
public void shouldMergeTemplateIntoStringWhenNoDotsIsAvailable() throws Exception {
//Arrange
final String expectedBody = TemplatingTestUtils.getExpectedBody();

final String templateWithNoExtension = TemplatingTestUtils.TEMPLATE.replace(".html", "");
assertions.assertThat(templateWithNoExtension).doesNotEndWith(".html");

//Act
final String body = templateService.mergeTemplateIntoString(templateWithNoExtension, TemplatingTestUtils.MODEL_OBJECT);

//Assert
assertions.assertThat(body).isEqualTo(expectedBody);
}

@Test
public void shouldMergeTemplateIntoStringThrowExceptionOnNullTemplateReference() throws Exception {
//Arrange
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package it.ozimov.springboot.mail.templating.service;

import com.mitchellbosecke.pebble.PebbleEngine;
import com.mitchellbosecke.pebble.spring4.PebbleViewResolver;
import com.mitchellbosecke.pebble.template.PebbleTemplate;
import it.ozimov.springboot.mail.service.TemplateService;
import it.ozimov.springboot.mail.service.exception.TemplateException;
Expand Down Expand Up @@ -51,14 +50,16 @@ public class PebbleTemplateService implements TemplateService {
String mergeTemplateIntoString(final @NonNull String templateReference,
final @NonNull Map<String, Object> model)
throws IOException, TemplateException {
checkArgument(!isNullOrEmpty(templateReference.trim()), "The given templateName is null, empty or blank");
checkArgument(Objects.equals(getFileExtension(templateReference), expectedTemplateExtension()),
"Expected a Pebble template file with extension '%s', while '%s' was given. To check " +
"the default extension look at 'pebble.suffix' in your application.properties file",
expectedTemplateExtension(), getFileExtension(templateReference));
final String trimmedTemplateReference = templateReference.trim();
checkArgument(!isNullOrEmpty(trimmedTemplateReference), "The given templateName is null, empty or blank");
if (trimmedTemplateReference.contains("."))
checkArgument(Objects.equals(getFileExtension(trimmedTemplateReference), expectedTemplateExtension()),
"Expected a Pebble template file with extension '%s', while '%s' was given. To check " +
"the default extension look at 'pebble.suffix' in your application.properties file",
expectedTemplateExtension(), getFileExtension(trimmedTemplateReference));

try {
final PebbleTemplate template = pebbleEngine.getTemplate(normalizeTemplateReference(templateReference));
final PebbleTemplate template = pebbleEngine.getTemplate(normalizeTemplateReference(trimmedTemplateReference));
final Writer writer = new StringWriter();
template.evaluate(writer, model);
return writer.toString();
Expand All @@ -73,8 +74,13 @@ public String expectedTemplateExtension() {
}

private String normalizeTemplateReference(final String templateReference) {
final String expectedSuffix = ("." + pebbleSuffix).replace("..", ".");
return templateReference.substring(0, templateReference.lastIndexOf(expectedSuffix));
if (templateReference.endsWith(pebbleSuffix)) {
final String expectedSuffix = ("." + pebbleSuffix).replace("..", ".");
return templateReference.substring(0, templateReference.lastIndexOf(expectedSuffix));
} else {
return templateReference;
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@
import java.util.Map;
import java.util.UUID;

import static it.ozimov.cirneco.hamcrest.java7.AssertFluently.given;
import static junit.framework.TestCase.fail;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsInstanceOf.instanceOf;

@RunWith(SpringRunner.class)
Expand All @@ -55,13 +53,30 @@ public class PebbleTemplateServiceTest {
public void shouldMergeTemplateIntoString() throws Exception {
//Arrange
final String expectedBody = TemplatingTestUtils.getExpectedBody();
final String templateWithExtension = TemplatingTestUtils.TEMPLATE;
assertions.assertThat(templateWithExtension).endsWith(".html");

//Act
final String body = templateService.mergeTemplateIntoString(TemplatingTestUtils.TEMPLATE,
final String body = templateService.mergeTemplateIntoString(templateWithExtension,
TemplatingTestUtils.MODEL_OBJECT);

//Assert
given(body).assertThat(is(expectedBody));
assertions.assertThat(body).isEqualTo(expectedBody);
}

@Test
public void shouldMergeTemplateIntoStringWhenNoDotsIsAvailable() throws Exception {
//Arrange
final String expectedBody = TemplatingTestUtils.getExpectedBody();

final String templateWithNoExtension = TemplatingTestUtils.TEMPLATE.replace(".html", "");
assertions.assertThat(templateWithNoExtension).doesNotEndWith(".html");

//Act
final String body = templateService.mergeTemplateIntoString(templateWithNoExtension, TemplatingTestUtils.MODEL_OBJECT);

//Assert
assertions.assertThat(body).isEqualTo(expectedBody);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,18 @@ public class ThymeleafTemplateService implements TemplateService {
String mergeTemplateIntoString(final @NonNull String templateReference,
final @NonNull Map<String, Object> model)
throws IOException, TemplateException {
checkArgument(!isNullOrEmpty(templateReference.trim()), "The given template is null, empty or blank");
checkArgument(Objects.equals(getNormalizedFileExtension(templateReference), expectedTemplateExtension()),
"Expected a Thymeleaf template file with extension '%s', while '%s' was given. To check " +
"the default extension look at 'spring.thymeleaf.suffix' in your application.properties file",
expectedTemplateExtension(), getNormalizedFileExtension(templateReference));
final String trimmedTemplateReference = templateReference.trim();
checkArgument(!isNullOrEmpty(trimmedTemplateReference), "The given template is null, empty or blank");
if (trimmedTemplateReference.contains("."))
checkArgument(Objects.equals(getNormalizedFileExtension(trimmedTemplateReference), expectedTemplateExtension()),
"Expected a Thymeleaf template file with extension '%s', while '%s' was given. To check " +
"the default extension look at 'spring.thymeleaf.suffix' in your application.properties file",
expectedTemplateExtension(), getNormalizedFileExtension(trimmedTemplateReference));

final Context context = new Context();
context.setVariables(model);

return thymeleafEngine.process(getNameWithoutExtension(templateReference), context);
return thymeleafEngine.process(getNameWithoutExtension(trimmedTemplateReference), context);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@
import java.util.Map;
import java.util.UUID;

import static it.ozimov.cirneco.hamcrest.java7.AssertFluently.given;
import static junit.framework.TestCase.fail;
import static org.hamcrest.core.Is.is;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = ThymeleafTestApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
Expand All @@ -52,12 +50,29 @@ public class ThymeleafTemplateServiceTest {
public void testMergeTemplateIntoString() throws Exception {
//Arrange
final String expectedBody = TemplatingTestUtils.getExpectedBody();
final String templateWithExtension = TemplatingTestUtils.TEMPLATE;
assertions.assertThat(templateWithExtension).endsWith(".html");

//Act
final String body = templateService.mergeTemplateIntoString(TemplatingTestUtils.TEMPLATE, TemplatingTestUtils.MODEL_OBJECT);
final String body = templateService.mergeTemplateIntoString(templateWithExtension, TemplatingTestUtils.MODEL_OBJECT);

//Assert
given(body).assertThat(is(expectedBody));
assertions.assertThat(body).isEqualTo(expectedBody);
}

@Test
public void shouldMergeTemplateIntoStringWhenNoDotsIsAvailable() throws Exception {
//Arrange
final String expectedBody = TemplatingTestUtils.getExpectedBody();

final String templateWithNoExtension = TemplatingTestUtils.TEMPLATE.replace(".html", "");
assertions.assertThat(templateWithNoExtension).doesNotEndWith(".html");

//Act
final String body = templateService.mergeTemplateIntoString(templateWithNoExtension, TemplatingTestUtils.MODEL_OBJECT);

//Assert
assertions.assertThat(body).isEqualTo(expectedBody);
}

@Test
Expand Down

0 comments on commit 862a3ed

Please sign in to comment.