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