001    /**
002     * Copyright (c) 2000-2010 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.mail.MailMessage;
024    import com.liferay.portal.kernel.util.OrderByComparator;
025    import com.liferay.portal.kernel.util.StringUtil;
026    import com.liferay.portal.kernel.util.Time;
027    import com.liferay.portal.kernel.util.Validator;
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.ContentUtil;
036    import com.liferay.portal.util.PortalUtil;
037    import com.liferay.portal.util.PropsValues;
038    import com.liferay.portlet.announcements.EntryContentException;
039    import com.liferay.portlet.announcements.EntryDisplayDateException;
040    import com.liferay.portlet.announcements.EntryExpirationDateException;
041    import com.liferay.portlet.announcements.EntryTitleException;
042    import com.liferay.portlet.announcements.EntryURLException;
043    import com.liferay.portlet.announcements.model.AnnouncementsDelivery;
044    import com.liferay.portlet.announcements.model.AnnouncementsEntry;
045    import com.liferay.portlet.announcements.service.base.AnnouncementsEntryLocalServiceBaseImpl;
046    
047    import java.io.IOException;
048    
049    import java.util.ArrayList;
050    import java.util.Date;
051    import java.util.LinkedHashMap;
052    import java.util.List;
053    
054    import javax.mail.internet.InternetAddress;
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                            new EntryDisplayDateException());
081    
082                    Date expirationDate = PortalUtil.getDate(
083                            expirationDateMonth, expirationDateDay, expirationDateYear,
084                            expirationDateHour, expirationDateMinute, user.getTimeZone(),
085                            new EntryExpirationDateException());
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, false);
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, new Date(now.getTime() - _entryCheckInterval));
130    
131                    if (_log.isDebugEnabled()) {
132                            _log.debug("Processing " + entries.size() + " entries");
133                    }
134    
135                    for (AnnouncementsEntry entry : entries) {
136                            try {
137                                    notifyUsers(entry);
138                            }
139                            catch (IOException ioe) {
140                                    throw new SystemException(ioe);
141                            }
142                    }
143            }
144    
145            public void deleteEntry(AnnouncementsEntry entry)
146                    throws PortalException, SystemException {
147    
148                    // Entry
149    
150                    announcementsEntryPersistence.remove(entry);
151    
152                    // Resources
153    
154                    resourceLocalService.deleteResource(
155                            entry.getCompanyId(), AnnouncementsEntry.class.getName(),
156                            ResourceConstants.SCOPE_INDIVIDUAL, entry.getEntryId());
157    
158                    // Flags
159    
160                    announcementsFlagLocalService.deleteFlags(entry.getEntryId());
161            }
162    
163            public void deleteEntry(long entryId)
164                    throws PortalException, SystemException {
165    
166                    AnnouncementsEntry entry =
167                            announcementsEntryPersistence.findByPrimaryKey(entryId);
168    
169                    deleteEntry(entry);
170            }
171    
172            public List<AnnouncementsEntry> getEntries(
173                            long userId, LinkedHashMap<Long, long[]> scopes, boolean alert,
174                            int flagValue, int start, int end)
175                    throws SystemException {
176    
177                    return getEntries(
178                            userId, scopes, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, alert, flagValue,
179                            start, end);
180            }
181    
182            public List<AnnouncementsEntry> getEntries(
183                            long userId, LinkedHashMap<Long, long[]> scopes,
184                            int displayDateMonth, int displayDateDay, int displayDateYear,
185                            int displayDateHour, int displayDateMinute, int expirationDateMonth,
186                            int expirationDateDay, int expirationDateYear,
187                            int expirationDateHour, int expirationDateMinute, boolean alert,
188                            int flagValue, int start, int end)
189                    throws SystemException {
190    
191                    return announcementsEntryFinder.findByScopes(
192                            userId, scopes, displayDateMonth, displayDateDay, displayDateYear,
193                            displayDateHour, displayDateMinute, expirationDateMonth,
194                            expirationDateDay, expirationDateYear, expirationDateHour,
195                            expirationDateMinute, alert, flagValue, start, end);
196            }
197    
198            public List<AnnouncementsEntry> getEntries(
199                            long classNameId, long classPK, boolean alert, int start, int end)
200                    throws SystemException {
201    
202                    return announcementsEntryPersistence.findByC_C_A(
203                            classNameId, classPK, alert, start, end);
204            }
205    
206            public List<AnnouncementsEntry> getEntries(
207                            long userId, long classNameId, long[] classPKs,
208                            int displayDateMonth, int displayDateDay, int displayDateYear,
209                            int displayDateHour, int displayDateMinute, int expirationDateMonth,
210                            int expirationDateDay, int expirationDateYear,
211                            int expirationDateHour, int expirationDateMinute, boolean alert,
212                            int flagValue, int start, int end)
213                    throws SystemException {
214    
215                    return announcementsEntryFinder.findByScope(
216                            userId, classNameId, classPKs, displayDateMonth, displayDateDay,
217                            displayDateYear, displayDateHour, displayDateMinute,
218                            expirationDateMonth, expirationDateDay, expirationDateYear,
219                            expirationDateHour, expirationDateMinute, alert, flagValue, start,
220                            end);
221            }
222    
223            public int getEntriesCount(
224                            long userId, LinkedHashMap<Long, long[]> scopes, boolean alert,
225                            int flagValue)
226                    throws SystemException {
227    
228                    return getEntriesCount(
229                            userId, scopes, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, alert, flagValue);
230            }
231    
232            public int getEntriesCount(
233                            long userId, LinkedHashMap<Long, long[]> scopes,
234                            int displayDateMonth, int displayDateDay, int displayDateYear,
235                            int displayDateHour, int displayDateMinute, int expirationDateMonth,
236                            int expirationDateDay, int expirationDateYear,
237                            int expirationDateHour, int expirationDateMinute, boolean alert,
238                            int flagValue)
239                    throws SystemException {
240    
241                    return announcementsEntryFinder.countByScopes(
242                            userId, scopes, displayDateMonth, displayDateDay, displayDateYear,
243                            displayDateHour, displayDateMinute, expirationDateMonth,
244                            expirationDateDay, expirationDateYear, expirationDateHour,
245                            expirationDateMinute, alert, flagValue);
246            }
247    
248            public int getEntriesCount(long classNameId, long classPK, boolean alert)
249                    throws SystemException {
250    
251                    return announcementsEntryPersistence.countByC_C_A(
252                            classNameId, classPK, alert);
253            }
254    
255            public int getEntriesCount(
256                            long userId, long classNameId, long[] classPKs, boolean alert,
257                            int flagValue)
258                    throws SystemException {
259    
260                    return getEntriesCount(
261                            userId, classNameId, classPKs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, alert,
262                            flagValue);
263            }
264    
265            public int getEntriesCount(
266                            long userId, long classNameId, long[] classPKs,
267                            int displayDateMonth, int displayDateDay, int displayDateYear,
268                            int displayDateHour, int displayDateMinute, int expirationDateMonth,
269                            int expirationDateDay, int expirationDateYear,
270                            int expirationDateHour, int expirationDateMinute, boolean alert,
271                            int flagValue)
272                    throws SystemException {
273    
274                    return announcementsEntryFinder.countByScope(
275                            userId, classNameId, classPKs, displayDateMonth, displayDateDay,
276                            displayDateYear, displayDateHour, displayDateMinute,
277                            expirationDateMonth, expirationDateDay, expirationDateYear,
278                            expirationDateHour, expirationDateMinute, alert, flagValue);
279            }
280    
281            public AnnouncementsEntry getEntry(long entryId)
282                    throws PortalException, SystemException {
283    
284                    return announcementsEntryPersistence.findByPrimaryKey(entryId);
285            }
286    
287            public List<AnnouncementsEntry> getUserEntries(
288                            long userId, int start, int end)
289                    throws SystemException {
290    
291                    return announcementsEntryPersistence.findByUserId(userId, start, end);
292            }
293    
294            public int getUserEntriesCount(long userId) throws SystemException {
295                    return announcementsEntryPersistence.countByUserId(userId);
296            }
297    
298            public AnnouncementsEntry updateEntry(
299                            long userId, long entryId, String title, String content, String url,
300                            String type, int displayDateMonth, int displayDateDay,
301                            int displayDateYear, int displayDateHour, int displayDateMinute,
302                            int expirationDateMonth, int expirationDateDay,
303                            int expirationDateYear, int expirationDateHour,
304                            int expirationDateMinute, int priority)
305                    throws PortalException, SystemException {
306    
307                    // Entry
308    
309                    User user = userPersistence.findByPrimaryKey(userId);
310    
311                    Date displayDate = PortalUtil.getDate(
312                            displayDateMonth, displayDateDay, displayDateYear, displayDateHour,
313                            displayDateMinute, user.getTimeZone(),
314                            new EntryDisplayDateException());
315    
316                    Date expirationDate = PortalUtil.getDate(
317                            expirationDateMonth, expirationDateDay, expirationDateYear,
318                            expirationDateHour, expirationDateMinute, user.getTimeZone(),
319                            new EntryExpirationDateException());
320    
321                    validate(title, content, url);
322    
323                    AnnouncementsEntry entry =
324                            announcementsEntryPersistence.findByPrimaryKey(entryId);
325    
326                    entry.setModifiedDate(new Date());
327                    entry.setTitle(title);
328                    entry.setContent(content);
329                    entry.setUrl(url);
330                    entry.setType(type);
331                    entry.setDisplayDate(displayDate);
332                    entry.setExpirationDate(expirationDate);
333                    entry.setPriority(priority);
334    
335                    announcementsEntryPersistence.update(entry, false);
336    
337                    // Flags
338    
339                    announcementsFlagLocalService.deleteFlags(entry.getEntryId());
340    
341                    return entry;
342            }
343    
344            protected void notifyUsers(AnnouncementsEntry entry)
345                    throws IOException, PortalException, SystemException {
346    
347                    Company company = companyPersistence.findByPrimaryKey(
348                            entry.getCompanyId());
349    
350                    String className = entry.getClassName();
351                    long classPK = entry.getClassPK();
352    
353                    String fromName = PropsValues.ANNOUNCEMENTS_EMAIL_FROM_NAME;
354                    String fromAddress = PropsValues.ANNOUNCEMENTS_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 = userLocalService.getUserById(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, Boolean.TRUE, params,
414                                    QueryUtil.ALL_POS, QueryUtil.ALL_POS, (OrderByComparator)null);
415                    }
416    
417                    if (_log.isDebugEnabled()) {
418                            _log.debug("Notifying " + users.size() + " users");
419                    }
420    
421                    List<InternetAddress> bulkAddresses = new ArrayList<InternetAddress>();
422    
423                    for (User user : users) {
424                            AnnouncementsDelivery announcementsDelivery =
425                                    announcementsDeliveryLocalService.getUserDelivery(
426                                            user.getUserId(), entry.getType());
427    
428                            if (announcementsDelivery.isEmail()) {
429                                    InternetAddress address = new InternetAddress(
430                                            user.getEmailAddress(), user.getFullName());
431    
432                                    bulkAddresses.add(address);
433                            }
434    
435                            if (announcementsDelivery.isSms()) {
436                                    String smsSn = user.getContact().getSmsSn();
437    
438                                    InternetAddress address = new InternetAddress(
439                                            smsSn, user.getFullName());
440    
441                                    bulkAddresses.add(address);
442                            }
443                    }
444    
445                    if (bulkAddresses.size() == 0) {
446                            return;
447                    }
448    
449                    String subject = ContentUtil.get(
450                            PropsValues.ANNOUNCEMENTS_EMAIL_SUBJECT);
451                    String body = ContentUtil.get(PropsValues.ANNOUNCEMENTS_EMAIL_BODY);
452    
453                    subject = StringUtil.replace(
454                            subject,
455                            new String[] {
456                                    "[$ENTRY_CONTENT$]",
457                                    "[$ENTRY_ID$]",
458                                    "[$ENTRY_TITLE$]",
459                                    "[$ENTRY_TYPE$]",
460                                    "[$ENTRY_URL$]",
461                                    "[$FROM_ADDRESS$]",
462                                    "[$FROM_NAME$]",
463                                    "[$PORTAL_URL$]",
464                                    "[$PORTLET_NAME$]",
465                                    "[$TO_ADDRESS$]",
466                                    "[$TO_NAME$]"
467                            },
468                            new String[] {
469                                    entry.getContent(),
470                                    String.valueOf(entry.getEntryId()),
471                                    entry.getTitle(),
472                                    LanguageUtil.get(company.getLocale(), entry.getType()),
473                                    entry.getUrl(),
474                                    fromAddress,
475                                    fromName,
476                                    company.getVirtualHost(),
477                                    LanguageUtil.get(
478                                            company.getLocale(),
479                                            (entry.isAlert() ? "alert" : "announcement")),
480                                    toAddress,
481                                    toName
482                            });
483    
484                    body = StringUtil.replace(
485                            body,
486                            new String[] {
487                                    "[$ENTRY_CONTENT$]",
488                                    "[$ENTRY_ID$]",
489                                    "[$ENTRY_TITLE$]",
490                                    "[$ENTRY_TYPE$]",
491                                    "[$ENTRY_URL$]",
492                                    "[$FROM_ADDRESS$]",
493                                    "[$FROM_NAME$]",
494                                    "[$PORTAL_URL$]",
495                                    "[$PORTLET_NAME$]",
496                                    "[$TO_ADDRESS$]",
497                                    "[$TO_NAME$]"
498                            },
499                            new String[] {
500                                    entry.getContent(),
501                                    String.valueOf(entry.getEntryId()),
502                                    entry.getTitle(),
503                                    LanguageUtil.get(company.getLocale(), entry.getType()),
504                                    entry.getUrl(),
505                                    fromAddress,
506                                    fromName,
507                                    company.getVirtualHost(),
508                                    LanguageUtil.get(
509                                            company.getLocale(),
510                                            (entry.isAlert() ? "alert" : "announcement")),
511                                    toAddress,
512                                    toName
513                            });
514    
515                    InternetAddress from = new InternetAddress(fromAddress, fromName);
516    
517                    InternetAddress to = new InternetAddress(toAddress, toName);
518    
519                    InternetAddress[] bulkAddressesArray = bulkAddresses.toArray(
520                            new InternetAddress[bulkAddresses.size()]);
521    
522                    MailMessage message = new MailMessage(
523                            from, to, subject, body, true);
524    
525                    message.setBulkAddresses(bulkAddressesArray);
526    
527                    mailService.sendEmail(message);
528            }
529    
530            protected void validate(String title, String content, String url)
531                    throws PortalException {
532    
533                    if (Validator.isNull(title)) {
534                            throw new EntryTitleException();
535                    }
536    
537                    if (Validator.isNull(content)) {
538                            throw new EntryContentException();
539                    }
540    
541                    if (!Validator.isUrl(url)) {
542                            throw new EntryURLException();
543                    }
544            }
545    
546            private static Log _log = LogFactoryUtil.getLog(
547                    AnnouncementsEntryLocalServiceImpl.class);
548    
549            private long _entryCheckInterval =
550                    PropsValues.ANNOUNCEMENTS_ENTRY_CHECK_INTERVAL * Time.MINUTE;
551    
552    }