1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17   * SOFTWARE.
18   */
19  
20  package com.liferay.portlet.announcements.service.impl;
21  
22  import com.liferay.portal.PortalException;
23  import com.liferay.portal.SystemException;
24  import com.liferay.portal.kernel.dao.orm.QueryUtil;
25  import com.liferay.portal.kernel.language.LanguageUtil;
26  import com.liferay.portal.kernel.log.Log;
27  import com.liferay.portal.kernel.log.LogFactoryUtil;
28  import com.liferay.portal.kernel.mail.MailMessage;
29  import com.liferay.portal.kernel.util.StringUtil;
30  import com.liferay.portal.kernel.util.Validator;
31  import com.liferay.portal.model.Company;
32  import com.liferay.portal.model.Group;
33  import com.liferay.portal.model.Organization;
34  import com.liferay.portal.model.Role;
35  import com.liferay.portal.model.User;
36  import com.liferay.portal.model.UserGroup;
37  import com.liferay.portal.util.ContentUtil;
38  import com.liferay.portal.util.PortalUtil;
39  import com.liferay.portal.util.PropsValues;
40  import com.liferay.portlet.announcements.EntryContentException;
41  import com.liferay.portlet.announcements.EntryDisplayDateException;
42  import com.liferay.portlet.announcements.EntryExpirationDateException;
43  import com.liferay.portlet.announcements.EntryTitleException;
44  import com.liferay.portlet.announcements.job.CheckEntryJob;
45  import com.liferay.portlet.announcements.model.AnnouncementsDelivery;
46  import com.liferay.portlet.announcements.model.AnnouncementsEntry;
47  import com.liferay.portlet.announcements.service.base.AnnouncementsEntryLocalServiceBaseImpl;
48  
49  import java.io.IOException;
50  
51  import java.util.ArrayList;
52  import java.util.Date;
53  import java.util.LinkedHashMap;
54  import java.util.List;
55  
56  import javax.mail.internet.InternetAddress;
57  
58  /**
59   * <a href="AnnouncementsEntryLocalServiceImpl.java.html"><b><i>View Source</i>
60   * </b></a>
61   *
62   * @author Brian Wing Shun Chan
63   * @author Raymond Augé
64   *
65   */
66  public class AnnouncementsEntryLocalServiceImpl
67      extends AnnouncementsEntryLocalServiceBaseImpl {
68  
69      public AnnouncementsEntry addEntry(
70              long userId, long classNameId, long classPK, String title,
71              String content, String url, String type, int displayDateMonth,
72              int displayDateDay, int displayDateYear, int displayDateHour,
73              int displayDateMinute, int expirationDateMonth,
74              int expirationDateDay, int expirationDateYear,
75              int expirationDateHour, int expirationDateMinute, int priority,
76              boolean alert)
77          throws PortalException, SystemException {
78  
79          // Entry
80  
81          User user = userPersistence.findByPrimaryKey(userId);
82  
83          Date displayDate = PortalUtil.getDate(
84              displayDateMonth, displayDateDay, displayDateYear, displayDateHour,
85              displayDateMinute, user.getTimeZone(),
86              new EntryDisplayDateException());
87  
88          Date expirationDate = PortalUtil.getDate(
89              expirationDateMonth, expirationDateDay, expirationDateYear,
90              expirationDateHour, expirationDateMinute, user.getTimeZone(),
91              new EntryExpirationDateException());
92  
93          Date now = new Date();
94  
95          validate(title, content);
96  
97          long entryId = counterLocalService.increment();
98  
99          AnnouncementsEntry entry = announcementsEntryPersistence.create(
100             entryId);
101 
102         entry.setCompanyId(user.getCompanyId());
103         entry.setUserId(user.getUserId());
104         entry.setUserName(user.getFullName());
105         entry.setCreateDate(now);
106         entry.setModifiedDate(now);
107         entry.setClassNameId(classNameId);
108         entry.setClassPK(classPK);
109         entry.setTitle(title);
110         entry.setContent(content);
111         entry.setUrl(url);
112         entry.setType(type);
113         entry.setDisplayDate(displayDate);
114         entry.setExpirationDate(expirationDate);
115         entry.setPriority(priority);
116         entry.setAlert(alert);
117 
118         announcementsEntryPersistence.update(entry, false);
119 
120         // Resources
121 
122         resourceLocalService.addResources(
123             user.getCompanyId(), 0, user.getUserId(),
124             AnnouncementsEntry.class.getName(), entry.getEntryId(), false,
125             false, false);
126 
127         return entry;
128     }
129 
130     public void checkEntries() throws PortalException, SystemException {
131         Date now = new Date();
132 
133         List<AnnouncementsEntry> entries =
134             announcementsEntryFinder.findByDisplayDate(
135                 now, new Date(now.getTime() - CheckEntryJob.INTERVAL));
136 
137         if (_log.isDebugEnabled()) {
138             _log.debug("Processing " + entries.size() + " entries");
139         }
140 
141         for (AnnouncementsEntry entry : entries) {
142             try {
143                 notifyUsers(entry);
144             }
145             catch (IOException ioe) {
146                 throw new SystemException(ioe);
147             }
148         }
149     }
150 
151     public void deleteEntry(long entryId)
152         throws PortalException, SystemException {
153 
154         // Flags
155 
156         announcementsFlagLocalService.deleteFlags(entryId);
157 
158         // Entry
159 
160         announcementsEntryPersistence.remove(entryId);
161     }
162 
163     public AnnouncementsEntry getEntry(long entryId)
164         throws PortalException, SystemException {
165 
166         return announcementsEntryPersistence.findByPrimaryKey(entryId);
167     }
168 
169     public List<AnnouncementsEntry> getEntries(
170             long classNameId, long classPK, boolean alert, int start, int end)
171         throws SystemException {
172 
173         return announcementsEntryPersistence.findByC_C_A(
174             classNameId, classPK, alert, start, end);
175     }
176 
177     public List<AnnouncementsEntry> getEntries(
178             long userId, long classNameId, long[] classPKs,
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.findByScope(
187             userId, classNameId, classPKs, displayDateMonth, displayDateDay,
188             displayDateYear, displayDateHour, displayDateMinute,
189             expirationDateMonth, expirationDateDay, expirationDateYear,
190             expirationDateHour, expirationDateMinute, alert, flagValue, start,
191             end);
192     }
193 
194     public List<AnnouncementsEntry> getEntries(
195             long userId, LinkedHashMap<Long, long[]> scopes, boolean alert,
196             int flagValue, int start, int end)
197         throws SystemException {
198 
199         return getEntries(
200             userId, scopes, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, alert, flagValue,
201             start, end);
202     }
203 
204     public List<AnnouncementsEntry> getEntries(
205             long userId, LinkedHashMap<Long, long[]> scopes,
206             int displayDateMonth, int displayDateDay, int displayDateYear,
207             int displayDateHour, int displayDateMinute, int expirationDateMonth,
208             int expirationDateDay, int expirationDateYear,
209             int expirationDateHour, int expirationDateMinute, boolean alert,
210             int flagValue, int start, int end)
211         throws SystemException {
212 
213         return announcementsEntryFinder.findByScopes(
214             userId, scopes, displayDateMonth, displayDateDay, displayDateYear,
215             displayDateHour, displayDateMinute, expirationDateMonth,
216             expirationDateDay, expirationDateYear, expirationDateHour,
217             expirationDateMinute, alert, flagValue, start, end);
218     }
219 
220     public int getEntriesCount(long classNameId, long classPK, boolean alert)
221         throws SystemException {
222 
223         return announcementsEntryPersistence.countByC_C_A(
224             classNameId, classPK, alert);
225     }
226 
227     public int getEntriesCount(
228             long userId, long classNameId, long[] classPKs, boolean alert,
229             int flagValue)
230         throws SystemException {
231 
232         return getEntriesCount(
233             userId, classNameId, classPKs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, alert,
234             flagValue);
235     }
236 
237     public int getEntriesCount(
238             long userId, long classNameId, long[] classPKs,
239             int displayDateMonth, int displayDateDay, int displayDateYear,
240             int displayDateHour, int displayDateMinute, int expirationDateMonth,
241             int expirationDateDay, int expirationDateYear,
242             int expirationDateHour, int expirationDateMinute, boolean alert,
243             int flagValue)
244         throws SystemException {
245 
246         return announcementsEntryFinder.countByScope(
247             userId, classNameId, classPKs, displayDateMonth, displayDateDay,
248             displayDateYear, displayDateHour, displayDateMinute,
249             expirationDateMonth, expirationDateDay, expirationDateYear,
250             expirationDateHour, expirationDateMinute, alert, flagValue);
251     }
252 
253     public int getEntriesCount(
254             long userId, LinkedHashMap<Long, long[]> scopes, boolean alert,
255             int flagValue)
256         throws SystemException {
257 
258         return getEntriesCount(
259             userId, scopes, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, alert, flagValue);
260     }
261 
262     public int getEntriesCount(
263             long userId, LinkedHashMap<Long, long[]> scopes,
264             int displayDateMonth, int displayDateDay, int displayDateYear,
265             int displayDateHour, int displayDateMinute, int expirationDateMonth,
266             int expirationDateDay, int expirationDateYear,
267             int expirationDateHour, int expirationDateMinute, boolean alert,
268             int flagValue)
269         throws SystemException {
270 
271         return announcementsEntryFinder.countByScopes(
272             userId, scopes, displayDateMonth, displayDateDay, displayDateYear,
273             displayDateHour, displayDateMinute, expirationDateMonth,
274             expirationDateDay, expirationDateYear, expirationDateHour,
275             expirationDateMinute, alert, flagValue);
276     }
277 
278     public List<AnnouncementsEntry> getUserEntries(
279             long userId, int start, int end)
280         throws SystemException {
281 
282         return announcementsEntryPersistence.findByUserId(userId, start, end);
283     }
284 
285     public int getUserEntriesCount(long userId) throws SystemException {
286         return announcementsEntryPersistence.countByUserId(userId);
287     }
288 
289     public AnnouncementsEntry updateEntry(
290             long userId, long entryId, String title, String content, String url,
291             String type, int displayDateMonth, int displayDateDay,
292             int displayDateYear, int displayDateHour, int displayDateMinute,
293             int expirationDateMonth, int expirationDateDay,
294             int expirationDateYear, int expirationDateHour,
295             int expirationDateMinute, int priority)
296         throws PortalException, SystemException {
297 
298         // Entry
299 
300         User user = userPersistence.findByPrimaryKey(userId);
301 
302         Date displayDate = PortalUtil.getDate(
303             displayDateMonth, displayDateDay, displayDateYear, displayDateHour,
304             displayDateMinute, user.getTimeZone(),
305             new EntryDisplayDateException());
306 
307         Date expirationDate = PortalUtil.getDate(
308             expirationDateMonth, expirationDateDay, expirationDateYear,
309             expirationDateHour, expirationDateMinute, user.getTimeZone(),
310             new EntryExpirationDateException());
311 
312         validate(title, content);
313 
314         AnnouncementsEntry entry =
315             announcementsEntryPersistence.findByPrimaryKey(entryId);
316 
317         entry.setModifiedDate(new Date());
318         entry.setTitle(title);
319         entry.setContent(content);
320         entry.setUrl(url);
321         entry.setType(type);
322         entry.setDisplayDate(displayDate);
323         entry.setExpirationDate(expirationDate);
324         entry.setPriority(priority);
325 
326         announcementsEntryPersistence.update(entry, false);
327 
328         // Flags
329 
330         announcementsFlagLocalService.deleteFlags(entry.getEntryId());
331 
332         return entry;
333     }
334 
335     protected void notifyUsers(AnnouncementsEntry entry)
336         throws IOException, PortalException, SystemException {
337 
338         Company company = companyPersistence.findByPrimaryKey(
339             entry.getCompanyId());
340 
341         String className = entry.getClassName();
342         long classPK = entry.getClassPK();
343 
344         String fromName = PropsValues.ANNOUNCEMENTS_EMAIL_FROM_NAME;
345         String fromAddress = PropsValues.ANNOUNCEMENTS_EMAIL_FROM_ADDRESS;
346 
347         String toName = PropsValues.ANNOUNCEMENTS_EMAIL_TO_NAME;
348         String toAddress = PropsValues.ANNOUNCEMENTS_EMAIL_TO_ADDRESS;
349 
350         LinkedHashMap<String, Object> params =
351             new LinkedHashMap<String, Object>();
352 
353         params.put("announcementsDeliveryEmailOrSms", entry.getType());
354 
355         if (classPK > 0) {
356             if (className.equals(Group.class.getName())) {
357                 Group group = groupPersistence.findByPrimaryKey(classPK);
358 
359                 toName = group.getName();
360 
361                 params.put("usersGroups", classPK);
362             }
363             else if (className.equals(Organization.class.getName())) {
364                 Organization organization =
365                     organizationPersistence.findByPrimaryKey(classPK);
366 
367                 toName = organization.getName();
368 
369                 params.put("usersOrgs", classPK);
370             }
371             else if (className.equals(Role.class.getName())) {
372                 Role role = rolePersistence.findByPrimaryKey(classPK);
373 
374                 toName = role.getName();
375 
376                 params.put("usersRoles", classPK);
377             }
378             else if (className.equals(UserGroup.class.getName())) {
379                 UserGroup userGroup = userGroupPersistence.findByPrimaryKey(
380                     classPK);
381 
382                 toName = userGroup.getName();
383 
384                 params.put("usersUserGroups", classPK);
385             }
386         }
387 
388         List<User> users = null;
389 
390         if (className.equals(User.class.getName())) {
391             User user = userLocalService.getUserById(classPK);
392 
393             toName = user.getFullName();
394             toAddress = user.getEmailAddress();
395 
396             users = new ArrayList<User>();
397 
398             users.add(user);
399         }
400         else {
401             users = userLocalService.search(
402                 company.getCompanyId(), null, Boolean.TRUE, params,
403                 QueryUtil.ALL_POS, QueryUtil.ALL_POS, null);
404         }
405 
406         if (_log.isDebugEnabled()) {
407             _log.debug("Notifying " + users.size() + " users");
408         }
409 
410         List<InternetAddress> bulkAddresses = new ArrayList<InternetAddress>();
411 
412         for (User user : users) {
413             AnnouncementsDelivery announcementsDelivery =
414                 announcementsDeliveryLocalService.getUserDelivery(
415                     user.getUserId(), entry.getType());
416 
417             if (announcementsDelivery.isEmail()) {
418                 InternetAddress address = new InternetAddress(
419                     user.getEmailAddress(), user.getFullName());
420 
421                 bulkAddresses.add(address);
422             }
423 
424             if (announcementsDelivery.isSms()) {
425                 String smsSn = user.getContact().getSmsSn();
426 
427                 InternetAddress address = new InternetAddress(
428                     smsSn, user.getFullName());
429 
430                 bulkAddresses.add(address);
431             }
432         }
433 
434         if (bulkAddresses.size() == 0) {
435             return;
436         }
437 
438         String subject = ContentUtil.get(
439             PropsValues.ANNOUNCEMENTS_EMAIL_SUBJECT);
440         String body = ContentUtil.get(PropsValues.ANNOUNCEMENTS_EMAIL_BODY);
441 
442         subject = StringUtil.replace(
443             subject,
444             new String[] {
445                 "[$ENTRY_CONTENT$]",
446                 "[$ENTRY_ID$]",
447                 "[$ENTRY_TITLE$]",
448                 "[$ENTRY_TYPE$]",
449                 "[$ENTRY_URL$]",
450                 "[$FROM_ADDRESS$]",
451                 "[$FROM_NAME$]",
452                 "[$PORTAL_URL$]",
453                 "[$PORTLET_NAME$]",
454                 "[$TO_ADDRESS$]",
455                 "[$TO_NAME$]"
456             },
457             new String[] {
458                 entry.getContent(),
459                 String.valueOf(entry.getEntryId()),
460                 entry.getTitle(),
461                 LanguageUtil.get(
462                     company.getCompanyId(), company.getLocale(),
463                     entry.getType()),
464                 entry.getUrl(),
465                 fromAddress,
466                 fromName,
467                 company.getVirtualHost(),
468                 LanguageUtil.get(
469                     company.getCompanyId(), company.getLocale(),
470                     (entry.isAlert() ? "alert" : "announcement")),
471                 toAddress,
472                 toName
473             });
474 
475         body = StringUtil.replace(
476             body,
477             new String[] {
478                 "[$ENTRY_CONTENT$]",
479                 "[$ENTRY_ID$]",
480                 "[$ENTRY_TITLE$]",
481                 "[$ENTRY_TYPE$]",
482                 "[$ENTRY_URL$]",
483                 "[$FROM_ADDRESS$]",
484                 "[$FROM_NAME$]",
485                 "[$PORTAL_URL$]",
486                 "[$PORTLET_NAME$]",
487                 "[$TO_ADDRESS$]",
488                 "[$TO_NAME$]"
489             },
490             new String[] {
491                 entry.getContent(),
492                 String.valueOf(entry.getEntryId()),
493                 entry.getTitle(),
494                 LanguageUtil.get(
495                     company.getCompanyId(), company.getLocale(),
496                     entry.getType()),
497                 entry.getUrl(),
498                 fromAddress,
499                 fromName,
500                 company.getVirtualHost(),
501                 LanguageUtil.get(
502                     company.getCompanyId(), company.getLocale(),
503                     (entry.isAlert() ? "alert" : "announcement")),
504                 toAddress,
505                 toName
506             });
507 
508         InternetAddress from = new InternetAddress(fromAddress, fromName);
509 
510         InternetAddress to = new InternetAddress(toAddress, toName);
511 
512         InternetAddress[] bulkAddressesArray = bulkAddresses.toArray(
513             new InternetAddress[bulkAddresses.size()]);
514 
515         MailMessage message = new MailMessage(
516             from, to, subject, body, true);
517 
518         message.setBulkAddresses(bulkAddressesArray);
519 
520         mailService.sendEmail(message);
521     }
522 
523     protected void validate(String title, String content)
524         throws PortalException {
525 
526         if (Validator.isNull(title)) {
527             throw new EntryTitleException();
528         }
529 
530         if (Validator.isNull(content)) {
531             throw new EntryContentException();
532         }
533     }
534 
535     private static Log _log =
536         LogFactoryUtil.getLog(AnnouncementsEntryLocalServiceImpl.class);
537 
538 }