1   /**
2    * Copyright (c) 2000-2007 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.GetterUtil;
27  import com.liferay.portal.kernel.util.ParamUtil;
28  import com.liferay.portal.kernel.util.StringPool;
29  import com.liferay.portal.kernel.util.StringUtil;
30  import com.liferay.portal.struts.JSONAction;
31  import com.liferay.portal.theme.ThemeDisplay;
32  import com.liferay.portal.util.PortalUtil;
33  import com.liferay.portal.util.PrettyDateFormat;
34  import com.liferay.portal.util.WebKeys;
35  import com.liferay.portlet.mail.model.MailEnvelope;
36  import com.liferay.portlet.mail.model.MailFolder;
37  import com.liferay.portlet.mail.search.MailDisplayTerms;
38  import com.liferay.portlet.mail.util.MailUtil;
39  import com.liferay.portlet.mail.util.comparator.DateComparator;
40  import com.liferay.portlet.mail.util.comparator.RecipientComparator;
41  import com.liferay.portlet.mail.util.comparator.SizeComparator;
42  import com.liferay.portlet.mail.util.comparator.StateComparator;
43  import com.liferay.portlet.mail.util.comparator.SubjectComparator;
44  import com.liferay.portlet.mail.util.recipient.RecipientFinder;
45  import com.liferay.portlet.mail.util.recipient.RecipientFinderLocator;
46  import com.liferay.util.Autocomplete;
47  import com.liferay.util.ListUtil;
48  import com.liferay.util.TextFormatter;
49  
50  import java.util.Comparator;
51  import java.util.HashMap;
52  import java.util.Iterator;
53  import java.util.List;
54  import java.util.Set;
55  import java.util.SortedSet;
56  import java.util.TreeSet;
57  
58  import javax.portlet.PortletPreferences;
59  
60  import javax.servlet.http.HttpServletRequest;
61  import javax.servlet.http.HttpServletResponse;
62  import javax.servlet.http.HttpSession;
63  
64  import org.apache.commons.collections.map.MultiValueMap;
65  import org.apache.commons.lang.time.StopWatch;
66  import org.apache.commons.logging.Log;
67  import org.apache.commons.logging.LogFactory;
68  import org.apache.struts.action.ActionForm;
69  import org.apache.struts.action.ActionMapping;
70  
71  import org.json.JSONArray;
72  import org.json.JSONObject;
73  
74  /**
75   * <a href="MailAction.java.html"><b><i>View Source</i></b></a>
76   *
77   * @author Ming-Gih Lam
78   *
79   */
80  public class MailAction extends JSONAction {
81  
82      public String getJSON(
83              ActionMapping mapping, ActionForm form, HttpServletRequest req,
84              HttpServletResponse res)
85          throws Exception {
86  
87          String cmd = ParamUtil.getString(req, Constants.CMD);
88  
89          try {
90              if (cmd.equals("addFolder")) {
91                  addFolder(req);
92              }
93              else if (cmd.equals("deleteFolder")) {
94                  deleteFolder(req);
95              }
96              else if (cmd.equals("deleteMessages")) {
97                  deleteMessages(req);
98              }
99              else if (cmd.equals("emptyFolder")) {
100                 return emptyFolder(req);
101             }
102             else if (cmd.equals("getFolders")) {
103                 return getFolders(req);
104             }
105             else if (cmd.equals("getMessage")) {
106                 return getMessage(req);
107             }
108             else if (cmd.equals("getPreview")) {
109                 return getPreview(req);
110             }
111             else if (cmd.equals("getRecipients")) {
112                 return getRecipients(req);
113             }
114             else if (cmd.equals("getSearch")) {
115                 return getSearch(req);
116             }
117             else if (cmd.equals("getSearchCached")) {
118                 return getSearchCached(req);
119             }
120             else if (cmd.equals("moveMessages")) {
121                 moveMessages(req);
122             }
123             else if (cmd.equals("renameFolder")) {
124                 renameFolder(req);
125             }
126             else if (cmd.equals("updatePreferences")) {
127                 updatePreferences(req);
128             }
129         }
130         catch (Exception e) {
131             _log.error(e, e);
132         }
133 
134         return null;
135     }
136 
137     protected void addFolder(HttpServletRequest req) throws Exception {
138         String folderId = ParamUtil.getString(req, "folderId");
139 
140         MailUtil.createFolder(req, folderId);
141     }
142 
143     protected void deleteFolder(HttpServletRequest req) throws Exception {
144         String folderId = ParamUtil.getString(req, "folderId");
145 
146         MailUtil.removeFolder(req, folderId);
147     }
148 
149     protected void deleteMessages(HttpServletRequest req) throws Exception {
150         MultiValueMap messages = _convertMessages(req);
151 
152         MailUtil.deleteMessages(req, messages);
153     }
154 
155     protected String emptyFolder(HttpServletRequest req) throws Exception {
156         JSONObject jsonObj = new JSONObject();
157 
158         String folderId = ParamUtil.getString(req, "folderId");
159 
160         MailUtil.emptyFolder(req, folderId);
161 
162         jsonObj.put("folderId", folderId);
163 
164         return jsonObj.toString();
165     }
166 
167     protected Comparator getComparator(HttpServletRequest req)
168         throws Exception {
169 
170         String sortBy = ParamUtil.getString(req, "sortBy");
171         boolean asc = ParamUtil.getBoolean(req, "asc");
172 
173         Comparator comparator;
174 
175         if (sortBy.equals("state")) {
176             comparator = new StateComparator(asc);
177         }
178         else if (sortBy.equals("name")) {
179             comparator = new RecipientComparator(asc);
180         }
181         else if (sortBy.equals("subject")) {
182             comparator = new SubjectComparator(asc);
183         }
184         else if (sortBy.equals("size")) {
185             comparator = new SizeComparator(asc);
186         }
187         else {
188             comparator = new DateComparator(asc);
189         }
190 
191         return comparator;
192     }
193 
194     protected String getFolders(HttpServletRequest req) throws Exception {
195         JSONObject jsonObj = new JSONObject();
196 
197         _getFolders(req, jsonObj);
198 
199         return jsonObj.toString();
200     }
201 
202     protected String getMessage(HttpServletRequest req) throws Exception {
203         JSONObject jsonObj = new JSONObject();
204 
205         String folderId = ParamUtil.getString(req, "folderId");
206         long messageId = ParamUtil.getLong(req, "messageId");
207 
208         MailUtil.setFolder(req, folderId);
209 
210         MailUtil.setMessageId(req, messageId);
211 
212         jsonObj.put("id", messageId);
213         jsonObj.put("folderId", folderId);
214 
215         return jsonObj.toString();
216     }
217 
218     protected String getPreview(HttpServletRequest req) throws Exception {
219         StopWatch stopWatch = null;
220 
221         if (_log.isInfoEnabled()) {
222             stopWatch = new StopWatch();
223 
224             stopWatch.start();
225         }
226 
227         JSONObject jsonObj = new JSONObject();
228 
229         String folderId = ParamUtil.getString(req, "folderId");
230 
231         ThemeDisplay themeDisplay = (ThemeDisplay)req.getAttribute(
232             WebKeys.THEME_DISPLAY);
233 
234         MailUtil.setFolder(req, folderId);
235 
236         Set envelopes = MailUtil.getEnvelopes(req, getComparator(req));
237 
238         JSONArray jsonEnvelopes = _convertEnvelopes(envelopes, themeDisplay);
239 
240         jsonObj.put("folderId", folderId);
241         jsonObj.put("headers", jsonEnvelopes);
242 
243         if (_log.isInfoEnabled()) {
244             _log.info(
245                 "Total time to get preview " + stopWatch.getTime() + "ms");
246         }
247 
248         return jsonObj.toString();
249     }
250 
251     protected String getRecipients(HttpServletRequest req) throws Exception {
252         long userId = PortalUtil.getUserId(req);
253 
254         String data = ParamUtil.getString(req, "data");
255 
256         PortletPreferences prefs = PortalUtil.getPreferences(req);
257 
258         List finders = RecipientFinderLocator.getInstances();
259 
260         SortedSet recipients = new TreeSet();
261 
262         for (int i = 0; i < finders.size(); i++) {
263             RecipientFinder finder = (RecipientFinder)finders.get(i);
264 
265             boolean enabled =
266                 GetterUtil.getBoolean(
267                     prefs.getValue(
268                         finder.getClass().getName(), null),
269                     true);
270 
271             if (enabled) {
272                 recipients.addAll(
273                     finder.getRecipients(userId, data, new HashMap()));
274             }
275         }
276 
277         String[] recipientsArray = (String[])ListUtil.fromCollection(
278             recipients).toArray(new String[0]);
279 
280         JSONArray jsonArray = Autocomplete.arrayToJson(recipientsArray, 50);
281 
282         return jsonArray.toString();
283     }
284 
285     protected String getSearch(HttpServletRequest req) throws Exception {
286         JSONObject jsonObj = new JSONObject();
287 
288         HttpSession ses = req.getSession();
289 
290         MailDisplayTerms displayTerms = new MailDisplayTerms(req);
291 
292         ThemeDisplay themeDisplay = (ThemeDisplay)req.getAttribute(
293                 WebKeys.THEME_DISPLAY);
294 
295         Set envelopes = MailUtil.search(req, displayTerms, getComparator(req));
296 
297         ses.setAttribute(WebKeys.MAIL_SEARCH_RESULTS, envelopes);
298 
299         JSONArray jsonEnvelopes = _convertEnvelopes(envelopes, themeDisplay);
300 
301         jsonObj.put("headers", jsonEnvelopes);
302 
303         return jsonObj.toString();
304     }
305 
306     protected String getSearchCached(HttpServletRequest req) throws Exception {
307         JSONObject jsonObj = new JSONObject();
308 
309         HttpSession ses = req.getSession();
310 
311         ThemeDisplay themeDisplay = (ThemeDisplay)req.getAttribute(
312             WebKeys.THEME_DISPLAY);
313 
314         Set envelopes = new TreeSet(getComparator(req));
315 
316         envelopes.addAll((Set)ses.getAttribute(WebKeys.MAIL_SEARCH_RESULTS));
317 
318         ses.setAttribute(WebKeys.MAIL_SEARCH_RESULTS, envelopes);
319 
320         JSONArray jsonEnvelopes = _convertEnvelopes(envelopes, themeDisplay);
321 
322         jsonObj.put("headers", jsonEnvelopes);
323 
324         return jsonObj.toString();
325     }
326 
327     protected void moveMessages(HttpServletRequest req) throws Exception {
328         MultiValueMap messages = _convertMessages(req);
329 
330         String folderId = ParamUtil.getString(req, "folderId");
331 
332         MailUtil.moveMessages(req, messages, folderId);
333     }
334 
335     protected void renameFolder(HttpServletRequest req) throws Exception {
336         String folderId = ParamUtil.getString(req, "folderId");
337         String newFolderId = ParamUtil.getString(req, "newFolderId");
338 
339         MailUtil.renameFolder(req, folderId, newFolderId);
340     }
341 
342     protected void updatePreferences(HttpServletRequest req) throws Exception {
343         PortletPreferences prefs = PortalUtil.getPreferences(req);
344 
345         String[] keys = StringUtil.split(ParamUtil.getString(req, "key"));
346         String[] values = StringUtil.split(ParamUtil.getString(req, "value"));
347 
348         for (int i = 0; i < keys.length && i < values.length; i++) {
349             prefs.setValue(keys[i], values[i]);
350         }
351 
352         prefs.store();
353     }
354 
355     private JSONArray _convertEnvelopes(
356         Set envelopes, ThemeDisplay themeDisplay) {
357 
358         PrettyDateFormat dateFormat =
359             new PrettyDateFormat(themeDisplay.getCompanyId(),
360                 themeDisplay.getLocale(), themeDisplay.getTimeZone());
361 
362         JSONArray jsonEnvelopes = new JSONArray();
363 
364         Iterator itr = envelopes.iterator();
365 
366         while (itr.hasNext()) {
367             MailEnvelope mailEnvelope = (MailEnvelope)itr.next();
368 
369             JSONObject jsonEnvelope = new JSONObject();
370 
371             String recipient = GetterUtil.getString(
372                 mailEnvelope.getRecipient(), StringPool.NBSP);
373 
374             String subject = GetterUtil.getString(
375                 mailEnvelope.getSubject(), StringPool.NBSP);
376 
377             jsonEnvelope.put("id", mailEnvelope.getMessageId());
378             jsonEnvelope.put("folderId", mailEnvelope.getFolderName());
379             jsonEnvelope.put("email", recipient);
380             jsonEnvelope.put("subject", subject);
381             jsonEnvelope.put("date", dateFormat.format(mailEnvelope.getDate()));
382             jsonEnvelope.put(
383                 "size",
384                 TextFormatter.formatKB(
385                     mailEnvelope.getSize(), themeDisplay.getLocale()) + "k");
386             jsonEnvelope.put("read", mailEnvelope.isRead());
387             jsonEnvelope.put("replied", mailEnvelope.isAnswered());
388             jsonEnvelope.put("flagged", mailEnvelope.isFlagged());
389 
390             jsonEnvelopes.put(jsonEnvelope);
391         }
392 
393         return jsonEnvelopes;
394     }
395 
396     private MultiValueMap _convertMessages(HttpServletRequest req) {
397         String[] messagesArray = StringUtil.split(
398             ParamUtil.getString(req, "messages"), ",");
399 
400         MultiValueMap messages = new MultiValueMap();
401 
402         for (int i = 0; i < messagesArray.length; i += 2) {
403             messages.put(messagesArray[i], messagesArray[i+1]);
404         }
405         return messages;
406     }
407 
408     private void _getFolders(HttpServletRequest req, JSONObject jsonObj)
409         throws Exception {
410 
411         StopWatch stopWatch = null;
412 
413         if (_log.isInfoEnabled()) {
414             stopWatch = new StopWatch();
415 
416             stopWatch.start();
417         }
418 
419         JSONArray jsonFolders = new JSONArray();
420 
421         int count = 1;
422 
423         Iterator itr = MailUtil.getFolders(req).iterator();
424 
425         while (itr.hasNext()) {
426             MailFolder folder = (MailFolder)itr.next();
427 
428             JSONObject jsonFolder = new JSONObject();
429 
430             String name = folder.getName();
431 
432             jsonFolder.put("name", name);
433             jsonFolder.put("id", name);
434             jsonFolder.put("newCount", folder.getUnreadMessageCount());
435             jsonFolder.put("totalCount", folder.getMessageCount());
436 
437             if (name.equals(MailUtil.MAIL_INBOX_NAME)) {
438                 jsonFolders.put(0, jsonFolder);
439             }
440             else {
441                 jsonFolders.put(count++, jsonFolder);
442             }
443         }
444 
445         jsonObj.put("folders", jsonFolders);
446 
447         if (_log.isInfoEnabled()) {
448             _log.info(
449                 "Total time to get folders " + stopWatch.getTime() + "ms");
450         }
451     }
452 
453     private static Log _log = LogFactory.getLog(MailAction.class);
454 
455 }