svn commit: r774198 - in /ofbiz/trunk/applications/party: servicedef/secas.xml servicedef/services.xml src/org/ofbiz/party/communication/CommunicationEventServices.java

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

svn commit: r774198 - in /ofbiz/trunk/applications/party: servicedef/secas.xml servicedef/services.xml src/org/ofbiz/party/communication/CommunicationEventServices.java

jaz-3
Author: jaz
Date: Wed May 13 05:01:13 2009
New Revision: 774198

URL: http://svn.apache.org/viewvc?rev=774198&view=rev
Log:
refactored the way communication events are created from emails; there are two services (instead of 1) which run now:
1) in-validate -- creates the communication event so the communication event ID can be used by the send mail service
2) commit -- stores the message content, addresses and now also stores all attachments

Modified:
    ofbiz/trunk/applications/party/servicedef/secas.xml
    ofbiz/trunk/applications/party/servicedef/services.xml
    ofbiz/trunk/applications/party/src/org/ofbiz/party/communication/CommunicationEventServices.java

Modified: ofbiz/trunk/applications/party/servicedef/secas.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/servicedef/secas.xml?rev=774198&r1=774197&r2=774198&view=diff
==============================================================================
--- ofbiz/trunk/applications/party/servicedef/secas.xml (original)
+++ ofbiz/trunk/applications/party/servicedef/secas.xml Wed May 13 05:01:13 2009
@@ -60,11 +60,26 @@
         <action service="createWorkEffort" mode="sync"/>
     </eca>
 
-    <!-- emails should not be stored as new communication event if there is no partyId or if it is already a commevent being sent out -->
-    <eca service="sendMail" event="commit">
+    <!-- email : communication event -->
+    <eca service="sendMailMultiPart" event="in-validate">
+        <condition field-name="partyId" operator="is-not-empty"/>
+        <condition field-name="communicationEventId" operator="is-empty"/>        
+        <action service="createCommEventFromEmail" mode="sync" run-as-user="system"/>
+    </eca>
+    <eca service="sendMail" event="in-validate">
         <condition field-name="partyId" operator="is-not-empty"/>
-        <condition field-name="communicationEventId" operator="is-empty"/>
-        <action service="storeEmailAsCommunication" mode="sync"/>
+        <condition field-name="communicationEventId" operator="is-empty"/>      
+        <action service="createCommEventFromEmail" mode="sync" run-as-user="system"/>
+    </eca>
+    <eca service="sendMailMultiPart" event="commit">
+        <condition field-name="messageWrapper" operator="is-not-empty"/>
+        <condition field-name="communicationEventId" operator="is-not-empty"/>
+        <action service="updateCommEventAfterEmail" mode="sync" run-as-user="system"/>
+    </eca>
+    <eca service="sendMail" event="commit">
+        <condition field-name="messageWrapper" operator="is-not-empty"/>
+        <condition field-name="communicationEventId" operator="is-not-empty"/>
+        <action service="updateCommEventAfterEmail" mode="sync" run-as-user="system"/>
     </eca>
     
     <!-- all these secas are now replaced by a sheduled job (sendEmailDated) which runs every 5 minutes -->

Modified: ofbiz/trunk/applications/party/servicedef/services.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/servicedef/services.xml?rev=774198&r1=774197&r2=774198&view=diff
==============================================================================
--- ofbiz/trunk/applications/party/servicedef/services.xml (original)
+++ ofbiz/trunk/applications/party/servicedef/services.xml Wed May 13 05:01:13 2009
@@ -792,18 +792,30 @@
             be of type EMAIL_COMMUNICATION. Will look for a contactMechIdTo to send the emails</description>
         <attribute name="communicationEventId" type="String" mode="IN" optional="false"/>
     </service>
-    <service name="storeEmailAsCommunication" engine="java"
-        location="org.ofbiz.party.communication.CommunicationEventServices" invoke="storeEmailAsCommunication" auth="true">
-        <description>Store email as a communication event with the status COM_COMPLETE and current timestamp as datetimeStarted and datetimeEnded.
-            The communication event will be from the party of the userLogin to the party of the partyId parameter.
-            It is meant to run a SECA after a sendMail to record outgoing emails.</description>
-        <attribute name="partyId" type="String" mode="IN" optional="true"/>
-        <attribute name="communicationEventId" type="String" mode="IN" optional="true"/>
+        
+    <!--  email to communication event ECA services -->
+    <service name="createCommEventFromEmail" engine="java"
+        location="org.ofbiz.party.communication.CommunicationEventServices" invoke="createCommEventFromEmail" auth="true">
+        <description>
+                Creates a CommunicationEvent record based on information before running a sendMail service (to be used via ECA)
+        </description>
+        <attribute name="partyId" type="String" mode="IN" optional="true"/>        
         <attribute name="subject" type="String" mode="IN" optional="false"/>
-        <attribute name="body" type="String" mode="IN" optional="false" allow-html="any"/>
+        <attribute name="sendFrom" type="String" mode="IN" optional="false"/>
+        <attribute name="sendTo" type="String" mode="IN" optional="false"/>
         <attribute name="contentType" type="String" mode="IN" optional="true"/>
-        <attribute name="emailType" type="String" mode="IN" optional="true"/>
+        <attribute name="statusId" type="String" mode="IN" optional="true"/>
+        <attribute name="communicationEventId" type="String" mode="OUT"/>
     </service>
+    <service name="updateCommEventAfterEmail" engine="java"
+        location="org.ofbiz.party.communication.CommunicationEventServices" invoke="updateCommEventAfterEmail" auth="true">
+        <description>
+                Updates a CommunicationEvent record after running a sendMail service (to be used via ECA)
+        </description>
+        <attribute name="communicationEventId" type="String" mode="IN" optional="false"/>        
+        <attribute name="messageWrapper" type="org.ofbiz.service.mail.MimeMessageWrapper" mode="IN" optional="false"/>        
+    </service>
+    
     <service name="storeIncomingEmail" engine="java"
         location="org.ofbiz.party.communication.CommunicationEventServices" invoke="storeIncomingEmail" auth="true">
         <description>

Modified: ofbiz/trunk/applications/party/src/org/ofbiz/party/communication/CommunicationEventServices.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/applications/party/src/org/ofbiz/party/communication/CommunicationEventServices.java?rev=774198&r1=774197&r2=774198&view=diff
==============================================================================
--- ofbiz/trunk/applications/party/src/org/ofbiz/party/communication/CommunicationEventServices.java (original)
+++ ofbiz/trunk/applications/party/src/org/ofbiz/party/communication/CommunicationEventServices.java Wed May 13 05:01:13 2009
@@ -19,9 +19,6 @@
 
 package org.ofbiz.party.communication;
 
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
 import java.nio.ByteBuffer;
 import java.sql.Timestamp;
 import java.util.Enumeration;
@@ -35,14 +32,8 @@
 import java.util.regex.Pattern;
 
 import javax.mail.Address;
-import javax.mail.BodyPart;
-import javax.mail.Header;
 import javax.mail.MessagingException;
-import javax.mail.Multipart;
-import javax.mail.Part;
 import javax.mail.internet.InternetAddress;
-import javax.mail.internet.MimeMessage;
-
 import javolution.util.FastList;
 import javolution.util.FastMap;
 
@@ -391,53 +382,133 @@
         return ServiceUtil.returnSuccess();
     }
 
-    /**
-     * Store email as communication event
-     *@param dctx The DispatchContext that this service is operating in
-     *@param serviceContext Map containing the input parameters
-     *@return Map with the result of the service, the output parameters
+    /*
+     * Store an outgoing email as a communication event;
+     * runs as a pre-invoke ECA on sendMail and sendMultipartMail services
+     * - service should run as the 'system' user
      */
-     public static Map<String, Object> storeEmailAsCommunication(DispatchContext dctx, Map<String, ? extends Object> serviceContext) {
+    public static Map<String, Object> createCommEventFromEmail(DispatchContext dctx, Map<String, ? extends Object> context) {
         LocalDispatcher dispatcher = dctx.getDispatcher();
-        GenericValue userLogin = (GenericValue) serviceContext.get("userLogin");
-
-        String subject = (String) serviceContext.get("subject");
-        String body = (String) serviceContext.get("body");
-        String partyId = (String) serviceContext.get("partyId");
-        String communicationEventId = (String) serviceContext.get("communicationEventId");
-        String contentType = (String) serviceContext.get("contentType");
-        String emailType = (String) serviceContext.get("emailType");
-
-        // only create a new communication event if the email is not already associated with one
-        if (communicationEventId == null) {
-            String partyIdFrom = (String) userLogin.get("partyId");
-            Map<String, Object> commEventMap = FastMap.newInstance();
-            commEventMap.put("communicationEventTypeId", "EMAIL_COMMUNICATION");
-            commEventMap.put("statusId", "COM_COMPLETE");
-            commEventMap.put("contactMechTypeId", "EMAIL_ADDRESS");
-            commEventMap.put("partyIdFrom", partyIdFrom);
-            commEventMap.put("partyIdTo", partyId);
-            commEventMap.put("datetimeStarted", UtilDateTime.nowTimestamp());
-            commEventMap.put("datetimeEnded", UtilDateTime.nowTimestamp());
-            commEventMap.put("subject", subject);
-            commEventMap.put("content", body);
-            commEventMap.put("userLogin", userLogin);
-            commEventMap.put("contentMimeTypeId", contentType);
-            String runService = "createCommunicationEvent";
-            if ("PARTY_REGIS_CONFIRM".equals(emailType)) {
-                runService = "createCommunicationEventWithoutPermission"; // used to create a new Customer, Prospect or Employee
-            }
-            try {
-                dispatcher.runSync(runService, commEventMap);
-            } catch (Exception e) {
-                Debug.logError(e, "Cannot store email as communication event", module);
-                return ServiceUtil.returnError("Cannot store email as communication event; see logs");
-            }
+        GenericDelegator delegator = dctx.getDelegator();
+        
+        GenericValue userLogin = (GenericValue) context.get("userLogin");
+        String subject = (String) context.get("subject");
+        String sendFrom = (String) context.get("sendFrom");
+        String sendTo = (String) context.get("sendTo");
+        String partyId = (String) context.get("partyId");        
+        String contentType = (String) context.get("contentType");        
+        String statusId = (String) context.get("statusId");
+        if (statusId == null) {
+            statusId = "COM_PENDING";
         }
-
+        
+        // get the from contact mech info
+        String contactMechIdFrom = null;
+        String partyIdFrom = null;
+        GenericValue fromCm;
+        try {
+            List<GenericValue> fromCms = delegator.findByAnd("PartyAndContactMech", UtilMisc.toMap("infoString", sendFrom), UtilMisc.toList("-fromDate"));
+            fromCms = EntityUtil.filterByDate(fromCms);
+            fromCm = EntityUtil.getFirst(fromCms);
+        } catch (GenericEntityException e) {
+            Debug.logError(e, module);
+            return ServiceUtil.returnError(e.getMessage());
+        }
+        if (fromCm != null) {
+            contactMechIdFrom = fromCm.getString("contactMechId");
+            partyIdFrom = fromCm.getString("partyId");
+        }
+        
+        // get the to contact mech info
+        String contactMechIdTo = null;
+        GenericValue toCm;
+        try {
+            List<GenericValue> toCms = delegator.findByAnd("PartyAndContactMech", UtilMisc.toMap("infoString", sendTo, "partyId", partyId), UtilMisc.toList("-fromDate"));
+            toCms = EntityUtil.filterByDate(toCms);
+            toCm = EntityUtil.getFirst(toCms);
+        } catch (GenericEntityException e) {
+            Debug.logError(e, module);
+            return ServiceUtil.returnError(e.getMessage());
+        }
+        if (toCm != null) {
+            contactMechIdTo = toCm.getString("contactMechId");
+        }
+        
+        Timestamp now = UtilDateTime.nowTimestamp();
+                
+        Map<String, Object> commEventMap = FastMap.newInstance();
+        commEventMap.put("communicationEventTypeId", "EMAIL_COMMUNICATION");
+        commEventMap.put("contactMechTypeId", "EMAIL_ADDRESS");
+        commEventMap.put("contactMechIdFrom", contactMechIdFrom);
+        commEventMap.put("contactMechIdTo", contactMechIdTo);
+        commEventMap.put("statusId", statusId);
+        
+        commEventMap.put("partyIdFrom", partyIdFrom);
+        commEventMap.put("partyIdTo", partyId);
+        commEventMap.put("datetimeStarted", now);
+        commEventMap.put("entryDate", now);
+        
+        commEventMap.put("subject", subject);      
+        commEventMap.put("userLogin", userLogin);
+        commEventMap.put("contentMimeTypeId", contentType);
+        
+        Map<String, Object> createResult;
+        try {
+            createResult = dispatcher.runSync("createCommunicationEvent", commEventMap);
+        } catch (GenericServiceException e) {
+            Debug.logError(e, module);
+            return ServiceUtil.returnError(e.getMessage());
+        }
+        if (ServiceUtil.isError(createResult)) {
+            return ServiceUtil.returnError(ServiceUtil.getErrorMessage(createResult));
+        }
+        String communicationEventId = (String) createResult.get("communicationEventId");
+        
+        Map<String, Object> result = ServiceUtil.returnSuccess();
+        result.put("communicationEventId", communicationEventId);
+        return result;
+    }
+    
+    /*
+     * Update the communication event with information from the email;
+     * runs as a post-commit ECA on sendMail and sendMultiPartMail services
+     * - service should run as the 'system' user
+     */
+    public static Map<String, Object> updateCommEventAfterEmail(DispatchContext dctx, Map<String, ? extends Object> context) {
+        LocalDispatcher dispatcher = dctx.getDispatcher();
+                
+        GenericValue userLogin = (GenericValue) context.get("userLogin");
+        String communicationEventId = (String) context.get("communicationEventId");
+        MimeMessageWrapper wrapper = (MimeMessageWrapper) context.get("messageWrapper");
+                                                        
+        Map<String, Object> commEventMap = FastMap.newInstance();
+        commEventMap.put("communicationEventId", communicationEventId);
+        commEventMap.put("statusId", "COM_COMPLETE");
+        commEventMap.put("datetimeEnded", UtilDateTime.nowTimestamp());
+        commEventMap.put("messageId", wrapper.getMessageId());
+        commEventMap.put("userLogin", userLogin);
+        commEventMap.put("content", wrapper.getMessageBody());
+        
+        // populate the address (to/from/cc/bcc) data
+        populateAddressesFromMessage(wrapper, commEventMap);
+        
+        // save the communication event        
+        try {
+            dispatcher.runSync("updateCommunicationEvent", commEventMap);
+        } catch (GenericServiceException e) {
+            return ServiceUtil.returnError(e.getMessage());
+        }
+        
+        // attachments
+        try {
+            createAttachmentContent(dispatcher, wrapper, communicationEventId, userLogin);
+        } catch (GenericServiceException e) {
+            return ServiceUtil.returnError(e.getMessage());
+        }    
+                        
         return ServiceUtil.returnSuccess();
     }
-
+            
     /**
      * This service is the main one for processing incoming emails.
      *
@@ -623,37 +694,9 @@
                 }
             }
 
-            // Retrieve all the addresses from the email
-            Set<String> emailAddressesFrom = new TreeSet<String>();
-            Set<String> emailAddressesTo = new TreeSet<String>();
-            Set<String> emailAddressesCC = new TreeSet<String>();
-            Set<String> emailAddressesBCC = new TreeSet<String>();
-            for (int x = 0 ; x < addressesFrom.length ; x++) {
-                emailAddressesFrom.add(((InternetAddress) addressesFrom[x]).getAddress());
-            }
-            for (int x = 0 ; x < addressesTo.length ; x++) {
-                emailAddressesTo.add(((InternetAddress) addressesTo[x]).getAddress());
-            }
-            if (addressesCC != null) {
-                for (int x = 0 ; x < addressesCC.length ; x++) {
-                    emailAddressesCC.add(((InternetAddress) addressesCC[x]).getAddress());
-                }
-            }
-            if (addressesBCC != null) {
-                for (int x = 0 ; x < addressesBCC.length ; x++) {
-                    emailAddressesBCC.add(((InternetAddress) addressesBCC[x]).getAddress());
-                }
-            }
-            String fromString = StringUtil.join(UtilMisc.toList(emailAddressesFrom), ",");
-            String toString = StringUtil.join(UtilMisc.toList(emailAddressesTo), ",");
-            String ccString = StringUtil.join(UtilMisc.toList(emailAddressesCC), ",");
-            String bccString = StringUtil.join(UtilMisc.toList(emailAddressesBCC), ",");
-
-            if (UtilValidate.isNotEmpty(fromString)) commEventMap.put("fromString", fromString);
-            if (UtilValidate.isNotEmpty(toString)) commEventMap.put("toString", toString);
-            if (UtilValidate.isNotEmpty(ccString)) commEventMap.put("ccString", ccString);
-            if (UtilValidate.isNotEmpty(bccString)) commEventMap.put("bccString", bccString);
-
+            // populate the address (to/from/cc/bcc) data
+            populateAddressesFromMessage(wrapper, commEventMap);
+            
             // store from/to parties, but when not found make a note of the email to/from address in the workEffort Note Section.
             String commNote = "";
             if (partyIdFrom != null) {
@@ -703,51 +746,8 @@
             communicationEventId = (String)result.get("communicationEventId");
 
             // handle the attachments
-            List<String> attachmentIndexes = wrapper.getAttachmentIndexes();
-            if (attachmentIndexes.size() > 0) {
-                Debug.logInfo("=== message has attachments [" + attachmentIndexes.size() + "] =====", module);
-                for (String attachmentIdx : attachmentIndexes) {
-                    Map<String, Object> attachmentMap = FastMap.newInstance();
-                    attachmentMap.put("communicationEventId", communicationEventId);
-                    attachmentMap.put("contentTypeId", "DOCUMENT");
-                    attachmentMap.put("mimeTypeId", "text/html");
-                    attachmentMap.put("userLogin", userLogin);
-                    if (subject != null && subject.length() > 80) {
-                        subject = subject.substring(0,80); // make sure not too big for database field. (20 characters for filename)
-                    }
-                    
-                    String attFileName = wrapper.getPartFilename(attachmentIdx);
-                    String attContentType = wrapper.getPartContentType(attachmentIdx);
-                    if (attContentType != null && attContentType.indexOf(";") > -1) {
-                        attContentType = attContentType.toLowerCase().substring(0, attContentType.indexOf(";"));
-                    }                    
-                    
-                    if (!UtilValidate.isEmpty(attFileName)) {
-                        attachmentMap.put("contentName", attFileName);
-                        attachmentMap.put("description", subject + "-" + attachmentIdx);
-                    } else {
-                        attachmentMap.put("contentName", subject + "-" + attachmentIdx);
-                    }
-                    
-                    attachmentMap.put("drMimeTypeId", attContentType);
-                    if (attContentType.startsWith("text")) {
-                        String text = wrapper.getPartText(attachmentIdx);
-                        attachmentMap.put("drDataResourceTypeId", "ELECTRONIC_TEXT");
-                        attachmentMap.put("textData", text);
-                    } else {
-                        ByteBuffer data = wrapper.getPartByteBuffer(attachmentIdx);                        
-                        if (Debug.infoOn()) Debug.logInfo("Binary attachment size: " + data.limit(), module);
-                        attachmentMap.put("drDataResourceName", attFileName);
-                        attachmentMap.put("imageData", data);
-                        attachmentMap.put("drDataResourceTypeId", "IMAGE_OBJECT"); // TODO: why always use IMAGE
-                        attachmentMap.put("_imageData_contentType", attContentType);
-                    }
-                    
-                    // save the content
-                    dispatcher.runSync("createCommContentDataResource", attachmentMap);                    
-                }
-            }
-            
+            createAttachmentContent(dispatcher, wrapper, communicationEventId, userLogin);
+                        
             // For all addresses create a CommunicationEventRoles
             createCommEventRoles(userLogin, delegator, dispatcher, communicationEventId, toParties, "ADDRESSEE");
             createCommEventRoles(userLogin, delegator, dispatcher, communicationEventId, ccParties, "CC");
@@ -769,6 +769,94 @@
         }
     }
 
+    private static void populateAddressesFromMessage(MimeMessageWrapper wrapper, Map<String, Object> commEventMap) {
+        // Retrieve all the addresses from the email
+        Address[] addressesFrom = wrapper.getFrom();
+        Address[] addressesTo = wrapper.getTo();
+        Address[] addressesCC = wrapper.getCc();
+        Address[] addressesBCC = wrapper.getBcc();
+        
+        Set<String> emailAddressesFrom = new TreeSet<String>();
+        Set<String> emailAddressesTo = new TreeSet<String>();
+        Set<String> emailAddressesCC = new TreeSet<String>();
+        Set<String> emailAddressesBCC = new TreeSet<String>();
+        for (int x = 0 ; x < addressesFrom.length ; x++) {
+            emailAddressesFrom.add(((InternetAddress) addressesFrom[x]).getAddress());
+        }
+        for (int x = 0 ; x < addressesTo.length ; x++) {
+            emailAddressesTo.add(((InternetAddress) addressesTo[x]).getAddress());
+        }
+        if (addressesCC != null) {
+            for (int x = 0 ; x < addressesCC.length ; x++) {
+                emailAddressesCC.add(((InternetAddress) addressesCC[x]).getAddress());
+            }
+        }
+        if (addressesBCC != null) {
+            for (int x = 0 ; x < addressesBCC.length ; x++) {
+                emailAddressesBCC.add(((InternetAddress) addressesBCC[x]).getAddress());
+            }
+        }
+        String fromString = StringUtil.join(UtilMisc.toList(emailAddressesFrom), ",");
+        String toString = StringUtil.join(UtilMisc.toList(emailAddressesTo), ",");
+        String ccString = StringUtil.join(UtilMisc.toList(emailAddressesCC), ",");
+        String bccString = StringUtil.join(UtilMisc.toList(emailAddressesBCC), ",");
+
+        if (UtilValidate.isNotEmpty(fromString)) commEventMap.put("fromString", fromString);
+        if (UtilValidate.isNotEmpty(toString)) commEventMap.put("toString", toString);
+        if (UtilValidate.isNotEmpty(ccString)) commEventMap.put("ccString", ccString);
+        if (UtilValidate.isNotEmpty(bccString)) commEventMap.put("bccString", bccString);
+    }
+    
+    private static void createAttachmentContent(LocalDispatcher dispatcher, MimeMessageWrapper wrapper, String communicationEventId, GenericValue userLogin) throws GenericServiceException {
+        // handle the attachments
+        String subject = wrapper.getSubject();        
+        List<String> attachmentIndexes = wrapper.getAttachmentIndexes();
+        
+        if (attachmentIndexes.size() > 0) {
+            Debug.logInfo("=== message has attachments [" + attachmentIndexes.size() + "] =====", module);
+            for (String attachmentIdx : attachmentIndexes) {
+                Map<String, Object> attachmentMap = FastMap.newInstance();
+                attachmentMap.put("communicationEventId", communicationEventId);
+                attachmentMap.put("contentTypeId", "DOCUMENT");
+                attachmentMap.put("mimeTypeId", "text/html");
+                attachmentMap.put("userLogin", userLogin);
+                if (subject != null && subject.length() > 80) {
+                    subject = subject.substring(0,80); // make sure not too big for database field. (20 characters for filename)
+                }
+                
+                String attFileName = wrapper.getPartFilename(attachmentIdx);
+                String attContentType = wrapper.getPartContentType(attachmentIdx);
+                if (attContentType != null && attContentType.indexOf(";") > -1) {
+                    attContentType = attContentType.toLowerCase().substring(0, attContentType.indexOf(";"));
+                }                    
+                
+                if (!UtilValidate.isEmpty(attFileName)) {
+                    attachmentMap.put("contentName", attFileName);
+                    attachmentMap.put("description", subject + "-" + attachmentIdx);
+                } else {
+                    attachmentMap.put("contentName", subject + "-" + attachmentIdx);
+                }
+                
+                attachmentMap.put("drMimeTypeId", attContentType);
+                if (attContentType.startsWith("text")) {
+                    String text = wrapper.getPartText(attachmentIdx);
+                    attachmentMap.put("drDataResourceTypeId", "ELECTRONIC_TEXT");
+                    attachmentMap.put("textData", text);
+                } else {
+                    ByteBuffer data = wrapper.getPartByteBuffer(attachmentIdx);                        
+                    if (Debug.infoOn()) Debug.logInfo("Binary attachment size: " + data.limit(), module);
+                    attachmentMap.put("drDataResourceName", attFileName);
+                    attachmentMap.put("imageData", data);
+                    attachmentMap.put("drDataResourceTypeId", "IMAGE_OBJECT"); // TODO: why always use IMAGE
+                    attachmentMap.put("_imageData_contentType", attContentType);
+                }
+                
+                // save the content
+                dispatcher.runSync("createCommContentDataResource", attachmentMap);                    
+            }
+        }
+    }
+    
     private static void createCommEventRoles(GenericValue userLogin, GenericDelegator delegator, LocalDispatcher dispatcher, String communicationEventId, List<Map<String, Object>> parties, String roleTypeId) {
         // It's not clear what the "role" of this communication event should be, so we'll just put _NA_
         // check and see if this role was already created and ignore if true