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