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