Skip to content

Commit

Permalink
Use beans in email builders
Browse files Browse the repository at this point in the history
  • Loading branch information
ttoino committed Mar 23, 2023
1 parent ef0fc4e commit 744c69c
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 52 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package pt.up.fe.ni.website.backend.config.email

import com.samskivert.mustache.Mustache
import org.commonmark.ext.front.matter.YamlFrontMatterExtension
import org.commonmark.parser.Parser
import org.commonmark.renderer.html.HtmlRenderer
import org.commonmark.renderer.text.TextContentRenderer
import org.springframework.boot.autoconfigure.mustache.MustacheResourceTemplateLoader
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration
class EmailConfig(
private val emailConfigProperties: EmailConfigProperties
) {
@Bean
fun mustacheCompiler() = Mustache.compiler().withLoader(
MustacheResourceTemplateLoader(emailConfigProperties.templatePrefix, emailConfigProperties.templateSuffix)
)

@Bean
fun commonmarkParser() = Parser.builder().extensions(
listOf(
YamlFrontMatterExtension.create()
)
).build()

@Bean
fun commonmarkHtmlRenderer() = HtmlRenderer.builder().build()

@Bean
fun commonmarkTextRenderer() = TextContentRenderer.builder().build()
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ package pt.up.fe.ni.website.backend.email
import jakarta.validation.Valid
import jakarta.validation.constraints.Email
import org.springframework.mail.javamail.MimeMessageHelper
import pt.up.fe.ni.website.backend.config.ApplicationContextUtils
import pt.up.fe.ni.website.backend.config.email.EmailConfigProperties
import pt.up.fe.ni.website.backend.model.Account

abstract class BaseEmailBuilder : EmailBuilder {
protected val emailConfigProperties = ApplicationContextUtils.getBean(EmailConfigProperties::class.java)

private var from: String? = null
private var fromPersonal: String? = null
private var to: MutableSet<String> = mutableSetOf()
Expand Down Expand Up @@ -42,7 +45,7 @@ abstract class BaseEmailBuilder : EmailBuilder {
bcc.addAll(users.map { it.email })
}

override fun build(helper: MimeMessageHelper, emailConfigProperties: EmailConfigProperties) {
override fun build(helper: MimeMessageHelper) {
helper.setFrom(from ?: emailConfigProperties.from, fromPersonal ?: emailConfigProperties.fromPersonal)

to.forEach(helper::setTo)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package pt.up.fe.ni.website.backend.email

import org.springframework.mail.javamail.MimeMessageHelper
import pt.up.fe.ni.website.backend.config.email.EmailConfigProperties

interface EmailBuilder {
fun build(helper: MimeMessageHelper, emailConfigProperties: EmailConfigProperties)
fun build(helper: MimeMessageHelper)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import jakarta.activation.URLDataSource
import java.io.File
import java.net.URL
import org.springframework.mail.javamail.MimeMessageHelper
import pt.up.fe.ni.website.backend.config.email.EmailConfigProperties

class SimpleEmailBuilder : BaseEmailBuilder() {
private var text: String? = null
Expand Down Expand Up @@ -51,20 +50,16 @@ class SimpleEmailBuilder : BaseEmailBuilder() {
inlines.add(EmailFile(name, URLDataSource(URL(path))))
}

override fun build(helper: MimeMessageHelper, emailConfigProperties: EmailConfigProperties) {
super.build(helper, emailConfigProperties)
override fun build(helper: MimeMessageHelper) {
super.build(helper)

if (text != null && html != null) {
helper.setText(text!!, html!!)
} else if (text != null) {
helper.setText(text!!)
} else if (html != null) {
helper.setText(html!!, true)
when {
text != null && html != null -> helper.setText(text!!, html!!)
html != null -> helper.setText(html!!, true)
text != null -> helper.setText(text!!)
}

if (subject != null) {
helper.setSubject(subject!!)
}
subject?.let { helper.setSubject(it) }

attachments.forEach { helper.addAttachment(it.name, it.content) }
inlines.forEach { helper.addInline(it.name, it.content) }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,43 +1,34 @@
package pt.up.fe.ni.website.backend.email

import com.samskivert.mustache.Mustache
import org.commonmark.ext.front.matter.YamlFrontMatterExtension
import org.commonmark.ext.front.matter.YamlFrontMatterVisitor
import org.commonmark.parser.Parser
import org.commonmark.renderer.html.HtmlRenderer
import org.commonmark.renderer.text.TextContentRenderer
import org.springframework.boot.autoconfigure.mustache.MustacheResourceTemplateLoader
import org.springframework.core.io.Resource
import org.springframework.core.io.UrlResource
import org.springframework.mail.javamail.MimeMessageHelper
import org.springframework.util.ResourceUtils
import pt.up.fe.ni.website.backend.config.email.EmailConfigProperties
import pt.up.fe.ni.website.backend.config.ApplicationContextUtils

abstract class TemplateEmailBuilder<T>(
private val template: String
) : BaseEmailBuilder() {
private companion object {
val commonmarkParser: Parser = Parser.builder().extensions(
listOf(
YamlFrontMatterExtension.create()
)
).build()
val commonmarkHtmlRenderer: HtmlRenderer = HtmlRenderer.builder().build()
val commonmarkTextRenderer: TextContentRenderer = TextContentRenderer.builder().build()
}
private val commonmarkParser = ApplicationContextUtils.getBean(Parser::class.java)
private val commonmarkHtmlRenderer = ApplicationContextUtils.getBean(HtmlRenderer::class.java)
private val commonmarkTextRenderer = ApplicationContextUtils.getBean(TextContentRenderer::class.java)
private val mustache = ApplicationContextUtils.getBean(Mustache.Compiler::class.java)

private var data: T? = null

fun data(data: T) = apply {
this.data = data
}

override fun build(helper: MimeMessageHelper, emailConfigProperties: EmailConfigProperties) {
super.build(helper, emailConfigProperties)
override fun build(helper: MimeMessageHelper) {
super.build(helper)

val mustache = Mustache.compiler().withLoader(
MustacheResourceTemplateLoader(emailConfigProperties.templatePrefix, emailConfigProperties.templateSuffix)
)
if (data == null) return

val markdown = mustache.loadTemplate(template).execute(data)

Expand All @@ -49,12 +40,7 @@ abstract class TemplateEmailBuilder<T>(
doc.accept(yamlVisitor)

val subject = yamlVisitor.data["subject"]?.firstOrNull()
if (subject != null) {
helper.setSubject(subject)
}

yamlVisitor.data.getOrDefault("attachments", emptyList()).forEach { addFile(helper::addAttachment, it) }
yamlVisitor.data.getOrDefault("inline", emptyList()).forEach { addFile(helper::addInline, it) }
subject?.let { helper.setSubject(it) }

val styles = yamlVisitor.data.getOrDefault("styles", mutableListOf()).apply {
if (yamlVisitor.data["no_default_style"].isNullOrEmpty()) {
Expand All @@ -74,22 +60,19 @@ abstract class TemplateEmailBuilder<T>(
)

helper.setText(text, html)

yamlVisitor.data.getOrDefault("attachments", emptyList()).forEach { addFile(helper::addAttachment, it) }
yamlVisitor.data.getOrDefault("inline", emptyList()).forEach { addFile(helper::addInline, it) }
}

private fun addFile(fn: (String, Resource) -> Any, file: String): Pair<String, String>? {
var split = file.split("\\s*::\\s*".toRegex(), 2)
private fun addFile(fn: (String, Resource) -> Any, file: String) {
val split = file.split("\\s*::\\s*".toRegex(), 2)

if (split.isEmpty()) {
return null
} else if (split.size == 1) {
split = listOf(split[0], split[0])
}
if (split.isEmpty()) return

val name = split[0]
val path = split[1]
val path = split.getOrElse(1) { split[0] }

fn(name, UrlResource(path))

return Pair(name, path)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,17 @@ package pt.up.fe.ni.website.backend.service
import org.springframework.mail.javamail.JavaMailSender
import org.springframework.mail.javamail.MimeMessageHelper
import org.springframework.stereotype.Service
import pt.up.fe.ni.website.backend.config.email.EmailConfigProperties
import pt.up.fe.ni.website.backend.email.EmailBuilder

@Service
class EmailService(
private val mailSender: JavaMailSender,
val emailConfigProperties: EmailConfigProperties
private val mailSender: JavaMailSender
) {
fun send(email: EmailBuilder) {
val message = mailSender.createMimeMessage()

val helper = MimeMessageHelper(message, true)
email.build(helper, emailConfigProperties)
email.build(helper)

mailSender.send(message)
}
Expand Down

0 comments on commit 744c69c

Please sign in to comment.