001
014
015 package com.liferay.portlet.announcements.service.impl;
016
017 import com.liferay.portal.kernel.exception.PortalException;
018 import com.liferay.portal.kernel.interval.IntervalActionProcessor;
019 import com.liferay.portal.kernel.language.LanguageUtil;
020 import com.liferay.portal.kernel.log.Log;
021 import com.liferay.portal.kernel.log.LogFactoryUtil;
022 import com.liferay.portal.kernel.portlet.PortletProvider;
023 import com.liferay.portal.kernel.portlet.PortletProviderUtil;
024 import com.liferay.portal.kernel.util.ListUtil;
025 import com.liferay.portal.kernel.util.OrderByComparator;
026 import com.liferay.portal.kernel.util.PropsKeys;
027 import com.liferay.portal.kernel.util.Time;
028 import com.liferay.portal.kernel.util.Validator;
029 import com.liferay.portal.kernel.workflow.WorkflowConstants;
030 import com.liferay.portal.model.Company;
031 import com.liferay.portal.model.Group;
032 import com.liferay.portal.model.Organization;
033 import com.liferay.portal.model.ResourceConstants;
034 import com.liferay.portal.model.Role;
035 import com.liferay.portal.model.RoleConstants;
036 import com.liferay.portal.model.User;
037 import com.liferay.portal.model.UserGroup;
038 import com.liferay.portal.util.PortalUtil;
039 import com.liferay.portal.util.PrefsPropsUtil;
040 import com.liferay.portal.util.PropsValues;
041 import com.liferay.portal.util.SubscriptionSender;
042 import com.liferay.portlet.announcements.exception.EntryContentException;
043 import com.liferay.portlet.announcements.exception.EntryDisplayDateException;
044 import com.liferay.portlet.announcements.exception.EntryExpirationDateException;
045 import com.liferay.portlet.announcements.exception.EntryTitleException;
046 import com.liferay.portlet.announcements.exception.EntryURLException;
047 import com.liferay.portlet.announcements.model.AnnouncementsDelivery;
048 import com.liferay.portlet.announcements.model.AnnouncementsEntry;
049 import com.liferay.portlet.announcements.service.base.AnnouncementsEntryLocalServiceBaseImpl;
050 import com.liferay.util.ContentUtil;
051
052 import java.util.Date;
053 import java.util.LinkedHashMap;
054 import java.util.List;
055 import java.util.Locale;
056
057
061 public class AnnouncementsEntryLocalServiceImpl
062 extends AnnouncementsEntryLocalServiceBaseImpl {
063
064 @Override
065 public AnnouncementsEntry addEntry(
066 long userId, long classNameId, long classPK, String title,
067 String content, String url, String type, int displayDateMonth,
068 int displayDateDay, int displayDateYear, int displayDateHour,
069 int displayDateMinute, boolean displayImmediately,
070 int expirationDateMonth, int expirationDateDay,
071 int expirationDateYear, int expirationDateHour,
072 int expirationDateMinute, int priority, boolean alert)
073 throws PortalException {
074
075
076
077 User user = userPersistence.findByPrimaryKey(userId);
078
079 Date displayDate = new Date();
080
081 if (!displayImmediately) {
082 displayDate = PortalUtil.getDate(
083 displayDateMonth, displayDateDay, displayDateYear,
084 displayDateHour, displayDateMinute, user.getTimeZone(),
085 EntryDisplayDateException.class);
086 }
087
088 Date expirationDate = PortalUtil.getDate(
089 expirationDateMonth, expirationDateDay, expirationDateYear,
090 expirationDateHour, expirationDateMinute, user.getTimeZone(),
091 EntryExpirationDateException.class);
092
093 validate(title, content, url);
094
095 long entryId = counterLocalService.increment();
096
097 AnnouncementsEntry entry = announcementsEntryPersistence.create(
098 entryId);
099
100 entry.setCompanyId(user.getCompanyId());
101 entry.setUserId(user.getUserId());
102 entry.setUserName(user.getFullName());
103 entry.setClassNameId(classNameId);
104 entry.setClassPK(classPK);
105 entry.setTitle(title);
106 entry.setContent(content);
107 entry.setUrl(url);
108 entry.setType(type);
109 entry.setDisplayDate(displayDate);
110 entry.setExpirationDate(expirationDate);
111 entry.setPriority(priority);
112 entry.setAlert(alert);
113
114 announcementsEntryPersistence.update(entry);
115
116
117
118 resourceLocalService.addResources(
119 user.getCompanyId(), 0, user.getUserId(),
120 AnnouncementsEntry.class.getName(), entry.getEntryId(), false,
121 false, false);
122
123 return entry;
124 }
125
126
131 @Deprecated
132 @Override
133 public AnnouncementsEntry addEntry(
134 long userId, long classNameId, long classPK, String title,
135 String content, String url, String type, int displayDateMonth,
136 int displayDateDay, int displayDateYear, int displayDateHour,
137 int displayDateMinute, int expirationDateMonth,
138 int expirationDateDay, int expirationDateYear,
139 int expirationDateHour, int expirationDateMinute, int priority,
140 boolean alert)
141 throws PortalException {
142
143 return addEntry(
144 userId, classNameId, classPK, title, content, url, type,
145 displayDateMonth, displayDateDay, displayDateYear, displayDateHour,
146 displayDateMinute, false, expirationDateMonth, expirationDateDay,
147 expirationDateYear, expirationDateHour, expirationDateMinute,
148 priority, alert);
149 }
150
151 @Override
152 public void checkEntries() throws PortalException {
153 Date now = new Date();
154
155 if (_previousCheckDate == null) {
156 _previousCheckDate = new Date(
157 now.getTime() - _ANNOUNCEMENTS_ENTRY_CHECK_INTERVAL);
158 }
159
160 List<AnnouncementsEntry> entries =
161 announcementsEntryFinder.findByDisplayDate(now, _previousCheckDate);
162
163 if (_log.isDebugEnabled()) {
164 _log.debug("Processing " + entries.size() + " entries");
165 }
166
167 for (AnnouncementsEntry entry : entries) {
168 notifyUsers(entry);
169 }
170
171 _previousCheckDate = now;
172 }
173
174 @Override
175 public void deleteEntry(AnnouncementsEntry entry) throws PortalException {
176
177
178
179 announcementsEntryPersistence.remove(entry);
180
181
182
183 resourceLocalService.deleteResource(
184 entry.getCompanyId(), AnnouncementsEntry.class.getName(),
185 ResourceConstants.SCOPE_INDIVIDUAL, entry.getEntryId());
186
187
188
189 announcementsFlagLocalService.deleteFlags(entry.getEntryId());
190 }
191
192 @Override
193 public void deleteEntry(long entryId) throws PortalException {
194 AnnouncementsEntry entry =
195 announcementsEntryPersistence.findByPrimaryKey(entryId);
196
197 deleteEntry(entry);
198 }
199
200 @Override
201 public List<AnnouncementsEntry> getEntries(
202 long userId, LinkedHashMap<Long, long[]> scopes, boolean alert,
203 int flagValue, int start, int end) {
204
205 return getEntries(
206 userId, scopes, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, alert, flagValue,
207 start, end);
208 }
209
210 @Override
211 public List<AnnouncementsEntry> getEntries(
212 long userId, LinkedHashMap<Long, long[]> scopes, int displayDateMonth,
213 int displayDateDay, int displayDateYear, int displayDateHour,
214 int displayDateMinute, int expirationDateMonth, int expirationDateDay,
215 int expirationDateYear, int expirationDateHour,
216 int expirationDateMinute, boolean alert, int flagValue, int start,
217 int end) {
218
219 return announcementsEntryFinder.findByScopes(
220 userId, scopes, displayDateMonth, displayDateDay, displayDateYear,
221 displayDateHour, displayDateMinute, expirationDateMonth,
222 expirationDateDay, expirationDateYear, expirationDateHour,
223 expirationDateMinute, alert, flagValue, start, end);
224 }
225
226 @Override
227 public List<AnnouncementsEntry> getEntries(
228 long classNameId, long classPK, boolean alert, int start, int end) {
229
230 return announcementsEntryPersistence.findByC_C_A(
231 classNameId, classPK, alert, start, end);
232 }
233
234 @Override
235 public List<AnnouncementsEntry> getEntries(
236 long userId, long classNameId, long[] classPKs, int displayDateMonth,
237 int displayDateDay, int displayDateYear, int displayDateHour,
238 int displayDateMinute, int expirationDateMonth, int expirationDateDay,
239 int expirationDateYear, int expirationDateHour,
240 int expirationDateMinute, boolean alert, int flagValue, int start,
241 int end) {
242
243 return announcementsEntryFinder.findByScope(
244 userId, classNameId, classPKs, displayDateMonth, displayDateDay,
245 displayDateYear, displayDateHour, displayDateMinute,
246 expirationDateMonth, expirationDateDay, expirationDateYear,
247 expirationDateHour, expirationDateMinute, alert, flagValue, start,
248 end);
249 }
250
251 @Override
252 public int getEntriesCount(
253 long userId, LinkedHashMap<Long, long[]> scopes, boolean alert,
254 int flagValue) {
255
256 return getEntriesCount(
257 userId, scopes, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, alert, flagValue);
258 }
259
260 @Override
261 public int getEntriesCount(
262 long userId, LinkedHashMap<Long, long[]> scopes, int displayDateMonth,
263 int displayDateDay, int displayDateYear, int displayDateHour,
264 int displayDateMinute, int expirationDateMonth, int expirationDateDay,
265 int expirationDateYear, int expirationDateHour,
266 int expirationDateMinute, boolean alert, int flagValue) {
267
268 return announcementsEntryFinder.countByScopes(
269 userId, scopes, displayDateMonth, displayDateDay, displayDateYear,
270 displayDateHour, displayDateMinute, expirationDateMonth,
271 expirationDateDay, expirationDateYear, expirationDateHour,
272 expirationDateMinute, alert, flagValue);
273 }
274
275 @Override
276 public int getEntriesCount(long classNameId, long classPK, boolean alert) {
277 return announcementsEntryPersistence.countByC_C_A(
278 classNameId, classPK, alert);
279 }
280
281 @Override
282 public int getEntriesCount(
283 long userId, long classNameId, long[] classPKs, boolean alert,
284 int flagValue) {
285
286 return getEntriesCount(
287 userId, classNameId, classPKs, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, alert,
288 flagValue);
289 }
290
291 @Override
292 public int getEntriesCount(
293 long userId, long classNameId, long[] classPKs, int displayDateMonth,
294 int displayDateDay, int displayDateYear, int displayDateHour,
295 int displayDateMinute, int expirationDateMonth, int expirationDateDay,
296 int expirationDateYear, int expirationDateHour,
297 int expirationDateMinute, boolean alert, int flagValue) {
298
299 return announcementsEntryFinder.countByScope(
300 userId, classNameId, classPKs, displayDateMonth, displayDateDay,
301 displayDateYear, displayDateHour, displayDateMinute,
302 expirationDateMonth, expirationDateDay, expirationDateYear,
303 expirationDateHour, expirationDateMinute, alert, flagValue);
304 }
305
306 @Override
307 public AnnouncementsEntry getEntry(long entryId) throws PortalException {
308 return announcementsEntryPersistence.findByPrimaryKey(entryId);
309 }
310
311 @Override
312 public List<AnnouncementsEntry> getUserEntries(
313 long userId, int start, int end) {
314
315 return announcementsEntryPersistence.findByUserId(userId, start, end);
316 }
317
318 @Override
319 public int getUserEntriesCount(long userId) {
320 return announcementsEntryPersistence.countByUserId(userId);
321 }
322
323 @Override
324 public AnnouncementsEntry updateEntry(
325 long userId, long entryId, String title, String content, String url,
326 String type, int displayDateMonth, int displayDateDay,
327 int displayDateYear, int displayDateHour, int displayDateMinute,
328 boolean displayImmediately, int expirationDateMonth,
329 int expirationDateDay, int expirationDateYear,
330 int expirationDateHour, int expirationDateMinute, int priority)
331 throws PortalException {
332
333
334
335 User user = userPersistence.findByPrimaryKey(userId);
336
337 Date displayDate = new Date();
338
339 if (!displayImmediately) {
340 displayDate = PortalUtil.getDate(
341 displayDateMonth, displayDateDay, displayDateYear,
342 displayDateHour, displayDateMinute, user.getTimeZone(),
343 EntryDisplayDateException.class);
344 }
345
346 Date expirationDate = PortalUtil.getDate(
347 expirationDateMonth, expirationDateDay, expirationDateYear,
348 expirationDateHour, expirationDateMinute, user.getTimeZone(),
349 EntryExpirationDateException.class);
350
351 validate(title, content, url);
352
353 AnnouncementsEntry entry =
354 announcementsEntryPersistence.findByPrimaryKey(entryId);
355
356 entry.setTitle(title);
357 entry.setContent(content);
358 entry.setUrl(url);
359 entry.setType(type);
360 entry.setDisplayDate(displayDate);
361 entry.setExpirationDate(expirationDate);
362 entry.setPriority(priority);
363
364 announcementsEntryPersistence.update(entry);
365
366
367
368 announcementsFlagLocalService.deleteFlags(entry.getEntryId());
369
370 return entry;
371 }
372
373 protected void notifyUsers(AnnouncementsEntry entry)
374 throws PortalException {
375
376 Company company = companyPersistence.findByPrimaryKey(
377 entry.getCompanyId());
378
379 String className = entry.getClassName();
380 long classPK = entry.getClassPK();
381
382 String toName = PropsValues.ANNOUNCEMENTS_EMAIL_TO_NAME;
383 String toAddress = PropsValues.ANNOUNCEMENTS_EMAIL_TO_ADDRESS;
384
385 long teamId = 0;
386
387 LinkedHashMap<String, Object> params = new LinkedHashMap<>();
388
389 params.put("announcementsDeliveryEmailOrSms", entry.getType());
390
391 if (classPK > 0) {
392 if (className.equals(Group.class.getName())) {
393 Group group = groupPersistence.findByPrimaryKey(classPK);
394
395 toName = group.getDescriptiveName();
396
397 params.put("inherit", Boolean.TRUE);
398 params.put("usersGroups", classPK);
399 }
400 else if (className.equals(Organization.class.getName())) {
401 Organization organization =
402 organizationPersistence.findByPrimaryKey(classPK);
403
404 toName = organization.getName();
405
406 params.put(
407 "usersOrgsTree",
408 ListUtil.fromArray(new Organization[] {organization}));
409 }
410 else if (className.equals(Role.class.getName())) {
411 Role role = rolePersistence.findByPrimaryKey(classPK);
412
413 toName = role.getName();
414
415 if (role.getType() == RoleConstants.TYPE_REGULAR) {
416 params.put("inherit", Boolean.TRUE);
417 params.put("usersRoles", classPK);
418 }
419 else if (role.isTeam()) {
420 teamId = role.getClassPK();
421 }
422 else {
423 params.put(
424 "userGroupRole", new Long[] {Long.valueOf(0), classPK});
425 }
426 }
427 else if (className.equals(UserGroup.class.getName())) {
428 UserGroup userGroup = userGroupPersistence.findByPrimaryKey(
429 classPK);
430
431 toName = userGroup.getName();
432
433 params.put("usersUserGroups", classPK);
434 }
435 }
436
437 if (className.equals(User.class.getName())) {
438 User user = userPersistence.findByPrimaryKey(classPK);
439
440 if (Validator.isNull(user.getEmailAddress())) {
441 return;
442 }
443
444 notifyUsers(
445 ListUtil.fromArray(new User[] {user}), entry,
446 company.getLocale(), user.getEmailAddress(),
447 user.getFullName());
448 }
449 else {
450 notifyUsers(entry, teamId, params, toName, toAddress, company);
451 }
452 }
453
454 protected void notifyUsers(
455 final AnnouncementsEntry entry, final long teamId,
456 final LinkedHashMap<String, Object> params, final String toName,
457 final String toAddress, final Company company)
458 throws PortalException {
459
460 int total = 0;
461
462 if (teamId > 0) {
463 total = userLocalService.getTeamUsersCount(teamId);
464 }
465 else {
466 total = userLocalService.searchCount(
467 company.getCompanyId(), null, WorkflowConstants.STATUS_APPROVED,
468 params);
469 }
470
471 final IntervalActionProcessor<Void> intervalActionProcessor =
472 new IntervalActionProcessor<>(total);
473
474 intervalActionProcessor.setPerformIntervalActionMethod(
475 new IntervalActionProcessor.PerformIntervalActionMethod<Void>() {
476
477 @Override
478 public Void performIntervalAction(int start, int end)
479 throws PortalException {
480
481 List<User> users = null;
482
483 if (teamId > 0) {
484 users = userLocalService.getTeamUsers(
485 teamId, start, end);
486 }
487 else {
488 users = userLocalService.search(
489 company.getCompanyId(), null,
490 WorkflowConstants.STATUS_APPROVED, params, start,
491 end, (OrderByComparator<User>)null);
492 }
493
494 notifyUsers(
495 users, entry, company.getLocale(), toAddress, toName);
496
497 intervalActionProcessor.incrementStart(users.size());
498
499 return null;
500 }
501
502 });
503
504 intervalActionProcessor.performIntervalActions();
505 }
506
507 protected void notifyUsers(
508 List<User> users, AnnouncementsEntry entry, Locale locale,
509 String toAddress, String toName)
510 throws PortalException {
511
512 if (_log.isDebugEnabled()) {
513 _log.debug("Notifying " + users.size() + " users");
514 }
515
516 boolean notifyUsers = false;
517
518 SubscriptionSender subscriptionSender = new SubscriptionSender();
519
520 for (User user : users) {
521 AnnouncementsDelivery announcementsDelivery =
522 announcementsDeliveryLocalService.getUserDelivery(
523 user.getUserId(), entry.getType());
524
525 if (announcementsDelivery.isEmail()) {
526 subscriptionSender.addRuntimeSubscribers(
527 user.getEmailAddress(), user.getFullName());
528
529 notifyUsers = true;
530 }
531
532 if (announcementsDelivery.isSms()) {
533 String smsSn = user.getContact().getSmsSn();
534
535 subscriptionSender.addRuntimeSubscribers(
536 smsSn, user.getFullName());
537
538 notifyUsers = true;
539 }
540 }
541
542 if (!notifyUsers) {
543 return;
544 }
545
546 String body = ContentUtil.get(PropsValues.ANNOUNCEMENTS_EMAIL_BODY);
547 String fromAddress = PrefsPropsUtil.getStringFromNames(
548 entry.getCompanyId(), PropsKeys.ANNOUNCEMENTS_EMAIL_FROM_ADDRESS,
549 PropsKeys.ADMIN_EMAIL_FROM_ADDRESS);
550 String fromName = PrefsPropsUtil.getStringFromNames(
551 entry.getCompanyId(), PropsKeys.ANNOUNCEMENTS_EMAIL_FROM_NAME,
552 PropsKeys.ADMIN_EMAIL_FROM_NAME);
553 String subject = ContentUtil.get(
554 PropsValues.ANNOUNCEMENTS_EMAIL_SUBJECT);
555
556 subscriptionSender.setBody(body);
557 subscriptionSender.setCompanyId(entry.getCompanyId());
558 subscriptionSender.setContextAttribute(
559 "[$ENTRY_CONTENT$]", entry.getContent(), false);
560 subscriptionSender.setContextAttributes(
561 "[$ENTRY_ID$]", entry.getEntryId(), "[$ENTRY_TITLE$]",
562 entry.getTitle(), "[$ENTRY_TYPE$]",
563 LanguageUtil.get(locale, entry.getType()), "[$ENTRY_URL$]",
564 entry.getUrl(), "[$PORTLET_NAME$]",
565 LanguageUtil.get(
566 locale, (entry.isAlert() ? "alert" : "announcement")));
567 subscriptionSender.setFrom(fromAddress, fromName);
568 subscriptionSender.setHtmlFormat(true);
569 subscriptionSender.setMailId("announcements_entry", entry.getEntryId());
570
571 String portletId = PortletProviderUtil.getPortletId(
572 AnnouncementsEntry.class.getName(), PortletProvider.Action.VIEW);
573
574 subscriptionSender.setPortletId(portletId);
575
576 subscriptionSender.setScopeGroupId(entry.getGroupId());
577 subscriptionSender.setSubject(subject);
578
579 subscriptionSender.addRuntimeSubscribers(toAddress, toName);
580
581 subscriptionSender.flushNotificationsAsync();
582 }
583
584 protected void validate(String title, String content, String url)
585 throws PortalException {
586
587 if (Validator.isNull(title)) {
588 throw new EntryTitleException();
589 }
590
591 if (Validator.isNull(content)) {
592 throw new EntryContentException();
593 }
594
595 if (Validator.isNotNull(url) && !Validator.isUrl(url)) {
596 throw new EntryURLException();
597 }
598 }
599
600 private static final long _ANNOUNCEMENTS_ENTRY_CHECK_INTERVAL =
601 PropsValues.ANNOUNCEMENTS_ENTRY_CHECK_INTERVAL * Time.MINUTE;
602
603 private static final Log _log = LogFactoryUtil.getLog(
604 AnnouncementsEntryLocalServiceImpl.class);
605
606 private Date _previousCheckDate;
607
608 }