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.HtmlUtil;
024    import com.liferay.portal.kernel.util.ListUtil;
025    import com.liferay.portal.kernel.util.OrderByComparator;
026    import com.liferay.portal.kernel.util.PropsKeys;
027    import com.liferay.portal.kernel.util.Time;
028    import com.liferay.portal.kernel.util.Validator;
029    import com.liferay.portal.kernel.workflow.WorkflowConstants;
030    import com.liferay.portal.model.Company;
031    import com.liferay.portal.model.Group;
032    import com.liferay.portal.model.Organization;
033    import com.liferay.portal.model.ResourceConstants;
034    import com.liferay.portal.model.Role;
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("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.setContextAttributes(
467                            "[$ENTRY_CONTENT$]", HtmlUtil.extractText(entry.getContent()),
468                            "[$ENTRY_ID$]", entry.getEntryId(), "[$ENTRY_TITLE$]",
469                            entry.getTitle(), "[$ENTRY_TYPE$]",
470                            LanguageUtil.get(company.getLocale(), entry.getType()),
471                            "[$ENTRY_URL$]", entry.getUrl(), "[$PORTLET_NAME$]",
472                            LanguageUtil.get(
473                                    company.getLocale(),
474                                    (entry.isAlert() ? "alert" : "announcement")));
475                    subscriptionSender.setFrom(fromAddress, fromName);
476                    subscriptionSender.setHtmlFormat(true);
477                    subscriptionSender.setMailId("announcements_entry", entry.getEntryId());
478                    subscriptionSender.setPortletId(PortletKeys.ANNOUNCEMENTS);
479                    subscriptionSender.setScopeGroupId(entry.getGroupId());
480                    subscriptionSender.setSubject(subject);
481                    subscriptionSender.setUserId(entry.getUserId());
482    
483                    subscriptionSender.addRuntimeSubscribers(toAddress, toName);
484    
485                    subscriptionSender.flushNotificationsAsync();
486            }
487    
488            protected void validate(String title, String content, String url)
489                    throws PortalException {
490    
491                    if (Validator.isNull(title)) {
492                            throw new EntryTitleException();
493                    }
494    
495                    if (Validator.isNull(content)) {
496                            throw new EntryContentException();
497                    }
498    
499                    if (Validator.isNotNull(url) && !Validator.isUrl(url)) {
500                            throw new EntryURLException();
501                    }
502            }
503    
504            private static final long _ANNOUNCEMENTS_ENTRY_CHECK_INTERVAL =
505                    PropsValues.ANNOUNCEMENTS_ENTRY_CHECK_INTERVAL * Time.MINUTE;
506    
507            private static Log _log = LogFactoryUtil.getLog(
508                    AnnouncementsEntryLocalServiceImpl.class);
509    
510            private Date _previousCheckDate;
511    
512    }