TokenMessageBuilder.java
/*
* The coLAB project
* Copyright (C) 2021-2023 AlbaSim, MEI, HEIG-VD, HES-SO
*
* Licensed under the MIT License
*/
package ch.colabproject.colab.api.controller.token;
import ch.colabproject.colab.api.model.token.Token;
import java.text.MessageFormat;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
/**
* To build the body of the message to send for a token.
*
* @author sandra
*/
public class TokenMessageBuilder {
/**
* Text to set as a footer to inform about the validity of the message
*/
public static final String VALIDITY_FOOTER = "This link can be used until {0} GMT.";
/**
* The message title
*/
private String headTitle;
/**
* The message main picture
*/
private String picture;
/**
* The message heading
*/
private String heading;
/**
* The message sub heading
*/
private String subheading;
/**
* The message informations
*/
private String info;
/**
* The link to go to consume the token on co.LAB
*/
private String linkHref;
/**
* The label of the link to go to consume the token on co.LAB
*/
private String linkLabel;
/**
* The message footer info
*/
private List<String> footer = new ArrayList<>();
/**
* Constructor
*
* @param token the token for which we are writing a message
*/
public TokenMessageBuilder(Token token) {
// this.token = token;
headTitle = null;
picture = null;
heading = null;
subheading = null;
info = null;
linkHref = null;
linkLabel = null;
footer = new ArrayList<>();
if (token.getExpirationDate() != null) {
footer.add(MessageFormat.format(VALIDITY_FOOTER,
token.getExpirationDate().format(DateTimeFormatter.RFC_1123_DATE_TIME)));
}
}
/**
* Set the message head title
*
* @param headTitle the head title to set
*
* @return this builder
*/
public TokenMessageBuilder headTitle(String headTitle) {
this.headTitle = headTitle;
return this;
}
/**
* Set the message main picture
*
* @param picture the main picture to set
*
* @return this builder
*/
public TokenMessageBuilder picture(String picture) {
this.picture = picture;
return this;
}
/**
* Set the message heading
*
* @param heading the heading to set
*
* @return this builder
*/
public TokenMessageBuilder heading(String heading) {
this.heading = heading;
return this;
}
/**
* Set the message sub heading
*
* @param subheading the sub heading to set
*
* @return this builder
*/
public TokenMessageBuilder subheading(String subheading) {
this.subheading = subheading;
return this;
}
/**
* Set the message additional content
*
* @param info the additional content to set
*
* @return this builder
*/
public TokenMessageBuilder info(String info) {
this.info = info;
return this;
}
/**
* Set the message link href
*
* @param linkHref the link href to set
*
* @return this builder
*/
public TokenMessageBuilder linkHref(String linkHref) {
this.linkHref = linkHref;
return this;
}
/**
* Set the message link label
*
* @param linkLabel the link label to set
*
* @return this builder
*/
public TokenMessageBuilder linkLabel(String linkLabel) {
this.linkLabel = linkLabel;
return this;
}
/**
* Add a message footer
*
* @param footer the footer to add
*
* @return this builder
*/
public TokenMessageBuilder additionalFooter(String footer) {
this.footer.add(footer);
return this;
}
/**
* Build the email body to send with the token
*
* @return html email body
*/
public String build() {
return "<!DOCTYPE html>\n"
+ "<html lang=\"en\" xmlns=\"http://www.w3.org/1999/xhtml\">\n"
+ " <head>\n"
+ " <meta charset=\"utf-8\" />\n"
+ " <!-- utf-8 works for most cases -->\n"
+ " <meta name=\"viewport\" content=\"width=device-width\" />\n"
+ " <!-- Forcing initial-scale shouldn't be necessary -->\n"
+ " <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n"
+ " <!-- Use the latest (edge) version of IE rendering engine -->\n"
+ " <meta name=\"x-apple-disable-message-reformatting\" />\n"
+ " <!-- Disable auto-scale in iOS 10 Mail entirely -->\n"
+ " <title>" + headTitle + "</title>\n"
+ " <!-- The title tag shows in email notifications, like Android 4.4. -->\n"
+ " <style>\n"
+ " h2,\n"
+ " h3 {\n"
+ " font-family: sans-serif;\n"
+ " color: #000000;\n"
+ " margin-top: 0;\n"
+ " }\n"
+ " /* What it does: Stops email clients resizing small text. */\n"
+ " * {\n"
+ " -ms-text-size-adjust: 100%;\n"
+ " -webkit-text-size-adjust: 100%;\n"
+ " }\n"
+ " /* What it does: Prevents Windows 10 Mail from underlining links despite inline CSS. Styles for underlined links should be inline. */\n"
+ " a {\n"
+ " text-decoration: none;\n"
+ " }\n"
+ " /* What it does: Removes right gutter in Gmail iOS app: https://github.com/TedGoas/Cerberus/issues/89 */\n"
+ " /* Create one of these media queries for each additional viewport size you'd like to fix */\n"
+ "\n"
+ " /* iPhone 4, 4S, 5, 5S, 5C, and 5SE */\n"
+ " @media only screen and (min-device-width: 320px) and (max-device-width: 374px) {\n"
+ " u ~ div .email-container {\n"
+ " min-width: 320px !important;\n"
+ " }\n"
+ " }\n"
+ " /* iPhone 6, 6S, 7, 8, and X */\n"
+ " @media only screen and (min-device-width: 375px) and (max-device-width: 413px) {\n"
+ " u ~ div .email-container {\n"
+ " min-width: 375px !important;\n"
+ " }\n"
+ " }\n"
+ " /* iPhone 6+, 7+, and 8+ */\n"
+ " @media only screen and (min-device-width: 414px) {\n"
+ " u ~ div .email-container {\n"
+ " min-width: 414px !important;\n"
+ " }\n"
+ " }\n"
+ " </style>\n"
+ " </head>\n"
+ "\n"
+ " <body\n"
+ " width=\"100%\"\n"
+ " style=\"\n"
+ " margin: 0;\n"
+ " padding: 0 !important;\n"
+ " mso-line-height-rule: exactly;\n"
+ " background-color: #f1f1f1;\n"
+ " font-family: sans-serif;\n"
+ " font-size: 15px;\n"
+ " line-height: 1.8;\n"
+ " color: rgba(0, 0, 0, 0.4);\n"
+ " \"\n"
+ " >\n"
+ " <div style=\"max-width: 600px; margin: 0 auto\" class=\"email-container\">\n"
+ " <div\n"
+ " align=\"center\"\n"
+ " role=\"presentation\"\n"
+ " cellspacing=\"0\"\n"
+ " cellpadding=\"0\"\n"
+ " border=\"0\"\n"
+ " width=\"100%\"\n"
+ " style=\"margin: auto\"\n"
+ " >\n"
+ " <div valign=\"middle\" class=\"hero\" style=\"padding: 3em 0 2em 0; background: #ffffff\">\n"
+ " " + picture + "\n"
+ " <div class=\"text\" style=\"padding: 0 2.5em; text-align: center\">\n"
+ (StringUtils.isNotBlank(heading)
? (" <h2 style=\"font-size: 30px; margin-bottom: 0\">" + heading
+ "</h2>\n")
: (""))
+ (StringUtils.isNotBlank(subheading) ? (" <h3>" + subheading + "</h3>\n")
: (""))
+ (StringUtils.isNotBlank(info) ? (" " + info + "\n")
: (""))
+ " <p>\n"
+ " <a\n"
+ " href=\"" + linkHref + "\"\n"
+ " style=\"\n"
+ " padding: 10px 15px;\n"
+ " display: inline-block;\n"
+ " border-radius: 5px;\n"
+ " background: #50bfd5;\n"
+ " color: #ffffff;\n"
+ " \">\n"
+ " " + linkLabel + "\n"
+ " </a>\n"
+ " </p>\n"
+ ((footer != null && footer.isEmpty())
? (" <p>" + footer.stream().collect(Collectors.joining(" ")) + "</p>")
: (""))
+ " </div>\n"
+ " </div>\n"
+ " </div>\n"
+ " </div>\n"
+ " </body>\n"
+ "</html>";
}
}