1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portlet.announcements.service.impl;
16  
17  import com.liferay.portal.kernel.dao.orm.QueryUtil;
18  import com.liferay.portal.kernel.exception.PortalException;
19  import com.liferay.portal.kernel.exception.SystemException;
20  import com.liferay.portal.kernel.language.LanguageUtil;
21  import com.liferay.portal.kernel.log.Log;
22  import com.liferay.portal.kernel.log.LogFactoryUtil;
23  import com.liferay.portal.kernel.mail.MailMessage;
24  import com.liferay.portal.kernel.util.OrderByComparator;
25  import com.liferay.portal.kernel.util.StringUtil;
26  import com.liferay.portal.kernel.util.Time;
27  import com.liferay.portal.kernel.util.Validator;
28  import com.liferay.portal.model.Company;
29  import com.liferay.portal.model.Group;
30  import com.liferay.portal.model.Organization;
31  import com.liferay.portal.model.ResourceConstants;
32  import com.liferay.portal.model.Role;
33  import com.liferay.portal.model.User;
34  import com.liferay.portal.model.UserGroup;
35  import com.liferay.portal.util.ContentUtil;
36  import com.liferay.portal.util.PortalUtil;
37  import com.liferay.portal.util.PropsValues;
38  import com.liferay.portlet.announcements.EntryContentException;
39  import com.liferay.portlet.announcements.EntryDisplayDateException;
40  import com.liferay.portlet.announcements.EntryExpirationDateException;
41  import com.liferay.portlet.announcements.EntryTitleException;
42  import com.liferay.portlet.announcements.EntryURLException;
43  import com.liferay.portlet.announcements.model.AnnouncementsDelivery;
44  import com.liferay.portlet.announcements.model.AnnouncementsEntry;
45  import com.liferay.portlet.announcements.service.base.AnnouncementsEntryLocalServiceBaseImpl;
46  
47  import java.io.IOException;
48  
49  import java.util.ArrayList;
50  import java.util.Date;
51  import java.util.LinkedHashMap;
52  import java.util.List;
53  
54  import javax.mail.internet.InternetAddress;
55  
56  /**
57   * <a href="AnnouncementsEntryLocalServiceImpl.java.html"><b><i>View Source</i>
58   * </b></a>
59   *
60   * @author Brian Wing Shun Chan
61   * @author Raymond Augé
62   */
63  public class AnnouncementsEntryLocalServiceImpl
64      extends AnnouncementsEntryLocalServiceBaseImpl {
65  
66      public AnnouncementsEntry addEntry(
67              long userId, long classNameId, long classPK, String title,
68              String content, String url, String type, int displayDateMonth,
69              int displayDateDay, int displayDateYear, int displayDateHour,
70              int displayDateMinute, int expirationDateMonth,
71              int expirationDateDay, int expirationDateYear,
72              int expirationDateHour, int expirationDateMinute, int priority,
73              boolean alert)
74          throws PortalException, SystemException {
75  
76          // Entry
77  
78          User user = userPersistence.findByPrimaryKey(userId);
79  
80          Date displayDate = PortalUtil.getDate(
81              displayDateMonth, displayDateDay, displayDateYear, displayDateHour,
82              displayDateMinute, user.getTimeZone(),
83              new EntryDisplayDateException());
84  
85          Date expirationDate = PortalUtil.getDate(
86              expirationDateMonth, expirationDateDay, expirationDateYear,
87              expirationDateHour, expirationDateMinute, user.getTimeZone(),
88              new EntryExpirationDateException());
89  
90          Date now = new Date();
91  
92          validate(title, content, url);
93  
94          long entryId = counterLocalService.increment();
95  
96          AnnouncementsEntry entry = announcementsEntryPersistence.create(
97              entryId);
98  
99          entry.setCompanyId(user.getCompanyId());
100         entry.setUserId(user.getUserId());
101         entry.setUserName(user.getFullName());
102         entry.setCreateDate(now);
103         entry.setModifiedDate(now);
104         entry.setClassNameId(classNameId);
105         entry.setClassPK(classPK);
106         entry.setTitle(title);
107         entry.setContent(content);
108         entry.setUrl(url);
109         entry.setType(type);
110         entry.setDisplayDate(displayDate);
111         entry.setExpirationDate(expirationDate);
112         entry.setPriority(priority);
113         entry.setAlert(alert);
114 
115         announcementsEntryPersistence.update(entry, false);
116 
117         // Resources
118 
119         resourceLocalService.addResources(
120             user.getCompanyId(), 0, user.getUserId(),
121             AnnouncementsEntry.class.getName(), entry.getEntryId(), false,
122             false, false);
123 
124         return entry;
125     }
126 
127     public void checkEntries() throws PortalException, SystemException {
128         Date now = new Date();
129 
130         List<AnnouncementsEntry> entries =
131             announcementsEntryFinder.findByDisplayDate(
132                 now, new Date(now.getTime() - _entryCheckInterval));
133 
134         if (_log.isDebugEnabled()) {
135             _log.debug("Processing " + entries.size() + " entries");
136         }
137 
138         for (AnnouncementsEntry entry : entries) {
139             try {
140                 notifyUsers(entry);
141             }
142             catch (IOException ioe) {
143                 throw new SystemException(ioe);
144             }
145         }
146     }
147 
148     public void deleteEntry(AnnouncementsEntry entry)
149         throws PortalException, SystemException {
150 
151         // Entry
152 
153         announcementsEntryPersistence.remove(entry);
154 
155         // Resources
156 
157         resourceLocalService.deleteResource(
158             entry.getCompanyId(), AnnouncementsEntry.class.getName(),
159             ResourceConstants.SCOPE_INDIVIDUAL, entry.getEntryId());
160 
161         // Flags
162 
163         announcementsFlagLocalService.deleteFlags(entry.getEntryId());
164     }
165 
166     public void deleteEntry(long entryId)
167         throws PortalException, SystemException {
168 
169         AnnouncementsEntry entry =
170             announcementsEntryPersistence.findByPrimaryKey(entryId);
171 
172         deleteEntry(entry);
173     }
174 
175     public List<AnnouncementsEntry> getEntries(
176             long userId, LinkedHashMap<Long, long[]> scopes, boolean alert,
177             int flagValue, int start, int end)
178         throws SystemException {
179 
180         return getEntries(
181             userId, scopes, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, alert, flagValue,
182             start, end);
183     }
184 
185     public List<AnnouncementsEntry> getEntries(
186             long userId, LinkedHashMap<Long, long[]> scopes,
187             int displayDateMonth, int displayDateDay, int displayDateYear,
188             int displayDateHour, int displayDateMinute, int expirationDateMonth,
189             int expirationDateDay, int expirationDateYear,
190             int expirationDateHour, int expirationDateMinute, boolean alert,
191             int flagValue, int start, int end)
192         throws SystemException {
193 
194         return announcementsEntryFinder.findByScopes(
195             userId, scopes, displayDateMonth, displayDateDay, displayDateYear,
196             displayDateHour, displayDateMinute, expirationDateMonth,
197             expirationDateDay, expirationDateYear, expirationDateHour,
198             expirationDateMinute, alert, flagValue, start, end);
199     }
200 
201     public List<AnnouncementsEntry> getEntries(
202             long classNameId, long classPK, boolean alert, int start, int end)
203         throws SystemException {
204 
205         return announcementsEntryPersistence.findByC_C_A(
206             classNameId, classPK, alert, start, end);
207     }
208 
209     public List<AnnouncementsEntry> getEntries(
210             long userId, long classNameId, long[] classPKs,
211             int displayDateMonth, int displayDateDay, int displayDateYear,
212             int displayDateHour, int displayDateMinute, int expirationDateMonth,
213             int expirationDateDay, int expirationDateYear,
214             int expirationDateHour, int expirationDateMinute, boolean alert,
215             int flagValue, int start, int end)
216         throws SystemException {
217 
218         return announcementsEntryFinder.findByScope(
219             userId, classNameId, classPKs, displayDateMonth, displayDateDay,
220             displayDateYear, displayDateHour, displayDateMinute,
221             expirationDateMonth, expirationDateDay, expirationDateYear,
222             expirationDateHour, expirationDateMinute, alert, flagValue, start,
223             end);
224     }
225 
226     public int getEntriesCount(
227             long userId, LinkedHashMap<Long, long[]> scopes, boolean alert,
228             int flagValue)
229         throws SystemException {
230 
231         return getEntriesCount(
232             userId, scopes, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, alert, flagValue);
233     }
234 
235     public int getEntriesCount(
236             long userId, LinkedHashMap<Long, long[]> scopes,
237             int displayDateMonth, int displayDateDay, int displayDateYear,
238             int displayDateHour, int displayDateMinute, int expirationDateMonth,
239             int expirationDateDay, int expirationDateYear,
240             int expirationDateHour, int expirationDateMinute, boolean alert,
241             int flagValue)
242         throws SystemException {
243 
244         return announcementsEntryFinder.countByScopes(
245             userId, scopes, displayDateMonth, displayDateDay, displayDateYear,
246             displayDateHour, displayDateMinute, expirationDateMonth,
247             expirationDateDay, expirationDateYear, expirationDateHour,
248             expirationDateMinute, alert, flagValue);
249     }
250 
251     public int getEntriesCount(long classNameId, long classPK, boolean alert)
252         throws SystemException {
253 
254         return announcementsEntryPersistence.countByC_C_A(
255             classNameId, classPK, alert);
256     }
257 
258     public int getEntriesCount(
259             long userId, long classNameId, long[] classPKs, boolean alert,
260             int flagValue)
261         throws SystemException {
262 
263         return getEntriesCount(
264             userId, classNameId, classPKs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, alert,
265             flagValue);
266     }
267 
268     public int getEntriesCount(
269             long userId, long classNameId, long[] classPKs,
270             int displayDateMonth, int displayDateDay, int displayDateYear,
271             int displayDateHour, int displayDateMinute, int expirationDateMonth,
272             int expirationDateDay, int expirationDateYear,
273             int expirationDateHour, int expirationDateMinute, boolean alert,
274             int flagValue)
275         throws SystemException {
276 
277         return announcementsEntryFinder.countByScope(
278             userId, classNameId, classPKs, displayDateMonth, displayDateDay,
279             displayDateYear, displayDateHour, displayDateMinute,
280             expirationDateMonth, expirationDateDay, expirationDateYear,
281             expirationDateHour, expirationDateMinute, alert, flagValue);
282     }
283 
284     public AnnouncementsEntry getEntry(long entryId)
285         throws PortalException, SystemException {
286 
287         return announcementsEntryPersistence.findByPrimaryKey(entryId);
288     }
289 
290     public List<AnnouncementsEntry> getUserEntries(
291             long userId, int start, int end)
292         throws SystemException {
293 
294         return announcementsEntryPersistence.findByUserId(userId, start, end);
295     }
296 
297     public int getUserEntriesCount(long userId) throws SystemException {
298         return announcementsEntryPersistence.countByUserId(userId);
299     }
300 
301     public AnnouncementsEntry updateEntry(
302             long userId, long entryId, String title, String content, String url,
303             String type, int displayDateMonth, int displayDateDay,
304             int displayDateYear, int displayDateHour, int displayDateMinute,
305             int expirationDateMonth, int expirationDateDay,
306             int expirationDateYear, int expirationDateHour,
307             int expirationDateMinute, int priority)
308         throws PortalException, SystemException {
309 
310         // Entry
311 
312         User user = userPersistence.findByPrimaryKey(userId);
313 
314         Date displayDate = PortalUtil.getDate(
315             displayDateMonth, displayDateDay, displayDateYear, displayDateHour,
316             displayDateMinute, user.getTimeZone(),
317             new EntryDisplayDateException());
318 
319         Date expirationDate = PortalUtil.getDate(
320             expirationDateMonth, expirationDateDay, expirationDateYear,
321             expirationDateHour, expirationDateMinute, user.getTimeZone(),
322             new EntryExpirationDateException());
323 
324         validate(title, content, url);
325 
326         AnnouncementsEntry entry =
327             announcementsEntryPersistence.findByPrimaryKey(entryId);
328 
329         entry.setModifiedDate(new Date());
330         entry.setTitle(title);
331         entry.setContent(content);
332         entry.setUrl(url);
333         entry.setType(type);
334         entry.setDisplayDate(displayDate);
335         entry.setExpirationDate(expirationDate);
336         entry.setPriority(priority);
337 
338         announcementsEntryPersistence.update(entry, false);
339 
340         // Flags
341 
342         announcementsFlagLocalService.deleteFlags(entry.getEntryId());
343 
344         return entry;
345     }
346 
347     protected void notifyUsers(AnnouncementsEntry entry)
348         throws IOException, PortalException, SystemException {
349 
350         Company company = companyPersistence.findByPrimaryKey(
351             entry.getCompanyId());
352 
353         String className = entry.getClassName();
354         long classPK = entry.getClassPK();
355 
356         String fromName = PropsValues.ANNOUNCEMENTS_EMAIL_FROM_NAME;
357         String fromAddress = PropsValues.ANNOUNCEMENTS_EMAIL_FROM_ADDRESS;
358 
359         String toName = PropsValues.ANNOUNCEMENTS_EMAIL_TO_NAME;
360         String toAddress = PropsValues.ANNOUNCEMENTS_EMAIL_TO_ADDRESS;
361 
362         LinkedHashMap<String, Object> params =
363             new LinkedHashMap<String, Object>();
364 
365         params.put("announcementsDeliveryEmailOrSms", entry.getType());
366 
367         if (classPK > 0) {
368             if (className.equals(Group.class.getName())) {
369                 Group group = groupPersistence.findByPrimaryKey(classPK);
370 
371                 toName = group.getName();
372 
373                 params.put("usersGroups", classPK);
374             }
375             else if (className.equals(Organization.class.getName())) {
376                 Organization organization =
377                     organizationPersistence.findByPrimaryKey(classPK);
378 
379                 toName = organization.getName();
380 
381                 params.put("usersOrgs", classPK);
382             }
383             else if (className.equals(Role.class.getName())) {
384                 Role role = rolePersistence.findByPrimaryKey(classPK);
385 
386                 toName = role.getName();
387 
388                 params.put("usersRoles", classPK);
389             }
390             else if (className.equals(UserGroup.class.getName())) {
391                 UserGroup userGroup = userGroupPersistence.findByPrimaryKey(
392                     classPK);
393 
394                 toName = userGroup.getName();
395 
396                 params.put("usersUserGroups", classPK);
397             }
398         }
399 
400         List<User> users = null;
401 
402         if (className.equals(User.class.getName())) {
403             User user = userLocalService.getUserById(classPK);
404 
405             toName = user.getFullName();
406             toAddress = user.getEmailAddress();
407 
408             users = new ArrayList<User>();
409 
410             if (Validator.isNotNull(toAddress)) {
411                 users.add(user);
412             }
413         }
414         else {
415             users = userLocalService.search(
416                 company.getCompanyId(), null, Boolean.TRUE, params,
417                 QueryUtil.ALL_POS, QueryUtil.ALL_POS, (OrderByComparator)null);
418         }
419 
420         if (_log.isDebugEnabled()) {
421             _log.debug("Notifying " + users.size() + " users");
422         }
423 
424         List<InternetAddress> bulkAddresses = new ArrayList<InternetAddress>();
425 
426         for (User user : users) {
427             AnnouncementsDelivery announcementsDelivery =
428                 announcementsDeliveryLocalService.getUserDelivery(
429                     user.getUserId(), entry.getType());
430 
431             if (announcementsDelivery.isEmail()) {
432                 InternetAddress address = new InternetAddress(
433                     user.getEmailAddress(), user.getFullName());
434 
435                 bulkAddresses.add(address);
436             }
437 
438             if (announcementsDelivery.isSms()) {
439                 String smsSn = user.getContact().getSmsSn();
440 
441                 InternetAddress address = new InternetAddress(
442                     smsSn, user.getFullName());
443 
444                 bulkAddresses.add(address);
445             }
446         }
447 
448         if (bulkAddresses.size() == 0) {
449             return;
450         }
451 
452         String subject = ContentUtil.get(
453             PropsValues.ANNOUNCEMENTS_EMAIL_SUBJECT);
454         String body = ContentUtil.get(PropsValues.ANNOUNCEMENTS_EMAIL_BODY);
455 
456         subject = StringUtil.replace(
457             subject,
458             new String[] {
459                 "[$ENTRY_CONTENT$]",
460                 "[$ENTRY_ID$]",
461                 "[$ENTRY_TITLE$]",
462                 "[$ENTRY_TYPE$]",
463                 "[$ENTRY_URL$]",
464                 "[$FROM_ADDRESS$]",
465                 "[$FROM_NAME$]",
466                 "[$PORTAL_URL$]",
467                 "[$PORTLET_NAME$]",
468                 "[$TO_ADDRESS$]",
469                 "[$TO_NAME$]"
470             },
471             new String[] {
472                 entry.getContent(),
473                 String.valueOf(entry.getEntryId()),
474                 entry.getTitle(),
475                 LanguageUtil.get(company.getLocale(), entry.getType()),
476                 entry.getUrl(),
477                 fromAddress,
478                 fromName,
479                 company.getVirtualHost(),
480                 LanguageUtil.get(
481                     company.getLocale(),
482                     (entry.isAlert() ? "alert" : "announcement")),
483                 toAddress,
484                 toName
485             });
486 
487         body = StringUtil.replace(
488             body,
489             new String[] {
490                 "[$ENTRY_CONTENT$]",
491                 "[$ENTRY_ID$]",
492                 "[$ENTRY_TITLE$]",
493                 "[$ENTRY_TYPE$]",
494                 "[$ENTRY_URL$]",
495                 "[$FROM_ADDRESS$]",
496                 "[$FROM_NAME$]",
497                 "[$PORTAL_URL$]",
498                 "[$PORTLET_NAME$]",
499                 "[$TO_ADDRESS$]",
500                 "[$TO_NAME$]"
501             },
502             new String[] {
503                 entry.getContent(),
504                 String.valueOf(entry.getEntryId()),
505                 entry.getTitle(),
506                 LanguageUtil.get(company.getLocale(), entry.getType()),
507                 entry.getUrl(),
508                 fromAddress,
509                 fromName,
510                 company.getVirtualHost(),
511                 LanguageUtil.get(
512                     company.getLocale(),
513                     (entry.isAlert() ? "alert" : "announcement")),
514                 toAddress,
515                 toName
516             });
517 
518         InternetAddress from = new InternetAddress(fromAddress, fromName);
519 
520         InternetAddress to = new InternetAddress(toAddress, toName);
521 
522         InternetAddress[] bulkAddressesArray = bulkAddresses.toArray(
523             new InternetAddress[bulkAddresses.size()]);
524 
525         MailMessage message = new MailMessage(
526             from, to, subject, body, true);
527 
528         message.setBulkAddresses(bulkAddressesArray);
529 
530         mailService.sendEmail(message);
531     }
532 
533     protected void validate(String title, String content, String url)
534         throws PortalException {
535 
536         if (Validator.isNull(title)) {
537             throw new EntryTitleException();
538         }
539 
540         if (Validator.isNull(content)) {
541             throw new EntryContentException();
542         }
543 
544         if (!Validator.isUrl(url)) {
545             throw new EntryURLException();
546         }
547     }
548 
549     private static Log _log = LogFactoryUtil.getLog(
550         AnnouncementsEntryLocalServiceImpl.class);
551 
552     private long _entryCheckInterval =
553         PropsValues.ANNOUNCEMENTS_ENTRY_CHECK_INTERVAL * Time.MINUTE;
554 
555 }