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