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.announcements.service.impl;
24  
25  import com.liferay.portal.PortalException;
26  import com.liferay.portal.SystemException;
27  import com.liferay.portal.kernel.language.LanguageUtil;
28  import com.liferay.portal.kernel.mail.MailMessage;
29  import com.liferay.portal.kernel.util.StringUtil;
30  import com.liferay.portal.kernel.util.Validator;
31  import com.liferay.portal.model.Company;
32  import com.liferay.portal.model.Group;
33  import com.liferay.portal.model.Organization;
34  import com.liferay.portal.model.Role;
35  import com.liferay.portal.model.User;
36  import com.liferay.portal.model.UserGroup;
37  import com.liferay.portal.util.ContentUtil;
38  import com.liferay.portal.util.PortalUtil;
39  import com.liferay.portal.util.PropsValues;
40  import com.liferay.portlet.announcements.EntryContentException;
41  import com.liferay.portlet.announcements.EntryDisplayDateException;
42  import com.liferay.portlet.announcements.EntryExpirationDateException;
43  import com.liferay.portlet.announcements.EntryTitleException;
44  import com.liferay.portlet.announcements.job.CheckEntryJob;
45  import com.liferay.portlet.announcements.model.AnnouncementsDelivery;
46  import com.liferay.portlet.announcements.model.AnnouncementsEntry;
47  import com.liferay.portlet.announcements.service.base.AnnouncementsEntryLocalServiceBaseImpl;
48  import com.liferay.util.dao.hibernate.QueryUtil;
49  
50  import java.io.IOException;
51  
52  import java.util.ArrayList;
53  import java.util.Date;
54  import java.util.LinkedHashMap;
55  import java.util.List;
56  
57  import javax.mail.internet.InternetAddress;
58  
59  import org.apache.commons.logging.Log;
60  import org.apache.commons.logging.LogFactory;
61  
62  /**
63   * <a href="AnnouncementsEntryLocalServiceImpl.java.html"><b><i>View Source</i>
64   * </b></a>
65   *
66   * @author Brian Wing Shun Chan
67   * @author Raymond Augé
68   *
69   */
70  public class AnnouncementsEntryLocalServiceImpl
71      extends AnnouncementsEntryLocalServiceBaseImpl {
72  
73      public AnnouncementsEntry addEntry(
74              long userId, long classNameId, long classPK, String title,
75              String content, String url, String type, int displayDateMonth,
76              int displayDateDay, int displayDateYear, int displayDateHour,
77              int displayDateMinute, int expirationDateMonth,
78              int expirationDateDay, int expirationDateYear,
79              int expirationDateHour, int expirationDateMinute, int priority,
80              boolean alert)
81          throws PortalException, SystemException {
82  
83          // Entry
84  
85          User user = userPersistence.findByPrimaryKey(userId);
86  
87          Date displayDate = PortalUtil.getDate(
88              displayDateMonth, displayDateDay, displayDateYear, displayDateHour,
89              displayDateMinute, new EntryDisplayDateException());
90  
91          Date expirationDate = PortalUtil.getDate(
92              expirationDateMonth, expirationDateDay, expirationDateYear,
93              expirationDateHour, expirationDateMinute,
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 begin, int end)
174         throws PortalException, SystemException {
175 
176         return announcementsEntryPersistence.findByC_C_A(
177             classNameId, classPK, alert, begin, 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 begin, int end)
187         throws PortalException, 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, begin,
194             end);
195     }
196 
197     public List<AnnouncementsEntry> getEntries(
198             long userId, LinkedHashMap<Long, long[]> scopes, boolean alert,
199             int flagValue, int begin, int end)
200         throws PortalException, SystemException {
201 
202         return getEntries(
203             userId, scopes, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, alert, flagValue,
204             begin, 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 begin, int end)
214         throws PortalException, SystemException {
215 
216         return announcementsEntryFinder.findByScopes(
217             userId, scopes, displayDateMonth, displayDateDay, displayDateYear,
218             displayDateHour, displayDateMinute, expirationDateMonth,
219             expirationDateDay, expirationDateYear, expirationDateHour,
220             expirationDateMinute, alert, flagValue, begin, end);
221     }
222 
223     public int getEntriesCount(long classNameId, long classPK, boolean alert)
224         throws PortalException, 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 PortalException, 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 PortalException, 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 PortalException, 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 PortalException, 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 begin, int end)
283         throws SystemException {
284 
285         return announcementsEntryPersistence.findByUserId(userId, begin, end);
286     }
287 
288     public int getUserEntriesCount(long userId) throws SystemException {
289         return announcementsEntryPersistence.countByUserId(userId);
290     }
291 
292     public AnnouncementsEntry updateEntry(
293             long entryId, String title, String content, String url, String type,
294             int displayDateMonth, int displayDateDay, int displayDateYear,
295             int displayDateHour, int displayDateMinute, int expirationDateMonth,
296             int expirationDateDay, int expirationDateYear,
297             int expirationDateHour, int expirationDateMinute,
298             int priority)
299         throws PortalException, SystemException {
300 
301         // Entry
302 
303         validate(title, content);
304 
305         Date displayDate = PortalUtil.getDate(
306             displayDateMonth, displayDateDay, displayDateYear, displayDateHour,
307             displayDateMinute, new EntryDisplayDateException());
308 
309         Date expirationDate = PortalUtil.getDate(
310             expirationDateMonth, expirationDateDay, expirationDateYear,
311             expirationDateHour, expirationDateMinute,
312             new EntryExpirationDateException());
313 
314         AnnouncementsEntry entry =
315             announcementsEntryPersistence.findByPrimaryKey(entryId);
316 
317         entry.setModifiedDate(new Date());
318         entry.setTitle(title);
319         entry.setContent(content);
320         entry.setUrl(url);
321         entry.setType(type);
322         entry.setDisplayDate(displayDate);
323         entry.setExpirationDate(expirationDate);
324         entry.setPriority(priority);
325 
326         announcementsEntryPersistence.update(entry, false);
327 
328         // Flags
329 
330         announcementsFlagLocalService.deleteFlags(entry.getEntryId());
331 
332         return entry;
333     }
334 
335     protected void notifyUsers(AnnouncementsEntry entry)
336         throws IOException, PortalException, SystemException {
337 
338         Company company = companyPersistence.findByPrimaryKey(
339             entry.getCompanyId());
340 
341         String className = entry.getClassName();
342         long classPK = entry.getClassPK();
343 
344         String fromName = PropsValues.ANNOUNCEMENTS_EMAIL_FROM_NAME;
345         String fromAddress = PropsValues.ANNOUNCEMENTS_EMAIL_FROM_ADDRESS;
346 
347         String toName = PropsValues.ANNOUNCEMENTS_EMAIL_TO_NAME;
348         String toAddress = PropsValues.ANNOUNCEMENTS_EMAIL_TO_ADDRESS;
349 
350         LinkedHashMap<String, Object> params =
351             new LinkedHashMap<String, Object>();
352 
353         params.put("announcementsDeliveryEmailOrSms", entry.getType());
354 
355         if (classPK > 0) {
356             if (className.equals(Group.class.getName())) {
357                 Group group = groupPersistence.findByPrimaryKey(classPK);
358 
359                 toName = group.getName();
360 
361                 params.put("usersGroups", classPK);
362             }
363             else if (className.equals(Organization.class.getName())) {
364                 Organization organization =
365                     organizationPersistence.findByPrimaryKey(classPK);
366 
367                 toName = organization.getName();
368 
369                 params.put("usersOrgs", classPK);
370             }
371             else if (className.equals(Role.class.getName())) {
372                 Role role = rolePersistence.findByPrimaryKey(classPK);
373 
374                 toName = role.getName();
375 
376                 params.put("usersRoles", classPK);
377             }
378             else if (className.equals(UserGroup.class.getName())) {
379                 UserGroup userGroup = userGroupPersistence.findByPrimaryKey(
380                     classPK);
381 
382                 toName = userGroup.getName();
383 
384                 params.put("usersUserGroups", classPK);
385             }
386         }
387 
388         List<User> users = null;
389 
390         if (className.equals(User.class.getName())) {
391             User user = userLocalService.getUserById(classPK);
392 
393             toName = user.getFullName();
394             toAddress = user.getEmailAddress();
395 
396             users = new ArrayList<User>();
397 
398             users.add(user);
399         }
400         else {
401             users = userLocalService.search(
402                 company.getCompanyId(), null, Boolean.TRUE, params,
403                 QueryUtil.ALL_POS, QueryUtil.ALL_POS, null);
404         }
405 
406         if (_log.isDebugEnabled()) {
407             _log.debug("Notifying " + users.size() + " users");
408         }
409 
410         List<InternetAddress> bulkAddresses = new ArrayList<InternetAddress>();
411 
412         for (User user : users) {
413             AnnouncementsDelivery announcementsDelivery =
414                 announcementsDeliveryLocalService.getUserDelivery(
415                     user.getUserId(), entry.getType());
416 
417             if (announcementsDelivery.isEmail()) {
418                 InternetAddress address = new InternetAddress(
419                     user.getEmailAddress(), user.getFullName());
420 
421                 bulkAddresses.add(address);
422             }
423             else if (announcementsDelivery.isSms()) {
424                 String smsSn = user.getContact().getSmsSn();
425 
426                 InternetAddress address = new InternetAddress(
427                     smsSn, user.getFullName());
428 
429                 bulkAddresses.add(address);
430             }
431         }
432 
433         if (bulkAddresses.size() == 0) {
434             return;
435         }
436 
437         String subject = ContentUtil.get(
438             PropsValues.ANNOUNCEMENTS_EMAIL_SUBJECT);
439         String body = ContentUtil.get(PropsValues.ANNOUNCEMENTS_EMAIL_BODY);
440 
441         subject = StringUtil.replace(
442             subject,
443             new String[] {
444                 "[$ENTRY_CONTENT$]",
445                 "[$ENTRY_ID$]",
446                 "[$ENTRY_TITLE$]",
447                 "[$ENTRY_TYPE$]",
448                 "[$ENTRY_URL$]",
449                 "[$FROM_ADDRESS$]",
450                 "[$FROM_NAME$]",
451                 "[$PORTAL_URL$]",
452                 "[$PORTLET_NAME$]",
453                 "[$TO_ADDRESS$]",
454                 "[$TO_NAME$]"
455             },
456             new String[] {
457                 entry.getContent(),
458                 String.valueOf(entry.getEntryId()),
459                 entry.getTitle(),
460                 LanguageUtil.get(
461                     company.getCompanyId(), company.getLocale(),
462                     entry.getType()),
463                 entry.getUrl(),
464                 fromAddress,
465                 fromName,
466                 company.getVirtualHost(),
467                 LanguageUtil.get(
468                     company.getCompanyId(), company.getLocale(),
469                     (entry.isAlert() ? "alert" : "announcement")),
470                 toAddress,
471                 toName
472             });
473 
474         body = StringUtil.replace(
475             body,
476             new String[] {
477                 "[$ENTRY_CONTENT$]",
478                 "[$ENTRY_ID$]",
479                 "[$ENTRY_TITLE$]",
480                 "[$ENTRY_TYPE$]",
481                 "[$ENTRY_URL$]",
482                 "[$FROM_ADDRESS$]",
483                 "[$FROM_NAME$]",
484                 "[$PORTAL_URL$]",
485                 "[$PORTLET_NAME$]",
486                 "[$TO_ADDRESS$]",
487                 "[$TO_NAME$]"
488             },
489             new String[] {
490                 entry.getContent(),
491                 String.valueOf(entry.getEntryId()),
492                 entry.getTitle(),
493                 LanguageUtil.get(
494                     company.getCompanyId(), company.getLocale(),
495                     entry.getType()),
496                 entry.getUrl(),
497                 fromAddress,
498                 fromName,
499                 company.getVirtualHost(),
500                 LanguageUtil.get(
501                     company.getCompanyId(), company.getLocale(),
502                     (entry.isAlert() ? "alert" : "announcement")),
503                 toAddress,
504                 toName
505             });
506 
507         InternetAddress from = new InternetAddress(fromAddress, fromName);
508 
509         InternetAddress[] to = new InternetAddress[] {
510             new InternetAddress(toAddress, toName)};
511 
512         InternetAddress[] bulkAddressesArray = bulkAddresses.toArray(
513             new InternetAddress[bulkAddresses.size()]);
514 
515         MailMessage message = new MailMessage(
516             from, to, null, null, bulkAddressesArray, subject, body, true);
517 
518         mailService.sendEmail(message);
519     }
520 
521     protected void validate(String title, String content)
522         throws PortalException {
523 
524         if (Validator.isNull(title)) {
525             throw new EntryTitleException();
526         }
527 
528         if (Validator.isNull(content)) {
529             throw new EntryContentException();
530         }
531     }
532 
533     private static Log _log =
534         LogFactory.getLog(AnnouncementsEntryLocalServiceImpl.class);
535 
536 }