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