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