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