Author: mbrohl
Date: Fri Aug 18 19:10:41 2017
New Revision: 1805459
URL: http://svn.apache.org/viewvc?rev=1805459&view=rev
Log:
Improved: EmailServices.sendMailFromScreen improved to take multiple
attachments with appropriate type along with several email fixes.
(OFBIZ-9395)
This patch fixes a number of issues combined in a patch because of the
code dependencies.
1. it enables to add BCC adress(es) to service
OrderServices.sendOrderNotificationScreens to oversteer
ProductStoreEmailSetting of BCC the same was as for CC.
2. a method UtilValidate.isEmailList(String) is added to check a
comma separated list of email addresses, used for example to check the
String passed to the new BCC field for an Order-Notification.
3. there are improvements in EmailServices.sendMailFromScreen. The
attachment type of MailAttachments is now not only .pdf but depends on
the specific file. This has not been the case before - the mime type was
always hard coded as .pdf. The same goes for the bodyPart content-type
which is now set to the passed content type or the default text/html
type. Before this was also always set to text/html.
Additionally, an attachment that has the mime-type text/plain is not
rendered with the fop-renderer anymore but with a simple text-renderer.
Therefore it is possible to send an CSV file as attachment now.
The patch also refactors some catch-Blocks in the
EmailServices.sendMailFromScreen by using multi-catch since the e
xception handling is always the same.
Thanks Martin Becker for reporting and providing the patch.
Modified:
ofbiz/ofbiz-framework/trunk/applications/order/servicedef/services.xml
ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/order/OrderServices.java
ofbiz/ofbiz-framework/trunk/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilValidate.java
ofbiz/ofbiz-framework/trunk/framework/common/src/main/java/org/apache/ofbiz/common/email/EmailServices.java
Modified: ofbiz/ofbiz-framework/trunk/applications/order/servicedef/services.xml
URL:
http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/servicedef/services.xml?rev=1805459&r1=1805458&r2=1805459&view=diff
==============================================================================
--- ofbiz/ofbiz-framework/trunk/applications/order/servicedef/services.xml
(original)
+++ ofbiz/ofbiz-framework/trunk/applications/order/servicedef/services.xml Fri
Aug 18 19:10:41 2017
@@ -34,6 +34,7 @@ under the License.
<attribute name="body" type="String" mode="OUT" optional="true"/>
<attribute name="sendTo" type="String" mode="IN" optional="true"/>
<attribute name="sendCc" type="String" mode="IN" optional="true"/>
+ <attribute name="sendBcc" type="String" mode="IN" optional="true"/>
<attribute name="note" type="String" mode="IN" optional="true"/>
<attribute name="temporaryAnonymousUserLogin" type="org.apache.ofbiz.entity.GenericValue"
mode="IN" optional="true"/>
<attribute name="messageWrapper" type="org.apache.ofbiz.service.mail.MimeMessageWrapper"
mode="OUT" optional="true"/>
Modified:
ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/order/OrderServices.java
URL:
http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/order/OrderServices.java?rev=1805459&r1=1805458&r2=1805459&view=diff
==============================================================================
---
ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/order/OrderServices.java
(original)
+++
ofbiz/ofbiz-framework/trunk/applications/order/src/main/java/org/apache/ofbiz/order/order/OrderServices.java
Fri Aug 18 19:10:41 2017
@@ -83,6 +83,9 @@ import org.apache.ofbiz.service.ServiceU
import com.ibm.icu.util.Calendar;
+import org.apache.commons.lang.StringUtils;
+import org.apache.fop.apps.MimeConstants;
+
/**
* Order Processing Services
*/
@@ -2533,8 +2536,10 @@ public class OrderServices {
GenericValue userLogin = (GenericValue) context.get("userLogin");
String orderId = (String) context.get("orderId");
String orderItemSeqId = (String) context.get("orderItemSeqId");
+ String shipGroupSeqId = (String) context.get("shipGroupSeqId");
String sendTo = (String) context.get("sendTo");
String sendCc = (String) context.get("sendCc");
+ String sendBcc = (String) context.get("sendBcc");
String note = (String) context.get("note");
String screenUri = (String) context.get("screenUri");
GenericValue temporaryAnonymousUserLogin = (GenericValue)
context.get("temporaryAnonymousUserLogin");
@@ -2589,10 +2594,17 @@ public class OrderServices {
String xslfoAttachScreenLocation =
productStoreEmail.getString("xslfoAttachScreenLocation");
sendMap.put("xslfoAttachScreenLocation",
xslfoAttachScreenLocation);
// add attachmentName param to get an attachment namend "[oderId].pdf"
instead of default "Details.pdf"
- sendMap.put("attachmentName", orderId + ".pdf");
+ sendMap.put("attachmentName", (UtilValidate.isNotEmpty(shipGroupSeqId) ? orderId + "-" + StringUtils.stripStart(shipGroupSeqId, "0")
: orderId) + ".pdf");
+ sendMap.put("attachmentType", MimeConstants.MIME_PDF);
} else {
sendMap.put("bodyScreenUri", screenUri);
}
+
+ if (context.containsKey("xslfoAttachScreenLocationList")) {
+ sendMap.put("xslfoAttachScreenLocationList",
context.get("xslfoAttachScreenLocationList"));
+ sendMap.put("attachmentNameList",
context.get("attachmentNameList"));
+ sendMap.put("attachmentTypeList",
context.get("attachmentTypeList"));
+ }
// website
sendMap.put("webSiteId", orderHeader.get("webSiteId"));
@@ -2636,6 +2648,7 @@ public class OrderServices {
bodyParameters.put("partyId", placingParty.get("partyId"));
}
bodyParameters.put("note", note);
+ bodyParameters.put("shipGroupSeqId", shipGroupSeqId);
sendMap.put("bodyParameters", bodyParameters);
sendMap.put("userLogin",userLogin);
@@ -2657,6 +2670,10 @@ public class OrderServices {
sendMap.put("sendCc", productStoreEmail.get("ccAddress"));
}
+ if ((sendBcc != null) && UtilValidate.isEmailList(sendBcc)) {
+ sendMap.put("sendBcc", sendBcc);
+ }
+
// send the notification
Map<String, Object> sendResp = null;
try {
Modified:
ofbiz/ofbiz-framework/trunk/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilValidate.java
URL:
http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilValidate.java?rev=1805459&r1=1805458&r2=1805459&view=diff
==============================================================================
---
ofbiz/ofbiz-framework/trunk/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilValidate.java
(original)
+++
ofbiz/ofbiz-framework/trunk/framework/base/src/main/java/org/apache/ofbiz/base/util/UtilValidate.java
Fri Aug 18 19:10:41 2017
@@ -691,6 +691,20 @@ public final class UtilValidate {
if (isEmpty(s)) return defaultEmptyOK;
return EmailValidator.getInstance().isValid(s);
}
+
+ /**
+ * Checks a String for a valid Email-List seperated by ",".
+ */
+ public static boolean isEmailList(String s) {
+ if (isEmpty(s)) return defaultEmptyOK;
+ String[] emails = s.split(",");
+ for (String email : emails) {
+ if (!EmailValidator.getInstance().isValid(email)) {
+ return false;
+ }
+ }
+ return true;
+ }
/** isUrl returns true if the string contains ://
* @param s String to validate
Modified:
ofbiz/ofbiz-framework/trunk/framework/common/src/main/java/org/apache/ofbiz/common/email/EmailServices.java
URL:
http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/framework/common/src/main/java/org/apache/ofbiz/common/email/EmailServices.java?rev=1805459&r1=1805458&r2=1805459&view=diff
==============================================================================
---
ofbiz/ofbiz-framework/trunk/framework/common/src/main/java/org/apache/ofbiz/common/email/EmailServices.java
(original)
+++
ofbiz/ofbiz-framework/trunk/framework/common/src/main/java/org/apache/ofbiz/common/email/EmailServices.java
Fri Aug 18 19:10:41 2017
@@ -51,6 +51,7 @@ import javax.mail.internet.MimeMultipart
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.stream.StreamSource;
+import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.MimeConstants;
import org.apache.ofbiz.base.util.Debug;
@@ -438,6 +439,12 @@ public class EmailServices {
if (UtilValidate.isNotEmpty(xslfoAttachScreenLocationListParam))
xslfoAttachScreenLocationList.addAll(xslfoAttachScreenLocationListParam);
if (UtilValidate.isNotEmpty(attachmentNameListParam))
attachmentNameList.addAll(attachmentNameListParam);
+ List<String> attachmentTypeList = new LinkedList<String>();
+ String attachmentTypeParam = (String)
serviceContext.remove("attachmentType");
+ List<String> attachmentTypeListParam =
UtilGenerics.checkList(serviceContext.remove("attachmentTypeList"));
+ if (UtilValidate.isNotEmpty(attachmentTypeParam))
attachmentTypeList.add(attachmentTypeParam);
+ if (UtilValidate.isNotEmpty(attachmentTypeListParam))
attachmentTypeList.addAll(attachmentTypeListParam);
+
Locale locale = (Locale) serviceContext.get("locale");
Map<String, Object> bodyParameters =
UtilGenerics.checkMap(serviceContext.remove("bodyParameters"));
if (bodyParameters == null) {
@@ -504,9 +511,9 @@ public class EmailServices {
List<Map<String, ? extends Object>> bodyParts = new
LinkedList<Map<String, ? extends Object>>();
if (bodyText != null) {
bodyText = FlexibleStringExpander.expandString(bodyText,
screenContext, locale);
- bodyParts.add(UtilMisc.<String, Object>toMap("content", bodyText,
"type", "text/html"));
+ bodyParts.add(UtilMisc.<String, Object>toMap("content", bodyText, "type", UtilValidate.isNotEmpty(contentType) ? contentType :
"text/html"));
} else {
- bodyParts.add(UtilMisc.<String, Object>toMap("content", bodyWriter.toString(),
"type", "text/html"));
+ bodyParts.add(UtilMisc.<String, Object>toMap("content", bodyWriter.toString(), "type", UtilValidate.isNotEmpty(contentType) ?
contentType : "text/html"));
}
for (int i = 0; i <
xslfoAttachScreenLocationList.size(); i++) {
@@ -515,39 +522,51 @@ public class EmailServices {
if (UtilValidate.isNotEmpty(attachmentNameList) &&
attachmentNameList.size() >= i) {
attachmentName = attachmentNameList.get(i);
}
+
+ String attachmentType = MimeConstants.MIME_PDF;
+ if (UtilValidate.isNotEmpty(attachmentTypeList) &&
attachmentTypeList.size() >= i) {
+ attachmentType = attachmentTypeList.get(i);
+ }
+
isMultiPart = true;
// start processing fo pdf attachment
try {
Writer writer = new StringWriter();
- MapStack<String> screenContextAtt = MapStack.create();
// substitute the freemarker variables...
- ScreenStringRenderer foScreenStringRenderer = new MacroScreenRenderer(EntityUtilProperties.getPropertyValue("widget",
"screenfop.name", dctx.getDelegator()),
- EntityUtilProperties.getPropertyValue("widget", "screenfop.screenrenderer",
dctx.getDelegator()));
+ ScreenStringRenderer foScreenStringRenderer = null;
+ if(MimeConstants.MIME_PLAIN_TEXT.equals(attachmentType)){
+ foScreenStringRenderer = new MacroScreenRenderer(EntityUtilProperties.getPropertyValue("widget", "screentext.name",
dctx.getDelegator()),
+ EntityUtilProperties.getPropertyValue("widget", "screentext.screenrenderer",
dctx.getDelegator()));
+ }else{
+ foScreenStringRenderer = new MacroScreenRenderer(EntityUtilProperties.getPropertyValue("widget", "screenfop.name",
dctx.getDelegator()),
+ EntityUtilProperties.getPropertyValue("widget", "screenfop.screenrenderer",
dctx.getDelegator()));
+ }
ScreenRenderer screensAtt = new ScreenRenderer(writer,
screenContext, foScreenStringRenderer);
screensAtt.populateContextForService(dctx, bodyParameters);
- screenContextAtt.putAll(bodyParameters);
screensAtt.render(xslfoAttachScreenLocation);
- // create the input stream for the generation
- StreamSource src = new StreamSource(new
StringReader(writer.toString()));
-
// create the output stream for the generation
ByteArrayOutputStream baos = new ByteArrayOutputStream();
- Fop fop = ApacheFopWorker.createFopInstance(baos,
MimeConstants.MIME_PDF);
- ApacheFopWorker.transform(src, null, fop);
+ if (MimeConstants.MIME_PLAIN_TEXT.equals(attachmentType)) {
+ baos.write(writer.toString().getBytes());
+ } else {
+ // create the input stream for the generation
+ StreamSource src = new StreamSource(new
StringReader(writer.toString()));
+ Fop fop = ApacheFopWorker.createFopInstance(baos,
attachmentType);
+ ApacheFopWorker.transform(src, null, fop);
+ }
- // and generate the PDF
+ // and generate the attachment
baos.flush();
baos.close();
// store in the list of maps for sendmail....
- bodyParts.add(UtilMisc.<String, Object> toMap("content", baos.toByteArray(),
"type", "application/pdf", "filename",
- attachmentName));
- } catch (Exception e) {
- Debug.logError(e, "Error rendering PDF attachment for email:
" + e.toString(), module);
- return ServiceUtil.returnError(UtilProperties.getMessage(resource,
"CommonEmailSendRenderingScreenPdfError",
- UtilMisc.toMap("errorString", e.toString()),
locale));
+ bodyParts.add(UtilMisc.<String, Object>toMap("content", baos.toByteArray(), "type", attachmentType, "filename",
attachmentName));
+
+ } catch
(GeneralException|IOException|SAXException|ParserConfigurationException
|TemplateException ge) {
+ Debug.logError(ge, "Error rendering PDF attachment for email:
" + ge.toString(), module);
+ return ServiceUtil.returnError(UtilProperties.getMessage(resource, "CommonEmailSendRenderingScreenPdfError",
UtilMisc.toMap("errorString", ge.toString()), locale));
}
serviceContext.put("bodyParts", bodyParts);