Skip to content

Commit

Permalink
Support Collection of strings and JsonArray as mail recipients in Mai…
Browse files Browse the repository at this point in the history
…lActivityBehavior (flowable#3671)

Co-authored-by: Roman Saratz <[email protected]>
  • Loading branch information
roumn and Roman Saratz committed Jul 10, 2023
1 parent d27f3f5 commit b95cc33
Show file tree
Hide file tree
Showing 5 changed files with 261 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.activation.DataSource;
import javax.naming.NamingException;
Expand All @@ -46,6 +49,9 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;

/**
* Based on the MailActivityBehavior found in the bpmn engine, adapted for use in cmmn.
*
Expand Down Expand Up @@ -83,10 +89,10 @@ public void execute(CommandContext commandContext, PlanItemInstanceEntity planIt
Email email = null;
try {
String headersStr = getStringFromField(headers, planItemInstanceEntity);
String toStr = getStringFromField(to, planItemInstanceEntity);
Collection<String> toList = parseRecipients(to, planItemInstanceEntity);
String fromStr = getStringFromField(from, planItemInstanceEntity);
String ccStr = getStringFromField(cc, planItemInstanceEntity);
String bccStr = getStringFromField(bcc, planItemInstanceEntity);
Collection<String> ccList = parseRecipients(cc, planItemInstanceEntity);
Collection<String> bccList = parseRecipients(bcc, planItemInstanceEntity);
String subjectStr = getStringFromField(subject, planItemInstanceEntity);
String textStr = textVar == null ? getStringFromField(text, planItemInstanceEntity)
: getStringFromField(getExpression(commandContext, planItemInstanceEntity, textVar), planItemInstanceEntity);
Expand All @@ -97,16 +103,16 @@ public void execute(CommandContext commandContext, PlanItemInstanceEntity planIt
List<DataSource> dataSources = new LinkedList<>();
getFilesFromFields(attachments, planItemInstanceEntity, files, dataSources);

if (StringUtils.isAllEmpty(toStr, ccStr, bccStr)) {
if (toList.isEmpty() && ccList.isEmpty() && bccList.isEmpty()) {
throw new FlowableException("No recipient could be found for sending email");
}

email = createEmail(textStr, htmlStr, attachmentsExist(files, dataSources));
addHeader(email, headersStr);
addTo(commandContext, email, toStr, planItemInstanceEntity.getTenantId());
addTo(email, toList, planItemInstanceEntity.getTenantId(), commandContext);
setFrom(commandContext, email, fromStr, planItemInstanceEntity.getTenantId());
addCc(commandContext, email, ccStr, planItemInstanceEntity.getTenantId());
addBcc(commandContext, email, bccStr, planItemInstanceEntity.getTenantId());
addCc(email, ccList, planItemInstanceEntity.getTenantId(), commandContext);
addBcc(email, bccList, planItemInstanceEntity.getTenantId(), commandContext);
setSubject(email, subjectStr);
setMailServerProperties(commandContext, email, planItemInstanceEntity.getTenantId());
setCharset(email, charSetStr, planItemInstanceEntity.getTenantId());
Expand Down Expand Up @@ -190,17 +196,17 @@ protected MultiPartEmail createMultiPartEmail(String text) {
}
}

protected void addTo(CommandContext commandContext, Email email, String to, String tenantId) {
if (to == null) {
protected void addTo(Email email, Collection<String> to, String tenantId, CommandContext commandContext) {
if (to == null || to.isEmpty()) {
return;
}
String newTo = getForceTo(commandContext, tenantId);
if (newTo == null) {
newTo = to;
Collection<String> newTo = to;
Collection<String> forceTo = getForceTo(commandContext, tenantId);
if (forceTo != null && !forceTo.isEmpty()) {
newTo = forceTo;
}
String[] tos = splitAndTrim(newTo);
if (tos != null) {
for (String t : tos) {
if (!newTo.isEmpty()) {
for (String t : newTo) {
try {
email.addTo(t);
} catch (EmailException e) {
Expand Down Expand Up @@ -238,18 +244,18 @@ protected void setFrom(CommandContext commandContext, Email email, String from,
}
}

protected void addCc(CommandContext commandContext, Email email, String cc, String tenantId) {
if (cc == null) {
protected void addCc(Email email, Collection<String> cc, String tenantId, CommandContext commandContext) {
if (cc == null || cc.isEmpty()) {
return;
}
Collection<String> newCc = cc;

String newCc = getForceTo(commandContext, tenantId);
if (newCc == null) {
newCc = cc;
Collection<String> forceTo = getForceTo(commandContext, tenantId);
if (forceTo != null && !forceTo.isEmpty()) {
newCc = forceTo;
}
String[] ccs = splitAndTrim(newCc);
if (ccs != null) {
for (String c : ccs) {
if (!newCc.isEmpty()) {
for (String c : newCc) {
try {
email.addCc(c);
} catch (EmailException e) {
Expand All @@ -259,17 +265,17 @@ protected void addCc(CommandContext commandContext, Email email, String cc, Stri
}
}

protected void addBcc(CommandContext commandContext, Email email, String bcc, String tenantId) {
if (bcc == null) {
protected void addBcc(Email email, Collection<String> bcc, String tenantId, CommandContext commandContext) {
if (bcc == null || bcc.isEmpty()) {
return;
}
String newBcc = getForceTo(commandContext, tenantId);
if (newBcc == null) {
newBcc = bcc;
Collection<String> newBcc = bcc;
Collection<String> forceTo = getForceTo(commandContext, tenantId);
if (forceTo != null && !forceTo.isEmpty()) {
newBcc = forceTo;
}
String[] bccs = splitAndTrim(newBcc);
if (bccs != null) {
for (String b : bccs) {
if (!newBcc.isEmpty()) {
for (String b : newBcc) {
try {
email.addBcc(b);
} catch (EmailException e) {
Expand Down Expand Up @@ -378,13 +384,9 @@ protected void setCharset(Email email, String charSetStr, String tenantId) {
}
}

protected String[] splitAndTrim(String str) {
protected Collection<String> splitAndTrim(String str) {
if (str != null) {
String[] splittedStrings = str.split(",");
for (int i = 0; i < splittedStrings.length; i++) {
splittedStrings[i] = splittedStrings[i].trim();
}
return splittedStrings;
return Arrays.stream(str.split(",")).map(String::trim).collect(Collectors.toList());
}
return null;
}
Expand All @@ -399,6 +401,32 @@ protected String getStringFromField(Expression expression, PlanItemInstanceEntit
return null;
}

protected Collection<String> parseRecipients(Expression expression, PlanItemInstanceEntity planItemInstanceEntity) {
if (expression == null) {
return Collections.emptyList();
}
Object value = expression.getValue(planItemInstanceEntity);
if (value == null) {
return Collections.emptyList();
}
if (value instanceof Collection) {
return (Collection<String>) value;
} else if (value instanceof ArrayNode) {
ArrayNode arrayNode = (ArrayNode) value;
Collection<String> recipients = new ArrayList<>(arrayNode.size());
for (JsonNode node : arrayNode) {
recipients.add(node.asText());
}
return recipients;
} else {
String str = value.toString();
if (StringUtils.isNotEmpty(str)) {
return Arrays.asList(value.toString().split("[\\s]*,[\\s]*"));
}
}
return Collections.emptyList();
}

protected void getFilesFromFields(Expression expression, PlanItemInstanceEntity planItemInstanceEntity, List<File> files, List<DataSource> dataSources) {

if (expression == null) {
Expand Down Expand Up @@ -489,7 +517,7 @@ protected void handleException(PlanItemInstanceEntity planItemInstanceEntity, St
}
}

protected String getForceTo(CommandContext commandContext, String tenantId) {
protected Collection<String> getForceTo(CommandContext commandContext, String tenantId) {
String forceTo = null;
if (tenantId != null && tenantId.length() > 0) {
Map<String, MailServerInfo> mailServers = CommandContextUtil.getCmmnEngineConfiguration(commandContext).getMailServers();
Expand All @@ -503,7 +531,7 @@ protected String getForceTo(CommandContext commandContext, String tenantId) {
forceTo = CommandContextUtil.getCmmnEngineConfiguration(commandContext).getMailServerForceTo();
}

return forceTo;
return splitAndTrim(forceTo);
}

protected Charset getDefaultCharset(String tenantId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

Expand All @@ -41,6 +42,9 @@
import org.subethamail.wiser.Wiser;
import org.subethamail.wiser.WiserMessage;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;

/**
* @author Joram Barrez
*/
Expand Down Expand Up @@ -162,6 +166,44 @@ public void testTextMailExpressions() {

}

@Test
@CmmnDeployment(resources = "org/flowable/cmmn/test/task/CmmnMailTaskTest.testTextMailExpressions.cmmn")
public void testDynamicRecipientsStringList() throws MessagingException {
String recipients = "flowable@localhost, [email protected]";
testDynamicRecipientsInternal(recipients);
}

@Test
@CmmnDeployment(resources = "org/flowable/cmmn/test/task/CmmnMailTaskTest.testTextMailExpressions.cmmn")
public void testDynamicRecipientsArrayList() throws MessagingException {
List<String> recipients = Arrays.asList("flowable@localhost", "[email protected]");
testDynamicRecipientsInternal(recipients);
}

@Test
@CmmnDeployment(resources = "org/flowable/cmmn/test/task/CmmnMailTaskTest.testTextMailExpressions.cmmn")
public void testDynamicRecipientsArrayNode() throws MessagingException {
ArrayNode recipients = new ObjectMapper().createArrayNode().add("flowable@localhost").add("[email protected]");
testDynamicRecipientsInternal(recipients);
}

private void testDynamicRecipientsInternal(Object recipients) throws MessagingException {
cmmnRuntimeService.createCaseInstanceBuilder()
.caseDefinitionKey("testMail")
.variable("toVar", recipients)
.variable("fromVar", "[email protected]")
.variable("ccVar", recipients)
.variable("bccVar", recipients)
.variable("subjectVar", "Testing")
.variable("bodyVar", "The test body")
.start();
List<WiserMessage> messages = wiser.getMessages();
MimeMessage mimeMessage = messages.get(0).getMimeMessage();
assertThat(mimeMessage.getHeader("To", null)).isEqualTo("flowable@localhost, [email protected]");
assertThat(mimeMessage.getHeader("Cc", null)).isEqualTo("flowable@localhost, [email protected]");

}

@Test
@CmmnDeployment
public void testCcBccWithoutTo() {
Expand Down
Loading

0 comments on commit b95cc33

Please sign in to comment.