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.dao.orm.QueryUtil;
28  import com.liferay.portal.kernel.language.LanguageUtil;
29  import com.liferay.portal.kernel.mail.MailMessage;
30  import com.liferay.portal.kernel.util.StringUtil;
31  import com.liferay.portal.kernel.util.Validator;
32  import com.liferay.portal.model.Company;
33  import com.liferay.portal.model.Group;
34  import com.liferay.portal.model.Organization;
35  import com.liferay.portal.model.Role;
36  import com.liferay.portal.model.User;
37  import com.liferay.portal.model.UserGroup;
38  import com.liferay.portal.util.ContentUtil;
39  import com.liferay.portal.util.PortalUtil;
40  import com.liferay.portal.util.PropsValues;
41  import com.liferay.portlet.announcements.EntryContentException;
42  import com.liferay.portlet.announcements.EntryDisplayDateException;
43  import com.liferay.portlet.announcements.EntryExpirationDateException;
44  import com.liferay.portlet.announcements.EntryTitleException;
45  import com.liferay.portlet.announcements.job.CheckEntryJob;
46  import com.liferay.portlet.announcements.model.AnnouncementsDelivery;
47  import com.liferay.portlet.announcements.model.AnnouncementsEntry;
48  import com.liferay.portlet.announcements.service.base.AnnouncementsEntryLocalServiceBaseImpl;
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, 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             users.add(user);
403         }
404         else {
405             users = userLocalService.search(
406                 company.getCompanyId(), null, Boolean.TRUE, params,
407                 QueryUtil.ALL_POS, QueryUtil.ALL_POS, null);
408         }
409 
410         if (_log.isDebugEnabled()) {
411             _log.debug("Notifying " + users.size() + " users");
412         }
413 
414         List<InternetAddress> bulkAddresses = new ArrayList<InternetAddress>();
415 
416         for (User user : users) {
417             AnnouncementsDelivery announcementsDelivery =
418                 announcementsDeliveryLocalService.getUserDelivery(
419                     user.getUserId(), entry.getType());
420 
421             if (announcementsDelivery.isEmail()) {
422                 InternetAddress address = new InternetAddress(
423                     user.getEmailAddress(), user.getFullName());
424 
425                 bulkAddresses.add(address);
426             }
427             else 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         LogFactory.getLog(AnnouncementsEntryLocalServiceImpl.class);
540 
541 }