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