001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.announcements.service.impl;
016    
017    import com.liferay.portal.kernel.dao.orm.QueryUtil;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.exception.SystemException;
020    import com.liferay.portal.kernel.language.LanguageUtil;
021    import com.liferay.portal.kernel.log.Log;
022    import com.liferay.portal.kernel.log.LogFactoryUtil;
023    import com.liferay.portal.kernel.util.ListUtil;
024    import com.liferay.portal.kernel.util.OrderByComparator;
025    import com.liferay.portal.kernel.util.PropsKeys;
026    import com.liferay.portal.kernel.util.Time;
027    import com.liferay.portal.kernel.util.Validator;
028    import com.liferay.portal.kernel.workflow.WorkflowConstants;
029    import com.liferay.portal.model.Company;
030    import com.liferay.portal.model.Group;
031    import com.liferay.portal.model.Organization;
032    import com.liferay.portal.model.ResourceConstants;
033    import com.liferay.portal.model.Role;
034    import com.liferay.portal.model.User;
035    import com.liferay.portal.model.UserGroup;
036    import com.liferay.portal.util.PortalUtil;
037    import com.liferay.portal.util.PortletKeys;
038    import com.liferay.portal.util.PrefsPropsUtil;
039    import com.liferay.portal.util.PropsValues;
040    import com.liferay.portal.util.SubscriptionSender;
041    import com.liferay.portlet.announcements.EntryContentException;
042    import com.liferay.portlet.announcements.EntryDisplayDateException;
043    import com.liferay.portlet.announcements.EntryExpirationDateException;
044    import com.liferay.portlet.announcements.EntryTitleException;
045    import com.liferay.portlet.announcements.EntryURLException;
046    import com.liferay.portlet.announcements.model.AnnouncementsDelivery;
047    import com.liferay.portlet.announcements.model.AnnouncementsEntry;
048    import com.liferay.portlet.announcements.service.base.AnnouncementsEntryLocalServiceBaseImpl;
049    import com.liferay.util.ContentUtil;
050    
051    import java.util.ArrayList;
052    import java.util.Date;
053    import java.util.LinkedHashMap;
054    import java.util.List;
055    
056    /**
057     * @author Brian Wing Shun Chan
058     * @author Raymond Augé
059     */
060    public class AnnouncementsEntryLocalServiceImpl
061            extends AnnouncementsEntryLocalServiceBaseImpl {
062    
063            public AnnouncementsEntry addEntry(
064                            long userId, long classNameId, long classPK, String title,
065                            String content, String url, String type, int displayDateMonth,
066                            int displayDateDay, int displayDateYear, int displayDateHour,
067                            int displayDateMinute, int expirationDateMonth,
068                            int expirationDateDay, int expirationDateYear,
069                            int expirationDateHour, int expirationDateMinute, int priority,
070                            boolean alert)
071                    throws PortalException, SystemException {
072    
073                    // Entry
074    
075                    User user = userPersistence.findByPrimaryKey(userId);
076    
077                    Date displayDate = PortalUtil.getDate(
078                            displayDateMonth, displayDateDay, displayDateYear, displayDateHour,
079                            displayDateMinute, user.getTimeZone(),
080                            EntryDisplayDateException.class);
081    
082                    Date expirationDate = PortalUtil.getDate(
083                            expirationDateMonth, expirationDateDay, expirationDateYear,
084                            expirationDateHour, expirationDateMinute, user.getTimeZone(),
085                            EntryExpirationDateException.class);
086    
087                    Date now = new Date();
088    
089                    validate(title, content, url);
090    
091                    long entryId = counterLocalService.increment();
092    
093                    AnnouncementsEntry entry = announcementsEntryPersistence.create(
094                            entryId);
095    
096                    entry.setCompanyId(user.getCompanyId());
097                    entry.setUserId(user.getUserId());
098                    entry.setUserName(user.getFullName());
099                    entry.setCreateDate(now);
100                    entry.setModifiedDate(now);
101                    entry.setClassNameId(classNameId);
102                    entry.setClassPK(classPK);
103                    entry.setTitle(title);
104                    entry.setContent(content);
105                    entry.setUrl(url);
106                    entry.setType(type);
107                    entry.setDisplayDate(displayDate);
108                    entry.setExpirationDate(expirationDate);
109                    entry.setPriority(priority);
110                    entry.setAlert(alert);
111    
112                    announcementsEntryPersistence.update(entry);
113    
114                    // Resources
115    
116                    resourceLocalService.addResources(
117                            user.getCompanyId(), 0, user.getUserId(),
118                            AnnouncementsEntry.class.getName(), entry.getEntryId(), false,
119                            false, false);
120    
121                    return entry;
122            }
123    
124            public void checkEntries() throws PortalException, SystemException {
125                    Date now = new Date();
126    
127                    if (_previousCheckDate == null) {
128                            _previousCheckDate = new Date(
129                                    now.getTime() - _ANNOUNCEMENTS_ENTRY_CHECK_INTERVAL);
130                    }
131    
132                    List<AnnouncementsEntry> entries =
133                            announcementsEntryFinder.findByDisplayDate(now, _previousCheckDate);
134    
135                    if (_log.isDebugEnabled()) {
136                            _log.debug("Processing " + entries.size() + " entries");
137                    }
138    
139                    for (AnnouncementsEntry entry : entries) {
140                            notifyUsers(entry);
141                    }
142    
143                    _previousCheckDate = now;
144            }
145    
146            public void deleteEntry(AnnouncementsEntry entry)
147                    throws PortalException, SystemException {
148    
149                    // Entry
150    
151                    announcementsEntryPersistence.remove(entry);
152    
153                    // Resources
154    
155                    resourceLocalService.deleteResource(
156                            entry.getCompanyId(), AnnouncementsEntry.class.getName(),
157                            ResourceConstants.SCOPE_INDIVIDUAL, entry.getEntryId());
158    
159                    // Flags
160    
161                    announcementsFlagLocalService.deleteFlags(entry.getEntryId());
162            }
163    
164            public void deleteEntry(long entryId)
165                    throws PortalException, SystemException {
166    
167                    AnnouncementsEntry entry =
168                            announcementsEntryPersistence.findByPrimaryKey(entryId);
169    
170                    deleteEntry(entry);
171            }
172    
173            public List<AnnouncementsEntry> getEntries(
174                            long userId, LinkedHashMap<Long, long[]> scopes, boolean alert,
175                            int flagValue, int start, int end)
176                    throws SystemException {
177    
178                    return getEntries(
179                            userId, scopes, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, alert, flagValue,
180                            start, end);
181            }
182    
183            public List<AnnouncementsEntry> getEntries(
184                            long userId, LinkedHashMap<Long, long[]> scopes,
185                            int displayDateMonth, int displayDateDay, int displayDateYear,
186                            int displayDateHour, int displayDateMinute, int expirationDateMonth,
187                            int expirationDateDay, int expirationDateYear,
188                            int expirationDateHour, int expirationDateMinute, boolean alert,
189                            int flagValue, int start, int end)
190                    throws SystemException {
191    
192                    return announcementsEntryFinder.findByScopes(
193                            userId, scopes, displayDateMonth, displayDateDay, displayDateYear,
194                            displayDateHour, displayDateMinute, expirationDateMonth,
195                            expirationDateDay, expirationDateYear, expirationDateHour,
196                            expirationDateMinute, alert, flagValue, start, end);
197            }
198    
199            public List<AnnouncementsEntry> getEntries(
200                            long classNameId, long classPK, boolean alert, int start, int end)
201                    throws SystemException {
202    
203                    return announcementsEntryPersistence.findByC_C_A(
204                            classNameId, classPK, alert, start, end);
205            }
206    
207            public List<AnnouncementsEntry> getEntries(
208                            long userId, long classNameId, long[] classPKs,
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.findByScope(
217                            userId, classNameId, classPKs, displayDateMonth, displayDateDay,
218                            displayDateYear, displayDateHour, displayDateMinute,
219                            expirationDateMonth, expirationDateDay, expirationDateYear,
220                            expirationDateHour, expirationDateMinute, alert, flagValue, start,
221                            end);
222            }
223    
224            public int getEntriesCount(
225                            long userId, LinkedHashMap<Long, long[]> scopes, boolean alert,
226                            int flagValue)
227                    throws SystemException {
228    
229                    return getEntriesCount(
230                            userId, scopes, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, alert, flagValue);
231            }
232    
233            public int getEntriesCount(
234                            long userId, LinkedHashMap<Long, long[]> scopes,
235                            int displayDateMonth, int displayDateDay, int displayDateYear,
236                            int displayDateHour, int displayDateMinute, int expirationDateMonth,
237                            int expirationDateDay, int expirationDateYear,
238                            int expirationDateHour, int expirationDateMinute, boolean alert,
239                            int flagValue)
240                    throws SystemException {
241    
242                    return announcementsEntryFinder.countByScopes(
243                            userId, scopes, displayDateMonth, displayDateDay, displayDateYear,
244                            displayDateHour, displayDateMinute, expirationDateMonth,
245                            expirationDateDay, expirationDateYear, expirationDateHour,
246                            expirationDateMinute, alert, flagValue);
247            }
248    
249            public int getEntriesCount(long classNameId, long classPK, boolean alert)
250                    throws SystemException {
251    
252                    return announcementsEntryPersistence.countByC_C_A(
253                            classNameId, classPK, alert);
254            }
255    
256            public int getEntriesCount(
257                            long userId, long classNameId, long[] classPKs, boolean alert,
258                            int flagValue)
259                    throws SystemException {
260    
261                    return getEntriesCount(
262                            userId, classNameId, classPKs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, alert,
263                            flagValue);
264            }
265    
266            public int getEntriesCount(
267                            long userId, long classNameId, long[] classPKs,
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.countByScope(
276                            userId, classNameId, classPKs, displayDateMonth, displayDateDay,
277                            displayDateYear, displayDateHour, displayDateMinute,
278                            expirationDateMonth, expirationDateDay, expirationDateYear,
279                            expirationDateHour, expirationDateMinute, alert, flagValue);
280            }
281    
282            public AnnouncementsEntry getEntry(long entryId)
283                    throws PortalException, SystemException {
284    
285                    return announcementsEntryPersistence.findByPrimaryKey(entryId);
286            }
287    
288            public List<AnnouncementsEntry> getUserEntries(
289                            long userId, int start, int end)
290                    throws SystemException {
291    
292                    return announcementsEntryPersistence.findByUserId(userId, start, end);
293            }
294    
295            public int getUserEntriesCount(long userId) throws SystemException {
296                    return announcementsEntryPersistence.countByUserId(userId);
297            }
298    
299            public AnnouncementsEntry updateEntry(
300                            long userId, long entryId, String title, String content, String url,
301                            String type, int displayDateMonth, int displayDateDay,
302                            int displayDateYear, int displayDateHour, int displayDateMinute,
303                            int expirationDateMonth, int expirationDateDay,
304                            int expirationDateYear, int expirationDateHour,
305                            int expirationDateMinute, int priority)
306                    throws PortalException, SystemException {
307    
308                    // Entry
309    
310                    User user = userPersistence.findByPrimaryKey(userId);
311    
312                    Date displayDate = PortalUtil.getDate(
313                            displayDateMonth, displayDateDay, displayDateYear, displayDateHour,
314                            displayDateMinute, user.getTimeZone(),
315                            EntryDisplayDateException.class);
316    
317                    Date expirationDate = PortalUtil.getDate(
318                            expirationDateMonth, expirationDateDay, expirationDateYear,
319                            expirationDateHour, expirationDateMinute, user.getTimeZone(),
320                            EntryExpirationDateException.class);
321    
322                    validate(title, content, url);
323    
324                    AnnouncementsEntry entry =
325                            announcementsEntryPersistence.findByPrimaryKey(entryId);
326    
327                    entry.setModifiedDate(new Date());
328                    entry.setTitle(title);
329                    entry.setContent(content);
330                    entry.setUrl(url);
331                    entry.setType(type);
332                    entry.setDisplayDate(displayDate);
333                    entry.setExpirationDate(expirationDate);
334                    entry.setPriority(priority);
335    
336                    announcementsEntryPersistence.update(entry);
337    
338                    // Flags
339    
340                    announcementsFlagLocalService.deleteFlags(entry.getEntryId());
341    
342                    return entry;
343            }
344    
345            protected void notifyUsers(AnnouncementsEntry entry)
346                    throws PortalException, SystemException {
347    
348                    Company company = companyPersistence.findByPrimaryKey(
349                            entry.getCompanyId());
350    
351                    String className = entry.getClassName();
352                    long classPK = entry.getClassPK();
353    
354                    String fromName = PrefsPropsUtil.getStringFromNames(
355                            entry.getCompanyId(), PropsKeys.ANNOUNCEMENTS_EMAIL_FROM_NAME,
356                            PropsKeys.ADMIN_EMAIL_FROM_NAME);
357                    String fromAddress = PrefsPropsUtil.getStringFromNames(
358                            entry.getCompanyId(), PropsKeys.ANNOUNCEMENTS_EMAIL_FROM_ADDRESS,
359                            PropsKeys.ADMIN_EMAIL_FROM_ADDRESS);
360    
361                    String toName = PropsValues.ANNOUNCEMENTS_EMAIL_TO_NAME;
362                    String toAddress = PropsValues.ANNOUNCEMENTS_EMAIL_TO_ADDRESS;
363    
364                    LinkedHashMap<String, Object> params =
365                            new LinkedHashMap<String, Object>();
366    
367                    params.put("announcementsDeliveryEmailOrSms", entry.getType());
368    
369                    if (classPK > 0) {
370                            if (className.equals(Group.class.getName())) {
371                                    Group group = groupPersistence.findByPrimaryKey(classPK);
372    
373                                    toName = group.getName();
374    
375                                    params.put("inherit", Boolean.TRUE);
376                                    params.put("usersGroups", classPK);
377                            }
378                            else if (className.equals(Organization.class.getName())) {
379                                    Organization organization =
380                                            organizationPersistence.findByPrimaryKey(classPK);
381    
382                                    toName = organization.getName();
383    
384                                    params.put(
385                                            "usersOrgsTree",
386                                            ListUtil.fromArray(new Organization[] {organization}));
387                            }
388                            else if (className.equals(Role.class.getName())) {
389                                    Role role = rolePersistence.findByPrimaryKey(classPK);
390    
391                                    toName = role.getName();
392    
393                                    params.put("usersRoles", classPK);
394                            }
395                            else if (className.equals(UserGroup.class.getName())) {
396                                    UserGroup userGroup = userGroupPersistence.findByPrimaryKey(
397                                            classPK);
398    
399                                    toName = userGroup.getName();
400    
401                                    params.put("usersUserGroups", classPK);
402                            }
403                    }
404    
405                    List<User> users = null;
406    
407                    if (className.equals(User.class.getName())) {
408                            User user = userPersistence.findByPrimaryKey(classPK);
409    
410                            toName = user.getFullName();
411                            toAddress = user.getEmailAddress();
412    
413                            users = new ArrayList<User>();
414    
415                            if (Validator.isNotNull(toAddress)) {
416                                    users.add(user);
417                            }
418                    }
419                    else {
420                            users = userLocalService.search(
421                                    company.getCompanyId(), null, WorkflowConstants.STATUS_APPROVED,
422                                    params, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
423                                    (OrderByComparator)null);
424                    }
425    
426                    if (_log.isDebugEnabled()) {
427                            _log.debug("Notifying " + users.size() + " users");
428                    }
429    
430                    boolean notifyUsers = false;
431    
432                    SubscriptionSender subscriptionSender = new SubscriptionSender();
433    
434                    for (User user : users) {
435                            AnnouncementsDelivery announcementsDelivery =
436                                    announcementsDeliveryLocalService.getUserDelivery(
437                                            user.getUserId(), entry.getType());
438    
439                            if (announcementsDelivery.isEmail()) {
440                                    subscriptionSender.addRuntimeSubscribers(
441                                            user.getEmailAddress(), user.getFullName());
442    
443                                    notifyUsers = true;
444                            }
445    
446                            if (announcementsDelivery.isSms()) {
447                                    String smsSn = user.getContact().getSmsSn();
448    
449                                    subscriptionSender.addRuntimeSubscribers(
450                                            smsSn, user.getFullName());
451    
452                                    notifyUsers = true;
453                            }
454                    }
455    
456                    if (!notifyUsers) {
457                            return;
458                    }
459    
460                    String subject = ContentUtil.get(
461                            PropsValues.ANNOUNCEMENTS_EMAIL_SUBJECT);
462                    String body = ContentUtil.get(PropsValues.ANNOUNCEMENTS_EMAIL_BODY);
463    
464                    subscriptionSender.setBody(body);
465                    subscriptionSender.setCompanyId(entry.getCompanyId());
466                    subscriptionSender.setContextAttribute(
467                            "[$ENTRY_CONTENT$]", entry.getContent(), false);
468                    subscriptionSender.setContextAttributes(
469                            "[$ENTRY_ID$]", entry.getEntryId(), "[$ENTRY_TITLE$]",
470                            entry.getTitle(), "[$ENTRY_TYPE$]",
471                            LanguageUtil.get(company.getLocale(), entry.getType()),
472                            "[$ENTRY_URL$]", entry.getUrl(), "[$PORTLET_NAME$]",
473                            LanguageUtil.get(
474                                    company.getLocale(),
475                                    (entry.isAlert() ? "alert" : "announcement")));
476                    subscriptionSender.setFrom(fromAddress, fromName);
477                    subscriptionSender.setHtmlFormat(true);
478                    subscriptionSender.setMailId("announcements_entry", entry.getEntryId());
479                    subscriptionSender.setPortletId(PortletKeys.ANNOUNCEMENTS);
480                    subscriptionSender.setScopeGroupId(entry.getGroupId());
481                    subscriptionSender.setSubject(subject);
482                    subscriptionSender.setUserId(entry.getUserId());
483    
484                    subscriptionSender.addRuntimeSubscribers(toAddress, toName);
485    
486                    subscriptionSender.flushNotificationsAsync();
487            }
488    
489            protected void validate(String title, String content, String url)
490                    throws PortalException {
491    
492                    if (Validator.isNull(title)) {
493                            throw new EntryTitleException();
494                    }
495    
496                    if (Validator.isNull(content)) {
497                            throw new EntryContentException();
498                    }
499    
500                    if (Validator.isNotNull(url) && !Validator.isUrl(url)) {
501                            throw new EntryURLException();
502                    }
503            }
504    
505            private static final long _ANNOUNCEMENTS_ENTRY_CHECK_INTERVAL =
506                    PropsValues.ANNOUNCEMENTS_ENTRY_CHECK_INTERVAL * Time.MINUTE;
507    
508            private static Log _log = LogFactoryUtil.getLog(
509                    AnnouncementsEntryLocalServiceImpl.class);
510    
511            private Date _previousCheckDate;
512    
513    }