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