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