001
014
015 package com.liferay.portlet.wiki.service.impl;
016
017 import com.liferay.portal.kernel.exception.PortalException;
018 import com.liferay.portal.kernel.exception.SystemException;
019 import com.liferay.portal.kernel.language.LanguageUtil;
020 import com.liferay.portal.kernel.util.CalendarFactoryUtil;
021 import com.liferay.portal.kernel.util.HtmlUtil;
022 import com.liferay.portal.kernel.util.HttpUtil;
023 import com.liferay.portal.kernel.util.ObjectValuePair;
024 import com.liferay.portal.kernel.util.OrderByComparator;
025 import com.liferay.portal.kernel.util.StringBundler;
026 import com.liferay.portal.kernel.util.StringPool;
027 import com.liferay.portal.kernel.util.StringUtil;
028 import com.liferay.portal.kernel.workflow.WorkflowConstants;
029 import com.liferay.portal.security.permission.ActionKeys;
030 import com.liferay.portal.service.ServiceContext;
031 import com.liferay.portal.util.PortalUtil;
032 import com.liferay.portal.util.PortletKeys;
033 import com.liferay.portal.util.PropsValues;
034 import com.liferay.portlet.wiki.NoSuchPageException;
035 import com.liferay.portlet.wiki.model.WikiNode;
036 import com.liferay.portlet.wiki.model.WikiPage;
037 import com.liferay.portlet.wiki.model.WikiPageConstants;
038 import com.liferay.portlet.wiki.service.base.WikiPageServiceBaseImpl;
039 import com.liferay.portlet.wiki.service.permission.WikiNodePermission;
040 import com.liferay.portlet.wiki.service.permission.WikiPagePermission;
041 import com.liferay.portlet.wiki.util.WikiUtil;
042 import com.liferay.portlet.wiki.util.comparator.PageCreateDateComparator;
043 import com.liferay.util.RSSUtil;
044
045 import com.sun.syndication.feed.synd.SyndContent;
046 import com.sun.syndication.feed.synd.SyndContentImpl;
047 import com.sun.syndication.feed.synd.SyndEntry;
048 import com.sun.syndication.feed.synd.SyndEntryImpl;
049 import com.sun.syndication.feed.synd.SyndFeed;
050 import com.sun.syndication.feed.synd.SyndFeedImpl;
051 import com.sun.syndication.feed.synd.SyndLink;
052 import com.sun.syndication.feed.synd.SyndLinkImpl;
053 import com.sun.syndication.io.FeedException;
054
055 import java.io.File;
056 import java.io.InputStream;
057
058 import java.util.ArrayList;
059 import java.util.Calendar;
060 import java.util.Date;
061 import java.util.Iterator;
062 import java.util.List;
063 import java.util.Locale;
064
065
070 public class WikiPageServiceImpl extends WikiPageServiceBaseImpl {
071
072 @Override
073 public WikiPage addPage(
074 long nodeId, String title, String content, String summary,
075 boolean minorEdit, ServiceContext serviceContext)
076 throws PortalException, SystemException {
077
078 WikiNodePermission.check(
079 getPermissionChecker(), nodeId, ActionKeys.ADD_PAGE);
080
081 return wikiPageLocalService.addPage(
082 getUserId(), nodeId, title, content, summary, minorEdit,
083 serviceContext);
084 }
085
086 @Override
087 public WikiPage addPage(
088 long nodeId, String title, String content, String summary,
089 boolean minorEdit, String format, String parentTitle,
090 String redirectTitle, ServiceContext serviceContext)
091 throws PortalException, SystemException {
092
093 WikiNodePermission.check(
094 getPermissionChecker(), nodeId, ActionKeys.ADD_PAGE);
095
096 return wikiPageLocalService.addPage(
097 getUserId(), nodeId, title, WikiPageConstants.VERSION_DEFAULT,
098 content, summary, minorEdit, format, true, parentTitle,
099 redirectTitle, serviceContext);
100 }
101
102 @Override
103 public void addPageAttachment(
104 long nodeId, String title, String fileName, File file)
105 throws PortalException, SystemException {
106
107 WikiNodePermission.check(
108 getPermissionChecker(), nodeId, ActionKeys.ADD_ATTACHMENT);
109
110 wikiPageLocalService.addPageAttachment(
111 getUserId(), nodeId, title, fileName, file);
112 }
113
114 @Override
115 public void addPageAttachment(
116 long nodeId, String title, String fileName, InputStream inputStream)
117 throws PortalException, SystemException {
118
119 WikiNodePermission.check(
120 getPermissionChecker(), nodeId, ActionKeys.ADD_ATTACHMENT);
121
122 wikiPageLocalService.addPageAttachment(
123 getUserId(), nodeId, title, fileName, inputStream);
124 }
125
126 @Override
127 public void addPageAttachments(
128 long nodeId, String title,
129 List<ObjectValuePair<String, InputStream>> inputStream)
130 throws PortalException, SystemException {
131
132 WikiNodePermission.check(
133 getPermissionChecker(), nodeId, ActionKeys.ADD_ATTACHMENT);
134
135 wikiPageLocalService.addPageAttachments(
136 getUserId(), nodeId, title, inputStream);
137 }
138
139 @Override
140 public String addTempPageAttachment(
141 long nodeId, String fileName, String tempFolderName,
142 InputStream inputStream)
143 throws PortalException, SystemException {
144
145 WikiNodePermission.check(
146 getPermissionChecker(), nodeId, ActionKeys.ADD_ATTACHMENT);
147
148 return wikiPageLocalService.addTempPageAttachment(
149 getUserId(), fileName, tempFolderName, inputStream);
150 }
151
152 @Override
153 public void changeParent(
154 long nodeId, String title, String newParentTitle,
155 ServiceContext serviceContext)
156 throws PortalException, SystemException {
157
158 WikiPagePermission.check(
159 getPermissionChecker(), nodeId, title, ActionKeys.DELETE);
160
161 WikiNodePermission.check(
162 getPermissionChecker(), nodeId, ActionKeys.ADD_PAGE);
163
164 wikiPageLocalService.changeParent(
165 getUserId(), nodeId, title, newParentTitle, serviceContext);
166 }
167
168 @Override
169 public void deletePage(long nodeId, String title)
170 throws PortalException, SystemException {
171
172 WikiPagePermission.check(
173 getPermissionChecker(), nodeId, title, ActionKeys.DELETE);
174
175 wikiPageLocalService.deletePage(nodeId, title);
176 }
177
178 @Override
179 public void deletePage(long nodeId, String title, double version)
180 throws PortalException, SystemException {
181
182 WikiPagePermission.check(
183 getPermissionChecker(), nodeId, title, version, ActionKeys.DELETE);
184
185 wikiPageLocalService.deletePage(nodeId, title, version);
186 }
187
188 @Override
189 public void deletePageAttachment(long nodeId, String title, String fileName)
190 throws PortalException, SystemException {
191
192 WikiPagePermission.check(
193 getPermissionChecker(), nodeId, title, ActionKeys.DELETE);
194
195 wikiPageLocalService.deletePageAttachment(nodeId, title, fileName);
196 }
197
198 @Override
199 public void deleteTempPageAttachment(
200 long nodeId, String fileName, String tempFolderName)
201 throws PortalException, SystemException {
202
203 WikiNodePermission.check(
204 getPermissionChecker(), nodeId, ActionKeys.ADD_ATTACHMENT);
205
206 wikiPageLocalService.deleteTempPageAttachment(
207 getUserId(), fileName, tempFolderName);
208 }
209
210 @Override
211 public List<WikiPage> getChildren(
212 long groupId, long nodeId, boolean head, String parentTitle)
213 throws PortalException, SystemException {
214
215 WikiNodePermission.check(
216 getPermissionChecker(), nodeId, ActionKeys.VIEW);
217
218 return wikiPagePersistence.filterFindByG_N_H_P_S(
219 groupId, nodeId, head, parentTitle,
220 WorkflowConstants.STATUS_APPROVED);
221 }
222
223 @Override
224 public WikiPage getDraftPage(long nodeId, String title)
225 throws PortalException, SystemException {
226
227 WikiPagePermission.check(
228 getPermissionChecker(), nodeId, title, ActionKeys.VIEW);
229
230 return wikiPageLocalService.getDraftPage(nodeId, title);
231 }
232
233 @Override
234 public List<WikiPage> getNodePages(long nodeId, int max)
235 throws PortalException, SystemException {
236
237 List<WikiPage> pages = new ArrayList<WikiPage>();
238
239 int lastIntervalStart = 0;
240 boolean listNotExhausted = true;
241
242 while ((pages.size() < max) && listNotExhausted) {
243 List<WikiPage> pageList = wikiPageLocalService.getPages(
244 nodeId, true, lastIntervalStart, lastIntervalStart + max);
245
246 Iterator<WikiPage> itr = pageList.iterator();
247
248 lastIntervalStart += max;
249 listNotExhausted = (pageList.size() == max);
250
251 while (itr.hasNext() && (pages.size() < max)) {
252 WikiPage page = itr.next();
253
254 if (WikiPagePermission.contains(
255 getPermissionChecker(), page, ActionKeys.VIEW)) {
256
257 pages.add(page);
258 }
259 }
260 }
261
262 return pages;
263 }
264
265 @Override
266 public String getNodePagesRSS(
267 long nodeId, int max, String type, double version,
268 String displayStyle, String feedURL, String entryURL)
269 throws PortalException, SystemException {
270
271 return getNodePagesRSS(
272 nodeId, max, type, version, displayStyle, feedURL, entryURL, null);
273 }
274
275 @Override
276 public String getNodePagesRSS(
277 long nodeId, int max, String type, double version,
278 String displayStyle, String feedURL, String entryURL,
279 String attachmentURLPrefix)
280 throws PortalException, SystemException {
281
282 WikiNodePermission.check(
283 getPermissionChecker(), nodeId, ActionKeys.VIEW);
284
285 WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
286
287 List<WikiPage> pages = getNodePages(nodeId, max);
288
289 return exportToRSS(
290 node.getCompanyId(), node.getName(), node.getDescription(), type,
291 version, displayStyle, feedURL, entryURL, attachmentURLPrefix,
292 pages, false, null);
293 }
294
295 @Override
296 public List<WikiPage> getOrphans(long groupId, long nodeId)
297 throws PortalException, SystemException {
298
299 WikiNodePermission.check(
300 getPermissionChecker(), nodeId, ActionKeys.VIEW);
301
302 List<WikiPage> pages = wikiPagePersistence.filterFindByG_N_H_S(
303 groupId, nodeId, true, WorkflowConstants.STATUS_APPROVED);
304
305 return WikiUtil.filterOrphans(pages);
306 }
307
308 @Override
309 public WikiPage getPage(long groupId, long nodeId, String title)
310 throws PortalException, SystemException {
311
312 List<WikiPage> pages = wikiPagePersistence.filterFindByG_N_T_H(
313 groupId, nodeId, title, true, 0, 1);
314
315 if (!pages.isEmpty()) {
316 return pages.get(0);
317 }
318 else {
319 throw new NoSuchPageException();
320 }
321 }
322
323 @Override
324 public WikiPage getPage(long nodeId, String title)
325 throws PortalException, SystemException {
326
327 WikiPagePermission.check(
328 getPermissionChecker(), nodeId, title, ActionKeys.VIEW);
329
330 return wikiPageLocalService.getPage(nodeId, title);
331 }
332
333 @Override
334 public WikiPage getPage(long nodeId, String title, Boolean head)
335 throws PortalException, SystemException {
336
337 WikiPagePermission.check(
338 getPermissionChecker(), nodeId, title, ActionKeys.VIEW);
339
340 return wikiPageLocalService.getPage(nodeId, title, head);
341 }
342
343 @Override
344 public WikiPage getPage(long nodeId, String title, double version)
345 throws PortalException, SystemException {
346
347 WikiPagePermission.check(
348 getPermissionChecker(), nodeId, title, ActionKeys.VIEW);
349
350 return wikiPageLocalService.getPage(nodeId, title, version);
351 }
352
353 @Override
354 public List<WikiPage> getPages(
355 long groupId, long nodeId, boolean head, int status, int start,
356 int end, OrderByComparator obc)
357 throws PortalException, SystemException {
358
359 WikiNodePermission.check(
360 getPermissionChecker(), nodeId, ActionKeys.VIEW);
361
362 if (status == WorkflowConstants.STATUS_ANY) {
363 return wikiPagePersistence.filterFindByG_N_H(
364 groupId, nodeId, head, start, end, obc);
365 }
366 else {
367 return wikiPagePersistence.filterFindByG_N_H_S(
368 groupId, nodeId, head, status, start, end, obc);
369 }
370 }
371
372 @Override
373 public List<WikiPage> getPages(
374 long groupId, long userId, long nodeId, int status, int start,
375 int end)
376 throws PortalException, SystemException {
377
378 WikiNodePermission.check(
379 getPermissionChecker(), nodeId, ActionKeys.VIEW);
380
381 if (userId > 0) {
382 return wikiPagePersistence.filterFindByG_U_N_S(
383 groupId, userId, nodeId, status, start, end,
384 new PageCreateDateComparator(false));
385 }
386 else {
387 return wikiPagePersistence.filterFindByG_N_S(
388 groupId, nodeId, status, start, end,
389 new PageCreateDateComparator(false));
390 }
391 }
392
393 @Override
394 public int getPagesCount(long groupId, long nodeId, boolean head)
395 throws PortalException, SystemException {
396
397 WikiNodePermission.check(
398 getPermissionChecker(), nodeId, ActionKeys.VIEW);
399
400 return wikiPagePersistence.filterCountByG_N_H_S(
401 groupId, nodeId, head, WorkflowConstants.STATUS_APPROVED);
402 }
403
404 @Override
405 public int getPagesCount(long groupId, long userId, long nodeId, int status)
406 throws PortalException, SystemException {
407
408 WikiNodePermission.check(
409 getPermissionChecker(), nodeId, ActionKeys.VIEW);
410
411 if (userId > 0) {
412 return wikiPagePersistence.filterCountByG_U_N_S(
413 groupId, userId, nodeId, status);
414 }
415 else {
416 return wikiPagePersistence.filterCountByG_N_S(
417 groupId, nodeId, status);
418 }
419 }
420
421 @Override
422 public String getPagesRSS(
423 long companyId, long nodeId, String title, int max, String type,
424 double version, String displayStyle, String feedURL,
425 String entryURL, Locale locale)
426 throws PortalException, SystemException {
427
428 return getPagesRSS(
429 companyId, nodeId, title, max, type, version, displayStyle, feedURL,
430 entryURL, null, locale);
431 }
432
433 @Override
434 public String getPagesRSS(
435 long companyId, long nodeId, String title, int max, String type,
436 double version, String displayStyle, String feedURL,
437 String entryURL, String attachmentURLPrefix, Locale locale)
438 throws PortalException, SystemException {
439
440 WikiPagePermission.check(
441 getPermissionChecker(), nodeId, title, ActionKeys.VIEW);
442
443 List<WikiPage> pages = wikiPageLocalService.getPages(
444 nodeId, title, 0, max, new PageCreateDateComparator(true));
445
446 return exportToRSS(
447 companyId, title, title, type, version, displayStyle, feedURL,
448 entryURL, attachmentURLPrefix, pages, true, locale);
449 }
450
451 @Override
452 public List<WikiPage> getRecentChanges(
453 long groupId, long nodeId, int start, int end)
454 throws PortalException, SystemException {
455
456 WikiNodePermission.check(
457 getPermissionChecker(), nodeId, ActionKeys.VIEW);
458
459 Calendar calendar = CalendarFactoryUtil.getCalendar();
460
461 calendar.add(Calendar.WEEK_OF_YEAR, -1);
462
463 return wikiPageFinder.filterFindByCreateDate(
464 groupId, nodeId, calendar.getTime(), false, start, end);
465 }
466
467 @Override
468 public int getRecentChangesCount(long groupId, long nodeId)
469 throws PortalException, SystemException {
470
471 WikiNodePermission.check(
472 getPermissionChecker(), nodeId, ActionKeys.VIEW);
473
474 Calendar calendar = CalendarFactoryUtil.getCalendar();
475
476 calendar.add(Calendar.WEEK_OF_YEAR, -1);
477
478 return wikiPageFinder.filterCountByCreateDate(
479 groupId, nodeId, calendar.getTime(), false);
480 }
481
482 @Override
483 public String[] getTempPageAttachmentNames(
484 long nodeId, String tempFolderName)
485 throws PortalException, SystemException {
486
487 WikiNodePermission.check(
488 getPermissionChecker(), nodeId, ActionKeys.ADD_ATTACHMENT);
489
490 return wikiPageLocalService.getTempPageAttachmentNames(
491 getUserId(), tempFolderName);
492 }
493
494 @Override
495 public void movePage(
496 long nodeId, String title, String newTitle,
497 ServiceContext serviceContext)
498 throws PortalException, SystemException {
499
500 WikiPagePermission.check(
501 getPermissionChecker(), nodeId, title, ActionKeys.DELETE);
502
503 WikiNodePermission.check(
504 getPermissionChecker(), nodeId, ActionKeys.ADD_PAGE);
505
506 wikiPageLocalService.movePage(
507 getUserId(), nodeId, title, newTitle, serviceContext);
508 }
509
510 @Override
511 public WikiPage revertPage(
512 long nodeId, String title, double version,
513 ServiceContext serviceContext)
514 throws PortalException, SystemException {
515
516 WikiPagePermission.check(
517 getPermissionChecker(), nodeId, title, ActionKeys.UPDATE);
518
519 return wikiPageLocalService.revertPage(
520 getUserId(), nodeId, title, version, serviceContext);
521 }
522
523 @Override
524 public void subscribePage(long nodeId, String title)
525 throws PortalException, SystemException {
526
527 WikiPagePermission.check(
528 getPermissionChecker(), nodeId, title, ActionKeys.SUBSCRIBE);
529
530 wikiPageLocalService.subscribePage(getUserId(), nodeId, title);
531 }
532
533 @Override
534 public void unsubscribePage(long nodeId, String title)
535 throws PortalException, SystemException {
536
537 WikiPagePermission.check(
538 getPermissionChecker(), nodeId, title, ActionKeys.SUBSCRIBE);
539
540 wikiPageLocalService.unsubscribePage(getUserId(), nodeId, title);
541 }
542
543 @Override
544 public WikiPage updatePage(
545 long nodeId, String title, double version, String content,
546 String summary, boolean minorEdit, String format,
547 String parentTitle, String redirectTitle,
548 ServiceContext serviceContext)
549 throws PortalException, SystemException {
550
551 WikiPagePermission.check(
552 getPermissionChecker(), nodeId, title, ActionKeys.UPDATE);
553
554 return wikiPageLocalService.updatePage(
555 getUserId(), nodeId, title, version, content, summary, minorEdit,
556 format, parentTitle, redirectTitle, serviceContext);
557 }
558
559 protected String exportToRSS(
560 long companyId, String name, String description, String type,
561 double version, String displayStyle, String feedURL,
562 String entryURL, String attachmentURLPrefix, List<WikiPage> pages,
563 boolean diff, Locale locale)
564 throws PortalException, SystemException {
565
566 SyndFeed syndFeed = new SyndFeedImpl();
567
568 syndFeed.setDescription(description);
569
570 List<SyndEntry> syndEntries = new ArrayList<SyndEntry>();
571
572 syndFeed.setEntries(syndEntries);
573
574 WikiPage latestPage = null;
575
576 StringBundler sb = new StringBundler(6);
577
578 for (WikiPage page : pages) {
579 SyndEntry syndEntry = new SyndEntryImpl();
580
581 String author = PortalUtil.getUserName(page);
582
583 syndEntry.setAuthor(author);
584
585 SyndContent syndContent = new SyndContentImpl();
586
587 syndContent.setType(RSSUtil.ENTRY_TYPE_DEFAULT);
588
589 sb.setIndex(0);
590
591 sb.append(entryURL);
592
593 if (entryURL.endsWith(StringPool.SLASH)) {
594 sb.append(HttpUtil.encodeURL(page.getTitle()));
595 }
596
597 if (diff) {
598 if ((latestPage != null) || (pages.size() == 1)) {
599 sb.append(StringPool.QUESTION);
600 sb.append(PortalUtil.getPortletNamespace(PortletKeys.WIKI));
601 sb.append("version=");
602 sb.append(page.getVersion());
603
604 String value = null;
605
606 if (latestPage == null) {
607 value = WikiUtil.convert(
608 page, null, null, attachmentURLPrefix);
609 }
610 else {
611 try {
612 value = WikiUtil.diffHtml(
613 latestPage, page, null, null,
614 attachmentURLPrefix);
615 }
616 catch (PortalException pe) {
617 throw pe;
618 }
619 catch (SystemException se) {
620 throw se;
621 }
622 catch (Exception e) {
623 throw new SystemException(e);
624 }
625 }
626
627 syndContent.setValue(value);
628
629 syndEntry.setDescription(syndContent);
630
631 syndEntries.add(syndEntry);
632 }
633 }
634 else {
635 String value = null;
636
637 if (displayStyle.equals(RSSUtil.DISPLAY_STYLE_ABSTRACT)) {
638 value = StringUtil.shorten(
639 HtmlUtil.extractText(page.getContent()),
640 PropsValues.WIKI_RSS_ABSTRACT_LENGTH, StringPool.BLANK);
641 }
642 else if (displayStyle.equals(RSSUtil.DISPLAY_STYLE_TITLE)) {
643 value = StringPool.BLANK;
644 }
645 else {
646 value = WikiUtil.convert(
647 page, null, null, attachmentURLPrefix);
648 }
649
650 syndContent.setValue(value);
651
652 syndEntry.setDescription(syndContent);
653
654 syndEntries.add(syndEntry);
655 }
656
657 syndEntry.setLink(sb.toString());
658 syndEntry.setPublishedDate(page.getCreateDate());
659
660 String title =
661 page.getTitle() + StringPool.SPACE + page.getVersion();
662
663 if (page.isMinorEdit()) {
664 title +=
665 StringPool.SPACE + StringPool.OPEN_PARENTHESIS +
666 LanguageUtil.get(locale, "minor-edit") +
667 StringPool.CLOSE_PARENTHESIS;
668 }
669
670 syndEntry.setTitle(title);
671
672 syndEntry.setUpdatedDate(page.getModifiedDate());
673 syndEntry.setUri(sb.toString());
674
675 latestPage = page;
676 }
677
678 syndFeed.setFeedType(RSSUtil.getFeedType(type, version));
679
680 List<SyndLink> syndLinks = new ArrayList<SyndLink>();
681
682 syndFeed.setLinks(syndLinks);
683
684 SyndLink syndLinkSelf = new SyndLinkImpl();
685
686 syndLinks.add(syndLinkSelf);
687
688 syndLinkSelf.setHref(feedURL);
689 syndLinkSelf.setRel("self");
690
691 syndFeed.setPublishedDate(new Date());
692 syndFeed.setTitle(name);
693 syndFeed.setUri(feedURL);
694
695 try {
696 return RSSUtil.export(syndFeed);
697 }
698 catch (FeedException fe) {
699 throw new SystemException(fe);
700 }
701 }
702
703 }