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