1
14
15 package com.liferay.portlet.messageboards.service.impl;
16
17 import com.liferay.portal.kernel.exception.PortalException;
18 import com.liferay.portal.kernel.exception.SystemException;
19 import com.liferay.portal.kernel.util.GetterUtil;
20 import com.liferay.portal.kernel.util.HtmlUtil;
21 import com.liferay.portal.kernel.util.ObjectValuePair;
22 import com.liferay.portal.kernel.util.PropsKeys;
23 import com.liferay.portal.kernel.util.StringPool;
24 import com.liferay.portal.kernel.util.StringUtil;
25 import com.liferay.portal.model.Company;
26 import com.liferay.portal.model.Group;
27 import com.liferay.portal.model.User;
28 import com.liferay.portal.security.auth.PrincipalException;
29 import com.liferay.portal.security.permission.ActionKeys;
30 import com.liferay.portal.service.ServiceContext;
31 import com.liferay.portal.theme.ThemeDisplay;
32 import com.liferay.portal.util.PortalUtil;
33 import com.liferay.portal.util.PropsUtil;
34 import com.liferay.portlet.messageboards.LockedThreadException;
35 import com.liferay.portlet.messageboards.NoSuchCategoryException;
36 import com.liferay.portlet.messageboards.model.MBCategory;
37 import com.liferay.portlet.messageboards.model.MBMessage;
38 import com.liferay.portlet.messageboards.model.MBMessageDisplay;
39 import com.liferay.portlet.messageboards.model.MBThread;
40 import com.liferay.portlet.messageboards.model.MBThreadConstants;
41 import com.liferay.portlet.messageboards.service.base.MBMessageServiceBaseImpl;
42 import com.liferay.portlet.messageboards.service.permission.MBCategoryPermission;
43 import com.liferay.portlet.messageboards.service.permission.MBDiscussionPermission;
44 import com.liferay.portlet.messageboards.service.permission.MBMessagePermission;
45 import com.liferay.portlet.messageboards.util.BBCodeUtil;
46 import com.liferay.portlet.messageboards.util.comparator.MessageCreateDateComparator;
47 import com.liferay.util.RSSUtil;
48
49 import com.sun.syndication.feed.synd.SyndContent;
50 import com.sun.syndication.feed.synd.SyndContentImpl;
51 import com.sun.syndication.feed.synd.SyndEntry;
52 import com.sun.syndication.feed.synd.SyndEntryImpl;
53 import com.sun.syndication.feed.synd.SyndFeed;
54 import com.sun.syndication.feed.synd.SyndFeedImpl;
55 import com.sun.syndication.io.FeedException;
56
57 import java.util.ArrayList;
58 import java.util.Iterator;
59 import java.util.List;
60
61
67 public class MBMessageServiceImpl extends MBMessageServiceBaseImpl {
68
69 public MBMessage addDiscussionMessage(
70 String className, long classPK, long threadId,
71 long parentMessageId, String subject, String body,
72 ServiceContext serviceContext)
73 throws PortalException, SystemException {
74
75 User user = getUser();
76
77 MBDiscussionPermission.check(
78 getPermissionChecker(), user.getCompanyId(),
79 serviceContext.getScopeGroupId(), className, classPK,
80 user.getUserId(), ActionKeys.ADD_DISCUSSION);
81
82 return mbMessageLocalService.addDiscussionMessage(
83 getUserId(), null, className, classPK, threadId,
84 parentMessageId, subject, body, serviceContext);
85 }
86
87 public MBMessage addMessage(
88 long groupId, long categoryId, String subject, String body,
89 List<ObjectValuePair<String, byte[]>> files,
90 boolean anonymous, double priority, boolean allowPingbacks,
91 ServiceContext serviceContext)
92 throws PortalException, SystemException {
93
94 MBCategoryPermission.check(
95 getPermissionChecker(), groupId, categoryId,
96 ActionKeys.ADD_MESSAGE);
97
98 if (!MBCategoryPermission.contains(
99 getPermissionChecker(), groupId, categoryId,
100 ActionKeys.ADD_FILE)) {
101
102 files.clear();
103 }
104
105 if (!MBCategoryPermission.contains(
106 getPermissionChecker(), groupId, categoryId,
107 ActionKeys.UPDATE_THREAD_PRIORITY)) {
108
109 priority = MBThreadConstants.PRIORITY_NOT_GIVEN;
110 }
111
112 return mbMessageLocalService.addMessage(
113 getGuestOrUserId(), null, groupId, categoryId, subject, body, files,
114 anonymous, priority, allowPingbacks, serviceContext);
115 }
116
117 public MBMessage addMessage(
118 long groupId, long categoryId, long threadId, long parentMessageId,
119 String subject, String body,
120 List<ObjectValuePair<String, byte[]>> files, boolean anonymous,
121 double priority, boolean allowPingbacks,
122 ServiceContext serviceContext)
123 throws PortalException, SystemException {
124
125 checkReplyToPermission(groupId, categoryId, parentMessageId);
126
127 if (lockLocalService.isLocked(
128 MBThread.class.getName(), threadId)) {
129
130 throw new LockedThreadException();
131 }
132
133 if (!MBCategoryPermission.contains(
134 getPermissionChecker(), groupId, categoryId,
135 ActionKeys.ADD_FILE)) {
136
137 files.clear();
138 }
139
140 if (!MBCategoryPermission.contains(
141 getPermissionChecker(), groupId, categoryId,
142 ActionKeys.UPDATE_THREAD_PRIORITY)) {
143
144 priority = MBThreadConstants.PRIORITY_NOT_GIVEN;
145 }
146
147 return mbMessageLocalService.addMessage(
148 getGuestOrUserId(), null, groupId, categoryId, threadId,
149 parentMessageId, subject, body, files, anonymous, priority,
150 allowPingbacks, serviceContext);
151 }
152
153 public void deleteDiscussionMessage(
154 long groupId, String className, long classPK, long messageId)
155 throws PortalException, SystemException {
156
157 User user = getUser();
158
159 MBDiscussionPermission.check(
160 getPermissionChecker(), user.getCompanyId(), groupId, className,
161 classPK, messageId, user.getUserId(), ActionKeys.DELETE_DISCUSSION);
162
163 mbMessageLocalService.deleteDiscussionMessage(messageId);
164 }
165
166 public void deleteMessage(long messageId)
167 throws PortalException, SystemException {
168
169 MBMessagePermission.check(
170 getPermissionChecker(), messageId, ActionKeys.DELETE);
171
172 mbMessageLocalService.deleteMessage(messageId);
173 }
174
175 public List<MBMessage> getCategoryMessages(
176 long groupId, long categoryId, int status, int start, int end)
177 throws PortalException, SystemException {
178
179 List<MBMessage> messages = new ArrayList<MBMessage>();
180
181 Iterator<MBMessage> itr = mbMessageLocalService.getCategoryMessages(
182 groupId, categoryId, status, start, end).iterator();
183
184 while (itr.hasNext()) {
185 MBMessage message = itr.next();
186
187 if (MBMessagePermission.contains(
188 getPermissionChecker(), message, ActionKeys.VIEW)) {
189
190 messages.add(message);
191 }
192 }
193
194 return messages;
195 }
196
197 public int getCategoryMessagesCount(
198 long groupId, long categoryId, int status)
199 throws SystemException {
200
201 return mbMessageLocalService.getCategoryMessagesCount(
202 groupId, categoryId, status);
203 }
204
205 public String getCategoryMessagesRSS(
206 long groupId, long categoryId, int status, int max, String type,
207 double version, String displayStyle, String feedURL,
208 String entryURL, ThemeDisplay themeDisplay)
209 throws PortalException, SystemException {
210
211 String name = StringPool.BLANK;
212 String description = StringPool.BLANK;
213
214 try {
215 MBCategory category = mbCategoryLocalService.getCategory(
216 categoryId);
217
218 name = category.getName();
219 description = category.getDescription();
220 }
221 catch (NoSuchCategoryException nsce) {
222 Group group = groupLocalService.getGroup(categoryId);
223
224 name = group.getName();
225 description = group.getDescription();
226 }
227
228 List<MBMessage> messages = new ArrayList<MBMessage>();
229
230 int lastIntervalStart = 0;
231 boolean listNotExhausted = true;
232 MessageCreateDateComparator comparator =
233 new MessageCreateDateComparator(false);
234
235 while ((messages.size() < max) && listNotExhausted) {
236 List<MBMessage> messageList =
237 mbMessageLocalService.getCategoryMessages(
238 groupId, categoryId, status, lastIntervalStart,
239 lastIntervalStart + max, comparator);
240
241 Iterator<MBMessage> itr = messageList.iterator();
242
243 lastIntervalStart += max;
244 listNotExhausted = (messageList.size() == max);
245
246 while (itr.hasNext() && (messages.size() < max)) {
247 MBMessage message = itr.next();
248
249 if (MBMessagePermission.contains(
250 getPermissionChecker(), message, ActionKeys.VIEW)) {
251
252 messages.add(message);
253 }
254 }
255 }
256
257 return exportToRSS(
258 name, description, type, version, displayStyle, feedURL, entryURL,
259 messages, themeDisplay);
260 }
261
262 public String getCompanyMessagesRSS(
263 long companyId, int status, int max, String type, double version,
264 String displayStyle, String feedURL, String entryURL,
265 ThemeDisplay themeDisplay)
266 throws PortalException, SystemException {
267
268 Company company = companyPersistence.findByPrimaryKey(companyId);
269
270 String name = company.getName();
271 String description = company.getName();
272
273 List<MBMessage> messages = new ArrayList<MBMessage>();
274
275 int lastIntervalStart = 0;
276 boolean listNotExhausted = true;
277 MessageCreateDateComparator comparator =
278 new MessageCreateDateComparator(false);
279
280 while ((messages.size() < max) && listNotExhausted) {
281 List<MBMessage> messageList =
282 mbMessageLocalService.getCompanyMessages(
283 companyId, status, lastIntervalStart,
284 lastIntervalStart + max, comparator);
285
286 Iterator<MBMessage> itr = messageList.iterator();
287
288 lastIntervalStart += max;
289 listNotExhausted = (messageList.size() == max);
290
291 while (itr.hasNext() && (messages.size() < max)) {
292 MBMessage message = itr.next();
293
294 if (MBMessagePermission.contains(
295 getPermissionChecker(), message, ActionKeys.VIEW)) {
296
297 messages.add(message);
298 }
299 }
300 }
301
302 return exportToRSS(
303 name, description, type, version, displayStyle, feedURL, entryURL,
304 messages, themeDisplay);
305 }
306
307 public String getGroupMessagesRSS(
308 long groupId, int status, int max, String type, double version,
309 String displayStyle, String feedURL, String entryURL,
310 ThemeDisplay themeDisplay)
311 throws PortalException, SystemException {
312
313 String name = StringPool.BLANK;
314 String description = StringPool.BLANK;
315
316 List<MBMessage> messages = new ArrayList<MBMessage>();
317
318 int lastIntervalStart = 0;
319 boolean listNotExhausted = true;
320 MessageCreateDateComparator comparator =
321 new MessageCreateDateComparator(false);
322
323 while ((messages.size() < max) && listNotExhausted) {
324 List<MBMessage> messageList =
325 mbMessageLocalService.getGroupMessages(
326 groupId, status, lastIntervalStart, lastIntervalStart + max,
327 comparator);
328
329 Iterator<MBMessage> itr = messageList.iterator();
330
331 lastIntervalStart += max;
332 listNotExhausted = (messageList.size() == max);
333
334 while (itr.hasNext() && (messages.size() < max)) {
335 MBMessage message = itr.next();
336
337 if (MBMessagePermission.contains(
338 getPermissionChecker(), message, ActionKeys.VIEW)) {
339
340 messages.add(message);
341 }
342 }
343 }
344
345 if (messages.size() > 0) {
346 MBMessage message = messages.get(messages.size() - 1);
347
348 name = message.getSubject();
349 description = message.getSubject();
350 }
351
352 return exportToRSS(
353 name, description, type, version, displayStyle, feedURL, entryURL,
354 messages, themeDisplay);
355 }
356
357 public String getGroupMessagesRSS(
358 long groupId, long userId, int status, int max, String type,
359 double version, String displayStyle, String feedURL,
360 String entryURL, ThemeDisplay themeDisplay)
361 throws PortalException, SystemException {
362
363 String name = StringPool.BLANK;
364 String description = StringPool.BLANK;
365
366 List<MBMessage> messages = new ArrayList<MBMessage>();
367
368 int lastIntervalStart = 0;
369 boolean listNotExhausted = true;
370 MessageCreateDateComparator comparator =
371 new MessageCreateDateComparator(false);
372
373 while ((messages.size() < max) && listNotExhausted) {
374 List<MBMessage> messageList =
375 mbMessageLocalService.getGroupMessages(
376 groupId, userId, status, lastIntervalStart,
377 lastIntervalStart + max, comparator);
378
379 Iterator<MBMessage> itr = messageList.iterator();
380
381 lastIntervalStart += max;
382 listNotExhausted = (messageList.size() == max);
383
384 while (itr.hasNext() && (messages.size() < max)) {
385 MBMessage message = itr.next();
386
387 if (MBMessagePermission.contains(
388 getPermissionChecker(), message, ActionKeys.VIEW)) {
389
390 messages.add(message);
391 }
392 }
393 }
394
395 if (messages.size() > 0) {
396 MBMessage message = messages.get(messages.size() - 1);
397
398 name = message.getSubject();
399 description = message.getSubject();
400 }
401
402 return exportToRSS(
403 name, description, type, version, displayStyle, feedURL, entryURL,
404 messages, themeDisplay);
405 }
406
407 public MBMessage getMessage(long messageId)
408 throws PortalException, SystemException {
409
410 MBMessagePermission.check(
411 getPermissionChecker(), messageId, ActionKeys.VIEW);
412
413 return mbMessageLocalService.getMessage(messageId);
414 }
415
416 public MBMessageDisplay getMessageDisplay(
417 long messageId, int status, String threadView)
418 throws PortalException, SystemException {
419
420 MBMessagePermission.check(
421 getPermissionChecker(), messageId, ActionKeys.VIEW);
422
423 return mbMessageLocalService.getMessageDisplay(
424 messageId, status, threadView);
425 }
426
427 public String getThreadMessagesRSS(
428 long threadId, int status, int max, String type, double version,
429 String displayStyle, String feedURL, String entryURL,
430 ThemeDisplay themeDisplay)
431 throws PortalException, SystemException {
432
433 String name = StringPool.BLANK;
434 String description = StringPool.BLANK;
435
436 List<MBMessage> messages = new ArrayList<MBMessage>();
437
438 MessageCreateDateComparator comparator =
439 new MessageCreateDateComparator(false);
440
441 Iterator<MBMessage> itr = mbMessageLocalService.getThreadMessages(
442 threadId, status, comparator).iterator();
443
444 while (itr.hasNext() && (messages.size() < max)) {
445 MBMessage message = itr.next();
446
447 if (MBMessagePermission.contains(
448 getPermissionChecker(), message, ActionKeys.VIEW)) {
449
450 messages.add(message);
451 }
452 }
453
454 if (messages.size() > 0) {
455 MBMessage message = messages.get(messages.size() - 1);
456
457 name = message.getSubject();
458 description = message.getSubject();
459 }
460
461 return exportToRSS(
462 name, description, type, version, displayStyle, feedURL, entryURL,
463 messages, themeDisplay);
464 }
465
466 public void subscribeMessage(long messageId)
467 throws PortalException, SystemException {
468
469 MBMessagePermission.check(
470 getPermissionChecker(), messageId, ActionKeys.SUBSCRIBE);
471
472 mbMessageLocalService.subscribeMessage(getUserId(), messageId);
473 }
474
475 public void unsubscribeMessage(long messageId)
476 throws PortalException, SystemException {
477
478 MBMessagePermission.check(
479 getPermissionChecker(), messageId, ActionKeys.SUBSCRIBE);
480
481 mbMessageLocalService.unsubscribeMessage(getUserId(), messageId);
482 }
483
484 public MBMessage updateDiscussionMessage(
485 String className, long classPK, long messageId, String subject,
486 String body, ServiceContext serviceContext)
487 throws PortalException, SystemException {
488
489 User user = getUser();
490
491 MBDiscussionPermission.check(
492 getPermissionChecker(), user.getCompanyId(),
493 serviceContext.getScopeGroupId(), className, classPK, messageId,
494 user.getUserId(), ActionKeys.UPDATE_DISCUSSION);
495
496 return mbMessageLocalService.updateDiscussionMessage(
497 getUserId(), messageId, subject, body, serviceContext.getStatus());
498 }
499
500 public MBMessage updateMessage(
501 long messageId, String subject, String body,
502 List<ObjectValuePair<String, byte[]>> files,
503 List<String> existingFiles, double priority, boolean allowPingbacks,
504 ServiceContext serviceContext)
505 throws PortalException, SystemException {
506
507 MBMessage message = mbMessageLocalService.getMessage(messageId);
508
509 MBMessagePermission.check(
510 getPermissionChecker(), messageId, ActionKeys.UPDATE);
511
512 if (lockLocalService.isLocked(
513 MBThread.class.getName(), message.getThreadId())) {
514
515 throw new LockedThreadException();
516 }
517
518 if (!MBCategoryPermission.contains(
519 getPermissionChecker(), message.getGroupId(),
520 message.getCategoryId(), ActionKeys.ADD_FILE)) {
521
522 files.clear();
523 }
524
525 if (!MBCategoryPermission.contains(
526 getPermissionChecker(), message.getGroupId(),
527 message.getCategoryId(), ActionKeys.UPDATE_THREAD_PRIORITY)) {
528
529 MBThread thread = mbThreadLocalService.getThread(
530 message.getThreadId());
531
532 priority = thread.getPriority();
533 }
534
535 return mbMessageLocalService.updateMessage(
536 getUserId(), messageId, subject, body, files, existingFiles,
537 priority, allowPingbacks, serviceContext);
538 }
539
540 protected void checkReplyToPermission(
541 long groupId, long categoryId, long parentMessageId)
542 throws PortalException, SystemException {
543
544 if (parentMessageId > 0) {
545 if (MBCategoryPermission.contains(
546 getPermissionChecker(), groupId, categoryId,
547 ActionKeys.ADD_MESSAGE)) {
548
549 return;
550 }
551
552 MBMessage parentMessage = mbMessagePersistence.fetchByPrimaryKey(
553 parentMessageId);
554
555 if ((parentMessage == null) ||
556 !MBCategoryPermission.contains(
557 getPermissionChecker(), groupId, categoryId,
558 ActionKeys.REPLY_TO_MESSAGE)) {
559
560 throw new PrincipalException();
561 }
562 }
563 else {
564 MBCategoryPermission.check(
565 getPermissionChecker(), groupId, categoryId,
566 ActionKeys.ADD_MESSAGE);
567 }
568 }
569
570 protected String exportToRSS(
571 String name, String description, String type, double version,
572 String displayStyle, String feedURL, String entryURL,
573 List<MBMessage> messages, ThemeDisplay themeDisplay)
574 throws SystemException {
575
576 SyndFeed syndFeed = new SyndFeedImpl();
577
578 syndFeed.setFeedType(RSSUtil.getFeedType(type, version));
579 syndFeed.setTitle(name);
580 syndFeed.setLink(feedURL);
581 syndFeed.setDescription(description);
582
583 List<SyndEntry> entries = new ArrayList<SyndEntry>();
584
585 syndFeed.setEntries(entries);
586
587 Iterator<MBMessage> itr = messages.iterator();
588
589 while (itr.hasNext()) {
590 MBMessage message = itr.next();
591
592 String author = PortalUtil.getUserName(
593 message.getUserId(), message.getUserName());
594
595 String value = null;
596
597 if (displayStyle.equals(RSSUtil.DISPLAY_STYLE_ABSTRACT)) {
598 value = StringUtil.shorten(
599 HtmlUtil.extractText(message.getBody()),
600 _RSS_ABSTRACT_LENGTH, StringPool.BLANK);
601 }
602 else if (displayStyle.equals(RSSUtil.DISPLAY_STYLE_TITLE)) {
603 value = StringPool.BLANK;
604 }
605 else {
606 value = BBCodeUtil.getHTML(message);
607
608 value = StringUtil.replace(
609 value,
610 new String[] {
611 "@theme_images_path@",
612 "href=\"/",
613 "src=\"/"
614 },
615 new String[] {
616 themeDisplay.getURLPortal() +
617 themeDisplay.getPathThemeImages(),
618 "href=\"" + themeDisplay.getURLPortal() + "/",
619 "src=\"" + themeDisplay.getURLPortal() + "/"
620 });
621 }
622
623 SyndEntry syndEntry = new SyndEntryImpl();
624
625 if (!message.isAnonymous()) {
626 syndEntry.setAuthor(author);
627 }
628
629 syndEntry.setTitle(message.getSubject());
630 syndEntry.setLink(
631 entryURL + "&messageId=" + message.getMessageId());
632 syndEntry.setUri(syndEntry.getLink());
633 syndEntry.setPublishedDate(message.getCreateDate());
634 syndEntry.setUpdatedDate(message.getModifiedDate());
635
636 SyndContent syndContent = new SyndContentImpl();
637
638 syndContent.setType(RSSUtil.DEFAULT_ENTRY_TYPE);
639 syndContent.setValue(value);
640
641 syndEntry.setDescription(syndContent);
642
643 entries.add(syndEntry);
644 }
645
646 try {
647 return RSSUtil.export(syndFeed);
648 }
649 catch (FeedException fe) {
650 throw new SystemException(fe);
651 }
652 }
653
654 private static final int _RSS_ABSTRACT_LENGTH = GetterUtil.getInteger(
655 PropsUtil.get(PropsKeys.MESSAGE_BOARDS_RSS_ABSTRACT_LENGTH));
656
657 }