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