1   /**
2    * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portlet.mail.action;
24  
25  import com.liferay.portal.kernel.util.Constants;
26  import com.liferay.portal.kernel.util.HtmlUtil;
27  import com.liferay.portal.kernel.util.ParamUtil;
28  import com.liferay.portal.kernel.util.StringMaker;
29  import com.liferay.portal.kernel.util.StringPool;
30  import com.liferay.portal.kernel.util.StringUtil;
31  import com.liferay.portal.kernel.util.Validator;
32  import com.liferay.portal.model.User;
33  import com.liferay.portal.struts.PortletAction;
34  import com.liferay.portal.theme.ThemeDisplay;
35  import com.liferay.portal.util.ContentTypeUtil;
36  import com.liferay.portal.util.DateFormats;
37  import com.liferay.portal.util.PortalUtil;
38  import com.liferay.portal.util.UploadRequestUtil;
39  import com.liferay.portal.util.WebKeys;
40  import com.liferay.portlet.mail.RecipientException;
41  import com.liferay.portlet.mail.model.MailAttachment;
42  import com.liferay.portlet.mail.model.MailMessage;
43  import com.liferay.portlet.mail.model.RemoteMailAttachment;
44  import com.liferay.portlet.mail.util.MailUtil;
45  import com.liferay.portlet.mail.util.multiaccount.MailAccount;
46  import com.liferay.portlet.mail.util.multiaccount.MailAccounts;
47  import com.liferay.util.FileUtil;
48  import com.liferay.util.mail.InternetAddressUtil;
49  import com.liferay.util.servlet.SessionErrors;
50  import com.liferay.util.servlet.UploadPortletRequest;
51  
52  import java.io.File;
53  
54  import java.text.DateFormat;
55  
56  import java.util.ArrayList;
57  import java.util.Enumeration;
58  import java.util.HashMap;
59  import java.util.Iterator;
60  import java.util.List;
61  import java.util.Map;
62  
63  import javax.mail.internet.InternetAddress;
64  
65  import javax.portlet.ActionRequest;
66  import javax.portlet.ActionResponse;
67  import javax.portlet.PortletConfig;
68  import javax.portlet.PortletPreferences;
69  import javax.portlet.PortletRequest;
70  import javax.portlet.RenderRequest;
71  import javax.portlet.RenderResponse;
72  
73  import javax.servlet.http.HttpServletRequest;
74  
75  import org.apache.struts.action.ActionForm;
76  import org.apache.struts.action.ActionForward;
77  import org.apache.struts.action.ActionMapping;
78  
79  /**
80   * <a href="EditMessageAction.java.html"><b><i>View Source</i></b></a>
81   *
82   * @author Ming-Gih Lam
83   * @author  Alexander Chow
84   *
85   */
86  public class EditMessageAction extends PortletAction {
87  
88      public void processAction(
89              ActionMapping mapping, ActionForm form, PortletConfig config,
90              ActionRequest req, ActionResponse res)
91          throws Exception {
92  
93          try {
94              completeMessage(req);
95  
96              sendRedirect(req, res);
97          }
98          catch (Exception e) {
99              if (e instanceof RecipientException) {
100                 SessionErrors.add(req, e.getClass().getName());
101             }
102             else {
103                 throw e;
104             }
105         }
106     }
107 
108     public ActionForward render(
109             ActionMapping mapping, ActionForm form, PortletConfig config,
110             RenderRequest req, RenderResponse res)
111         throws Exception {
112 
113         HttpServletRequest httpReq = PortalUtil.getHttpServletRequest(req);
114 
115         String cmd = ParamUtil.getString(req, Constants.CMD);
116 
117         PortletPreferences prefs = req.getPreferences();
118 
119         String folderId = ParamUtil.getString(req, "folderId");
120         long messageId = ParamUtil.getLong(req, "messageId");
121 
122         String signature = prefs.getValue("signature", StringPool.BLANK);
123 
124         if (Validator.isNotNull(signature)) {
125             signature = "<br />--<br />" + signature;
126         }
127 
128         if (cmd.equals("forward") || cmd.startsWith("reply")) {
129             MailUtil.setFolder(httpReq, folderId);
130 
131             MailMessage mailMessage = MailUtil.getMessage(httpReq, messageId);
132 
133             if (cmd.equals("forward")) {
134                 req.setAttribute(
135                     WebKeys.MAIL_MESSAGE_SUBJECT,
136                     "Fw: " + getSubject(mailMessage.getSubject(), "fw"));
137                 req.setAttribute(
138                     WebKeys.MAIL_MESSAGE_ATTACHMENTS,
139                     mailMessage.getRemoteAttachments());
140             }
141             else {
142                 String to = StringPool.BLANK;
143                 String cc = StringPool.BLANK;
144 
145                 if (cmd.equals("replyAll")) {
146                     User user = PortalUtil.getUser(req);
147 
148                     String emailAddress = user.getEmailAddress();
149 
150                     to = InternetAddressUtil.toString(
151                         InternetAddressUtil.removeEntry(
152                             mailMessage.getTo(), emailAddress));
153 
154                     cc = InternetAddressUtil.toString(
155                         InternetAddressUtil.removeEntry(
156                             mailMessage.getCc(), emailAddress));
157 
158                     String replyTo = InternetAddressUtil.toString(
159                         mailMessage.getReplyTo());
160 
161                     if (Validator.isNull(replyTo)) {
162                         InternetAddress from =
163                             (InternetAddress)mailMessage.getFrom();
164 
165                         replyTo = from.toUnicodeString();
166                     }
167 
168                     to = replyTo + StringPool.COMMA + StringPool.SPACE + to;
169                 }
170                 else {
171                     to = InternetAddressUtil.toString(
172                         mailMessage.getReplyTo());
173 
174                     if (Validator.isNull(to)) {
175                         InternetAddress from =
176                             (InternetAddress)mailMessage.getFrom();
177 
178                         to = from.toUnicodeString();
179                     }
180                 }
181 
182                 String[] recipients = new String[] {
183                     HtmlUtil.escape(to), HtmlUtil.escape(cc), StringPool.BLANK
184                 };
185 
186                 req.setAttribute(WebKeys.MAIL_MESSAGE_ORIGINAL_ID,
187                     String.valueOf(mailMessage.getMessageId()));
188                 req.setAttribute(WebKeys.MAIL_MESSAGE_RECIPIENTS, recipients);
189                 req.setAttribute(
190                     WebKeys.MAIL_MESSAGE_IN_REPLY_TO,
191                     String.valueOf(mailMessage.getInReplyTo()));
192                 req.setAttribute(
193                     WebKeys.MAIL_MESSAGE_REFERENCES,
194                     String.valueOf(mailMessage.getReferences()));
195                 req.setAttribute(
196                     WebKeys.MAIL_MESSAGE_SUBJECT,
197                     "Re: " + getSubject(mailMessage.getSubject(), "re"));
198             }
199 
200             req.setAttribute(
201                 WebKeys.MAIL_MESSAGE_BODY,
202                 signature + getBody(req, mailMessage));
203         }
204         else if (cmd.equals(Constants.EDIT)) {
205             MailUtil.setFolder(httpReq, folderId);
206 
207             MailMessage mailMessage = MailUtil.getMessage(httpReq, messageId);
208 
209             String to = HtmlUtil.escape(
210                 InternetAddressUtil.toString(mailMessage.getTo()));
211             String cc = HtmlUtil.escape(
212                 InternetAddressUtil.toString(mailMessage.getCc()));
213             String bcc = HtmlUtil.escape(
214                 InternetAddressUtil.toString(mailMessage.getBcc()));
215 
216             String[] recipients = new String[] {to, cc, bcc};
217 
218             req.setAttribute(
219                 WebKeys.MAIL_MESSAGE_ORIGINAL_ID,
220                 new String(_DRAFT_ID_PREFIX + messageId));
221             req.setAttribute(WebKeys.MAIL_MESSAGE_RECIPIENTS, recipients);
222             req.setAttribute(
223                 WebKeys.MAIL_MESSAGE_SUBJECT, mailMessage.getSubject());
224             req.setAttribute(
225                 WebKeys.MAIL_MESSAGE_BODY, mailMessage.getBody());
226             req.setAttribute(
227                 WebKeys.MAIL_MESSAGE_ATTACHMENTS,
228                 mailMessage.getRemoteAttachments());
229         }
230         else if (cmd.equals(Constants.SEND)) {
231             String originalId = ParamUtil.getString(req, "originalId");
232 
233             String to = ParamUtil.getString(req, "to");
234             String cc = ParamUtil.getString(req, "cc");
235             String bcc = ParamUtil.getString(req, "bcc");
236 
237             String[] recipients = new String[] {to, cc, bcc};
238 
239             String subject = ParamUtil.getString(req, "subject");
240             String body = ParamUtil.getString(req, "body");
241 
242             req.setAttribute(WebKeys.MAIL_MESSAGE_ORIGINAL_ID, originalId);
243             req.setAttribute(WebKeys.MAIL_MESSAGE_RECIPIENTS, recipients);
244             req.setAttribute(WebKeys.MAIL_MESSAGE_SUBJECT, subject);
245             req.setAttribute(WebKeys.MAIL_MESSAGE_BODY, body);
246             req.setAttribute(
247                 WebKeys.MAIL_MESSAGE_ATTACHMENTS, getRemoteAttachments(req));
248         }
249         else {
250             String to = ParamUtil.getString(req, "to");
251 
252             String[] recipients =
253                 new String[] {to, StringPool.BLANK, StringPool.BLANK};
254 
255             req.setAttribute(WebKeys.MAIL_MESSAGE_RECIPIENTS, recipients);
256             req.setAttribute(WebKeys.MAIL_MESSAGE_BODY, signature);
257         }
258 
259         return mapping.findForward("portlet.mail.edit_message");
260     }
261 
262     protected void completeMessage(ActionRequest req)
263         throws Exception {
264 
265         String cmd = ParamUtil.getString(req, Constants.CMD);
266 
267         User user = PortalUtil.getUser(req);
268 
269         String originalId = ParamUtil.getString(req, "originalId");
270 
271         boolean wasDraft = false;
272 
273         if (originalId.startsWith(_DRAFT_ID_PREFIX)) {
274             wasDraft = true;
275 
276             originalId = originalId.substring(_DRAFT_ID_PREFIX.length());
277         }
278 
279         String to = ParamUtil.getString(req, "to");
280         String cc = ParamUtil.getString(req, "cc");
281         String bcc = ParamUtil.getString(req, "bcc");
282         String inReplyTo = ParamUtil.getString(req, "inReplyTo");
283         String references = ParamUtil.getString(req, "references");
284         String subject = ParamUtil.getString(req, "subject");
285         String body = ParamUtil.getString(req, "body");
286 
287         MailMessage mailMessage = new MailMessage();
288 
289         try {
290             MailAccount account = MailAccounts.getCurrentAccount(req);
291 
292             mailMessage.setFrom(new InternetAddress(
293                 account.getEmailAddress(), user.getFullName()));
294             mailMessage.setTo(to);
295             mailMessage.setCc(cc);
296             mailMessage.setBcc(bcc);
297             mailMessage.setInReplyTo(inReplyTo);
298             mailMessage.setReferences(references);
299         }
300         catch (Exception ex) {
301             throw new RecipientException(ex);
302         }
303 
304         mailMessage.setSubject(subject);
305         mailMessage.setBody(body);
306 
307         Iterator itr = getAttachments(req).entrySet().iterator();
308 
309         while (itr.hasNext()) {
310             Map.Entry entry = (Map.Entry)itr.next();
311 
312             String fileName = (String)entry.getKey();
313             byte[] attachment = (byte[])entry.getValue();
314 
315             MailAttachment mailAttachment = new MailAttachment();
316 
317             mailAttachment.setFilename(fileName);
318             mailAttachment.setContent(attachment);
319             mailAttachment.setContentType(
320                 ContentTypeUtil.getContentType(fileName));
321 
322             mailMessage.appendAttachment(mailAttachment);
323         }
324 
325         mailMessage.setRemoteAttachments(getRemoteAttachments(req));
326 
327         boolean send = cmd.equals(Constants.SEND);
328 
329         HttpServletRequest httpReq = PortalUtil.getHttpServletRequest(req);
330 
331         MailUtil.completeMessage(
332             httpReq, mailMessage, send, originalId, wasDraft);
333     }
334 
335     protected Map getAttachments(ActionRequest req) throws Exception {
336         UploadPortletRequest uploadReq =
337             UploadRequestUtil.getUploadPortletRequest(req);
338 
339         Map attachments = new HashMap();
340 
341         Enumeration enu = uploadReq.getParameterNames();
342 
343         while (enu.hasMoreElements()) {
344             String name = (String)enu.nextElement();
345 
346             if (name.startsWith("attachment")) {
347                 File file = uploadReq.getFile(name);
348                 String fileName = uploadReq.getFileName(name);
349                 byte[] bytes = FileUtil.getBytes(file);
350 
351                 if ((bytes != null) && (bytes.length > 0)) {
352                     attachments.put(fileName, bytes);
353                 }
354             }
355         }
356 
357         return attachments;
358     }
359 
360     protected String getBody(RenderRequest req, MailMessage mailMessage)
361         throws Exception {
362 
363         StringMaker sm = new StringMaker();
364 
365         InternetAddress from = (InternetAddress)mailMessage.getFrom();
366 
367         ThemeDisplay themeDisplay = (ThemeDisplay)req.getAttribute(
368             WebKeys.THEME_DISPLAY);
369 
370         DateFormat dateFormatDateTime = DateFormats.getDateTime(
371             themeDisplay.getLocale(), themeDisplay.getTimeZone());
372 
373         sm.append("<br /><br />");
374         sm.append("On " + dateFormatDateTime.format(mailMessage.getSentDate()));
375         sm.append(StringPool.COMMA + StringPool.NBSP + from.getPersonal());
376         sm.append(" &lt;<a href=\"mailto: " + from.getAddress() + "\">");
377         sm.append(from.getAddress() + "</a>&gt; wrote:<br />");
378         sm.append("<div style=\"");
379         sm.append("border-left: 1px solid rgb(204, 204, 204); ");
380         sm.append("margin: 0pt 0pt 0pt 1ex; ");
381         sm.append("padding-left: 1ex; \">");
382         sm.append(mailMessage.getBody());
383         sm.append("</div>");
384 
385         return sm.toString();
386     }
387 
388     protected List getRemoteAttachments(PortletRequest req)
389         throws Exception {
390 
391         List list = new ArrayList();
392 
393         String prefix = "remoteAttachment";
394 
395         Enumeration enu = req.getParameterNames();
396 
397         while (enu.hasMoreElements()) {
398             String name = (String)enu.nextElement();
399 
400             if (name.startsWith(prefix)) {
401                 String fileName = name.substring(prefix.length());
402                 String contentPath = ParamUtil.getString(req, name);
403 
404                 RemoteMailAttachment remoteMailAttachment =
405                     new RemoteMailAttachment();
406 
407                 remoteMailAttachment.setFilename(fileName);
408                 remoteMailAttachment.setContentPath(contentPath);
409 
410                 list.add(remoteMailAttachment);
411             }
412         }
413 
414         return list;
415     }
416 
417     protected String getSubject(String subject, String prefix)
418         throws Exception {
419 
420         if (Validator.isNotNull(subject)) {
421             while (StringUtil.startsWith(subject, prefix + ":") ||
422                    StringUtil.startsWith(subject, prefix + ">")) {
423 
424                 subject = subject.substring(3).trim();
425             }
426         }
427 
428         return subject;
429     }
430 
431     private String _DRAFT_ID_PREFIX = "draft.";
432 
433 }