1
19
20 package com.liferay.portlet.wiki.service.impl;
21
22 import com.liferay.documentlibrary.DuplicateDirectoryException;
23 import com.liferay.documentlibrary.DuplicateFileException;
24 import com.liferay.documentlibrary.NoSuchDirectoryException;
25 import com.liferay.documentlibrary.NoSuchFileException;
26 import com.liferay.portal.PortalException;
27 import com.liferay.portal.SystemException;
28 import com.liferay.portal.kernel.log.Log;
29 import com.liferay.portal.kernel.log.LogFactoryUtil;
30 import com.liferay.portal.kernel.messaging.DestinationNames;
31 import com.liferay.portal.kernel.messaging.Message;
32 import com.liferay.portal.kernel.messaging.MessageBusUtil;
33 import com.liferay.portal.kernel.search.SearchException;
34 import com.liferay.portal.kernel.util.CalendarFactoryUtil;
35 import com.liferay.portal.kernel.util.ContentTypes;
36 import com.liferay.portal.kernel.util.HttpUtil;
37 import com.liferay.portal.kernel.util.ListUtil;
38 import com.liferay.portal.kernel.util.MathUtil;
39 import com.liferay.portal.kernel.util.NotificationThreadLocal;
40 import com.liferay.portal.kernel.util.ObjectValuePair;
41 import com.liferay.portal.kernel.util.OrderByComparator;
42 import com.liferay.portal.kernel.util.StringPool;
43 import com.liferay.portal.kernel.util.StringUtil;
44 import com.liferay.portal.kernel.util.Validator;
45 import com.liferay.portal.model.Company;
46 import com.liferay.portal.model.CompanyConstants;
47 import com.liferay.portal.model.Group;
48 import com.liferay.portal.model.GroupConstants;
49 import com.liferay.portal.model.ResourceConstants;
50 import com.liferay.portal.model.User;
51 import com.liferay.portal.theme.ThemeDisplay;
52 import com.liferay.portal.util.PortalUtil;
53 import com.liferay.portal.util.PortletKeys;
54 import com.liferay.portal.util.PropsValues;
55 import com.liferay.portlet.wiki.DuplicatePageException;
56 import com.liferay.portlet.wiki.NoSuchPageException;
57 import com.liferay.portlet.wiki.PageContentException;
58 import com.liferay.portlet.wiki.PageTitleException;
59 import com.liferay.portlet.wiki.PageVersionException;
60 import com.liferay.portlet.wiki.model.WikiNode;
61 import com.liferay.portlet.wiki.model.WikiPage;
62 import com.liferay.portlet.wiki.model.WikiPageDisplay;
63 import com.liferay.portlet.wiki.model.WikiPageResource;
64 import com.liferay.portlet.wiki.model.impl.WikiPageDisplayImpl;
65 import com.liferay.portlet.wiki.model.impl.WikiPageImpl;
66 import com.liferay.portlet.wiki.service.base.WikiPageLocalServiceBaseImpl;
67 import com.liferay.portlet.wiki.social.WikiActivityKeys;
68 import com.liferay.portlet.wiki.util.Indexer;
69 import com.liferay.portlet.wiki.util.WikiCacheThreadLocal;
70 import com.liferay.portlet.wiki.util.WikiCacheUtil;
71 import com.liferay.portlet.wiki.util.WikiUtil;
72 import com.liferay.portlet.wiki.util.comparator.PageCreateDateComparator;
73 import com.liferay.util.UniqueList;
74
75 import java.rmi.RemoteException;
76
77 import java.util.ArrayList;
78 import java.util.Calendar;
79 import java.util.Date;
80 import java.util.HashSet;
81 import java.util.Iterator;
82 import java.util.LinkedHashMap;
83 import java.util.List;
84 import java.util.Map;
85 import java.util.Set;
86 import java.util.regex.Matcher;
87 import java.util.regex.Pattern;
88
89 import javax.portlet.PortletPreferences;
90 import javax.portlet.PortletURL;
91
92
99 public class WikiPageLocalServiceImpl extends WikiPageLocalServiceBaseImpl {
100
101 public WikiPage addPage(
102 long userId, long nodeId, String title, String content,
103 String summary, boolean minorEdit, PortletPreferences prefs,
104 ThemeDisplay themeDisplay)
105 throws PortalException, SystemException {
106
107 String uuid = null;
108 double version = WikiPageImpl.DEFAULT_VERSION;
109 String format = WikiPageImpl.DEFAULT_FORMAT;
110 boolean head = true;
111 String parentTitle = null;
112 String redirectTitle = null;
113 String[] tagsEntries = null;
114
115 return addPage(
116 uuid, userId, nodeId, title, version, content, summary, minorEdit,
117 format, head, parentTitle, redirectTitle, tagsEntries, prefs,
118 themeDisplay);
119 }
120
121 public WikiPage addPage(
122 String uuid, long userId, long nodeId, String title, double version,
123 String content, String summary, boolean minorEdit, String format,
124 boolean head, String parentTitle, String redirectTitle,
125 String[] tagsEntries, PortletPreferences prefs,
126 ThemeDisplay themeDisplay)
127 throws PortalException, SystemException {
128
129
131 User user = userPersistence.findByPrimaryKey(userId);
132 WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
133
134 Date now = new Date();
135
136 validate(title, nodeId, content, format);
137
138 long pageId = counterLocalService.increment();
139
140 long resourcePrimKey =
141 wikiPageResourceLocalService.getPageResourcePrimKey(nodeId, title);
142
143 WikiPage page = wikiPagePersistence.create(pageId);
144
145 page.setUuid(uuid);
146 page.setResourcePrimKey(resourcePrimKey);
147 page.setCompanyId(user.getCompanyId());
148 page.setUserId(user.getUserId());
149 page.setUserName(user.getFullName());
150 page.setCreateDate(now);
151 page.setModifiedDate(now);
152 page.setNodeId(nodeId);
153 page.setTitle(title);
154 page.setVersion(version);
155 page.setMinorEdit(minorEdit);
156 page.setContent(content);
157 page.setSummary(summary);
158 page.setFormat(format);
159 page.setHead(head);
160 page.setParentTitle(parentTitle);
161 page.setRedirectTitle(redirectTitle);
162
163 wikiPagePersistence.update(page, false);
164
165
167 addPageResources(page.getNode(), page, true, true);
168
169
171 node.setLastPostDate(now);
172
173 wikiNodePersistence.update(node, false);
174
175
177 socialActivityLocalService.addActivity(
178 userId, node.getGroupId(), WikiPage.class.getName(),
179 page.getResourcePrimKey(), WikiActivityKeys.ADD_PAGE,
180 StringPool.BLANK, 0);
181
182
184 if (!minorEdit && NotificationThreadLocal.isNotificationEnabled()) {
185 notifySubscribers(node, page, prefs, themeDisplay, false);
186 }
187
188
190 updateTagsAsset(userId, page, tagsEntries);
191
192
194 try {
195 Indexer.addPage(
196 page.getCompanyId(), node.getGroupId(), nodeId, title,
197 content, page.getModifiedDate(), tagsEntries);
198 }
199 catch (SearchException se) {
200 _log.error("Indexing " + pageId, se);
201 }
202
203
205 clearPageCache(page);
206 clearReferralsCache(page);
207
208 return page;
209 }
210
211 public void addPageAttachments(
212 long nodeId, String title,
213 List<ObjectValuePair<String, byte[]>> files)
214 throws PortalException, SystemException {
215
216 if (files.size() == 0) {
217 return;
218 }
219
220 WikiPage page = getPage(nodeId, title);
221
222 long companyId = page.getCompanyId();
223 String portletId = CompanyConstants.SYSTEM_STRING;
224 long groupId = GroupConstants.DEFAULT_PARENT_GROUP_ID;
225 long repositoryId = CompanyConstants.SYSTEM;
226 String dirName = page.getAttachmentsDir();
227
228 try {
229 try {
230 dlService.addDirectory(companyId, repositoryId, dirName);
231 }
232 catch (DuplicateDirectoryException dde) {
233 }
234
235 for (int i = 0; i < files.size(); i++) {
236 ObjectValuePair<String, byte[]> ovp = files.get(i);
237
238 String fileName = ovp.getKey();
239 byte[] bytes = ovp.getValue();
240
241 if (Validator.isNull(fileName)) {
242 continue;
243 }
244
245 try {
246 dlService.addFile(
247 companyId, portletId, groupId, repositoryId,
248 dirName + "/" + fileName, StringPool.BLANK,
249 page.getModifiedDate(), new String[0], bytes);
250 }
251 catch (DuplicateFileException dfe) {
252 }
253 }
254 }
255 catch (RemoteException re) {
256 throw new SystemException(re);
257 }
258 }
259
260 public void addPageResources(
261 long nodeId, String title, boolean addCommunityPermissions,
262 boolean addGuestPermissions)
263 throws PortalException, SystemException {
264
265 WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
266 WikiPage page = getPage(nodeId, title);
267
268 addPageResources(
269 node, page, addCommunityPermissions, addGuestPermissions);
270 }
271
272 public void addPageResources(
273 WikiNode node, WikiPage page, boolean addCommunityPermissions,
274 boolean addGuestPermissions)
275 throws PortalException, SystemException {
276
277 resourceLocalService.addResources(
278 page.getCompanyId(), node.getGroupId(), page.getUserId(),
279 WikiPage.class.getName(), page.getResourcePrimKey(), false,
280 addCommunityPermissions, addGuestPermissions);
281 }
282
283 public void addPageResources(
284 long nodeId, String title, String[] communityPermissions,
285 String[] guestPermissions)
286 throws PortalException, SystemException {
287
288 WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
289 WikiPage page = getPage(nodeId, title);
290
291 addPageResources(node, page, communityPermissions, guestPermissions);
292 }
293
294 public void addPageResources(
295 WikiNode node, WikiPage page, String[] communityPermissions,
296 String[] guestPermissions)
297 throws PortalException, SystemException {
298
299 resourceLocalService.addModelResources(
300 page.getCompanyId(), node.getGroupId(), page.getUserId(),
301 WikiPage.class.getName(), page.getResourcePrimKey(),
302 communityPermissions, guestPermissions);
303 }
304
305 public void changeParent(
306 long userId, long nodeId, String title, String newParentTitle,
307 PortletPreferences prefs, ThemeDisplay themeDisplay)
308 throws PortalException, SystemException {
309
310 WikiPage page = getPage(nodeId, title);
311
312 String originalParentTitle = page.getParentTitle();
313
314 double version = page.getVersion();
315 String content = page.getContent();
316 String summary = themeDisplay.translate(
317 "changed-parent-from-x", originalParentTitle);
318 boolean minorEdit = false;
319 String format = page.getFormat();
320 String redirectTitle = page.getRedirectTitle();
321 String[] tagsEntries = tagsEntryLocalService.getEntryNames(
322 WikiPage.class.getName(), page.getResourcePrimKey());
323
324 updatePage(
325 userId, nodeId, title, version, content, summary, minorEdit,
326 format, newParentTitle, redirectTitle, tagsEntries, prefs,
327 themeDisplay);
328
329 List<WikiPage> oldPages = wikiPagePersistence.findByN_T_H(
330 nodeId, title, false);
331
332 for (WikiPage oldPage : oldPages) {
333 oldPage.setParentTitle(originalParentTitle);
334
335 wikiPagePersistence.update(oldPage, false);
336 }
337 }
338
339 public void deletePage(long nodeId, String title)
340 throws PortalException, SystemException {
341
342 List<WikiPage> pages = wikiPagePersistence.findByN_T_H(
343 nodeId, title, true, 0, 1);
344
345 if (pages.size() > 0) {
346 WikiPage page = pages.iterator().next();
347
348 deletePage(page);
349 }
350 }
351
352 public void deletePage(WikiPage page)
353 throws PortalException, SystemException {
354
355
357 List<WikiPage> children = wikiPagePersistence.findByN_P(
358 page.getNodeId(), page.getTitle());
359
360 for (WikiPage curPage : children) {
361 deletePage(curPage);
362 }
363
364
366 try {
367 Indexer.deletePage(
368 page.getCompanyId(), page.getNodeId(), page.getTitle());
369 }
370 catch (SearchException se) {
371 _log.error("Deleting index " + page.getPrimaryKey(), se);
372 }
373
374
376 long companyId = page.getCompanyId();
377 String portletId = CompanyConstants.SYSTEM_STRING;
378 long repositoryId = CompanyConstants.SYSTEM;
379 String dirName = page.getAttachmentsDir();
380
381 try {
382 dlService.deleteDirectory(
383 companyId, portletId, repositoryId, dirName);
384 }
385 catch (NoSuchDirectoryException nsde) {
386 }
387 catch (RemoteException re) {
388 throw new SystemException(re);
389 }
390
391
393 tagsAssetLocalService.deleteAsset(
394 WikiPage.class.getName(), page.getResourcePrimKey());
395
396
398 subscriptionLocalService.deleteSubscriptions(
399 page.getCompanyId(), WikiPage.class.getName(), page.getPageId());
400
401
403 socialActivityLocalService.deleteActivities(
404 WikiPage.class.getName(), page.getResourcePrimKey());
405
406
408 mbMessageLocalService.deleteDiscussionMessages(
409 WikiPage.class.getName(), page.getResourcePrimKey());
410
411
413 resourceLocalService.deleteResource(
414 page.getCompanyId(), WikiPage.class.getName(),
415 ResourceConstants.SCOPE_INDIVIDUAL, page.getResourcePrimKey());
416
417
419 wikiPageResourceLocalService.deletePageResource(
420 page.getNodeId(), page.getTitle());
421
422
424 wikiPagePersistence.removeByN_T(page.getNodeId(), page.getTitle());
425
426
428 wikiPagePersistence.removeByN_R(page.getNodeId(), page.getTitle());
429
430
432 clearPageCache(page);
433 clearReferralsCache(page);
434 }
435
436 public void deletePageAttachment(long nodeId, String title, String fileName)
437 throws PortalException, SystemException {
438
439 if (Validator.isNull(fileName)) {
440 return;
441 }
442
443 WikiPage page = getPage(nodeId, title);
444
445 long companyId = page.getCompanyId();
446 String portletId = CompanyConstants.SYSTEM_STRING;
447 long repositoryId = CompanyConstants.SYSTEM;
448
449 try {
450 dlService.deleteFile(companyId, portletId, repositoryId, fileName);
451 }
452 catch (NoSuchFileException nsfe) {
453 }
454 catch (RemoteException re) {
455 throw new SystemException(re);
456 }
457 }
458
459 public void deletePages(long nodeId)
460 throws PortalException, SystemException {
461
462 Iterator<WikiPage> itr = wikiPagePersistence.findByN_H(
463 nodeId, true).iterator();
464
465 while (itr.hasNext()) {
466 WikiPage page = itr.next();
467
468 deletePage(page);
469 }
470 }
471
472 public List<WikiPage> getChildren(
473 long nodeId, boolean head, String parentTitle)
474 throws SystemException {
475
476 return wikiPagePersistence.findByN_H_P(nodeId, head, parentTitle);
477 }
478
479 public List<WikiPage> getIncomingLinks(long nodeId, String title)
480 throws PortalException, SystemException {
481
482 List<WikiPage> links = new UniqueList<WikiPage>();
483
484 List<WikiPage> pages = wikiPagePersistence.findByN_H(nodeId, true);
485
486 for (WikiPage page : pages) {
487 if (isLinkedTo(page, title)) {
488 links.add(page);
489 }
490 }
491
492 List<WikiPage> referrals = wikiPagePersistence.findByN_R(nodeId, title);
493
494 for (WikiPage referral : referrals) {
495 for (WikiPage page : pages) {
496 if (isLinkedTo(page, referral.getTitle())) {
497 links.add(page);
498 }
499 }
500 }
501
502 return ListUtil.sort(links);
503 }
504
505 public List<WikiPage> getNoAssetPages() throws SystemException {
506 return wikiPageFinder.findByNoAssets();
507 }
508
509 public List<WikiPage> getOrphans(long nodeId)
510 throws PortalException, SystemException {
511
512 List<Map<String, Boolean>> pageTitles =
513 new ArrayList<Map<String, Boolean>>();
514
515 List<WikiPage> pages = wikiPagePersistence.findByN_H(nodeId, true);
516
517 for (WikiPage page : pages) {
518 pageTitles.add(WikiCacheUtil.getOutgoingLinks(page));
519 }
520
521 Set<WikiPage> notOrphans = new HashSet<WikiPage>();
522
523 for (WikiPage page : pages) {
524 for (Map<String, Boolean> pageTitle : pageTitles) {
525 if (pageTitle.get(page.getTitle()) != null) {
526 notOrphans.add(page);
527
528 break;
529 }
530 }
531 }
532
533 List<WikiPage> orphans = new ArrayList<WikiPage>();
534
535 for (WikiPage page : pages) {
536 if (!notOrphans.contains(page)) {
537 orphans.add(page);
538 }
539 }
540
541 orphans = ListUtil.sort(orphans);
542
543 return orphans;
544 }
545
546 public List<WikiPage> getOutgoingLinks(long nodeId, String title)
547 throws PortalException, SystemException {
548
549 WikiPage page = getPage(nodeId, title);
550
551 Map<String, WikiPage> pages = new LinkedHashMap<String, WikiPage>();
552
553 Map<String, Boolean> links = WikiCacheUtil.getOutgoingLinks(page);
554
555 for (String curTitle : links.keySet()) {
556 Boolean exists = links.get(curTitle);
557
558 if (exists) {
559 if (!pages.containsKey(curTitle)) {
560 pages.put(curTitle, getPage(nodeId, curTitle));
561 }
562 }
563 else {
564 WikiPageImpl newPage = new WikiPageImpl();
565
566 newPage.setNew(true);
567 newPage.setNodeId(nodeId);
568 newPage.setTitle(curTitle);
569
570 if (!pages.containsKey(curTitle)) {
571 pages.put(curTitle, newPage);
572 }
573 }
574 }
575
576 return ListUtil.fromCollection(pages.values());
577 }
578
579 public WikiPage getPage(long nodeId, String title)
580 throws PortalException, SystemException {
581
582 List<WikiPage> pages = wikiPagePersistence.findByN_T_H(
583 nodeId, title, true, 0, 1);
584
585 if (pages.size() > 0) {
586 return pages.get(0);
587 }
588 else {
589 throw new NoSuchPageException();
590 }
591 }
592
593 public WikiPage getPage(long nodeId, String title, double version)
594 throws PortalException, SystemException {
595
596 WikiPage page = null;
597
598 if (version == 0) {
599 page = getPage(nodeId, title);
600 }
601 else {
602 page = wikiPagePersistence.findByN_T_V(nodeId, title, version);
603 }
604
605 return page;
606 }
607
608 public WikiPageDisplay getPageDisplay(
609 long nodeId, String title, PortletURL viewPageURL,
610 PortletURL editPageURL, String attachmentURLPrefix)
611 throws PortalException, SystemException {
612
613 WikiPage page = getPage(nodeId, title);
614
615 String formattedContent = WikiUtil.convert(
616 page, viewPageURL, editPageURL, attachmentURLPrefix);
617
618 return new WikiPageDisplayImpl(
619 page.getUserId(), page.getNodeId(), page.getTitle(),
620 page.getVersion(), page.getContent(), formattedContent,
621 page.getFormat(), page.getHead(), page.getAttachmentsFiles());
622 }
623
624 public List<WikiPage> getPages(long nodeId, int start, int end)
625 throws SystemException {
626
627 return wikiPagePersistence.findByNodeId(
628 nodeId, start, end, new PageCreateDateComparator(false));
629 }
630
631 public List<WikiPage> getPages(String format) throws SystemException {
632 return wikiPagePersistence.findByFormat(format);
633 }
634
635 public List<WikiPage> getPages(
636 long nodeId, String title, int start, int end)
637 throws SystemException {
638
639 return wikiPagePersistence.findByN_T(
640 nodeId, title, start, end, new PageCreateDateComparator(false));
641 }
642
643 public List<WikiPage> getPages(
644 long nodeId, String title, int start, int end,
645 OrderByComparator obc)
646 throws SystemException {
647
648 return wikiPagePersistence.findByN_T(nodeId, title, start, end, obc);
649 }
650
651 public List<WikiPage> getPages(
652 long nodeId, boolean head, int start, int end)
653 throws SystemException {
654
655 return wikiPagePersistence.findByN_H(
656 nodeId, head, start, end, new PageCreateDateComparator(false));
657 }
658
659 public List<WikiPage> getPages(
660 long nodeId, String title, boolean head, int start, int end)
661 throws SystemException {
662
663 return wikiPagePersistence.findByN_T_H(
664 nodeId, title, head, start, end,
665 new PageCreateDateComparator(false));
666 }
667
668 public int getPagesCount(long nodeId) throws SystemException {
669 return wikiPagePersistence.countByNodeId(nodeId);
670 }
671
672 public int getPagesCount(long nodeId, String title)
673 throws SystemException {
674
675 return wikiPagePersistence.countByN_T(nodeId, title);
676 }
677
678 public int getPagesCount(long nodeId, boolean head)
679 throws SystemException {
680
681 return wikiPagePersistence.countByN_H(nodeId, head);
682 }
683
684 public int getPagesCount(long nodeId, String title, boolean head)
685 throws SystemException {
686
687 return wikiPagePersistence.countByN_T_H(nodeId, title, head);
688 }
689
690 public List<WikiPage> getRecentChanges(long nodeId, int start, int end)
691 throws SystemException {
692
693 Calendar cal = CalendarFactoryUtil.getCalendar();
694
695 cal.add(Calendar.WEEK_OF_YEAR, -1);
696
697 return wikiPageFinder.findByCreateDate(
698 nodeId, cal.getTime(), false, start, end);
699 }
700
701 public int getRecentChangesCount(long nodeId) throws SystemException {
702 Calendar cal = CalendarFactoryUtil.getCalendar();
703
704 cal.add(Calendar.WEEK_OF_YEAR, -1);
705
706 return wikiPageFinder.countByCreateDate(nodeId, cal.getTime(), false);
707 }
708
709 public void movePage(
710 long userId, long nodeId, String title, String newTitle,
711 PortletPreferences prefs, ThemeDisplay themeDisplay)
712 throws PortalException, SystemException {
713
714 movePage(userId, nodeId, title, newTitle, true, prefs, themeDisplay);
715 }
716
717 public void movePage(
718 long userId, long nodeId, String title, String newTitle,
719 boolean strict, PortletPreferences prefs, ThemeDisplay themeDisplay)
720 throws PortalException, SystemException {
721
722 validateTitle(newTitle);
723
724
726 if (isUsedTitle(nodeId, newTitle)) {
727 WikiPage page = getPage(nodeId, newTitle);
728
729
731 if (((page.getVersion() == WikiPageImpl.DEFAULT_VERSION) &&
732 (page.getContent().length() < 200)) ||
733 !strict) {
734
735 deletePage(nodeId, newTitle);
736 }
737 else {
738 throw new DuplicatePageException(newTitle);
739 }
740 }
741
742
744 List<WikiPage> pageVersions = wikiPagePersistence.findByN_T(
745 nodeId, title);
746
747 if (pageVersions.size() == 0) {
748 return;
749 }
750
751 for (WikiPage page : pageVersions) {
752 page.setTitle(newTitle);
753
754 wikiPagePersistence.update(page, false);
755 }
756
757
759 List<WikiPage> children = wikiPagePersistence.findByN_P(nodeId, title);
760
761 for (WikiPage page : children) {
762 page.setParentTitle(newTitle);
763
764 wikiPagePersistence.update(page, false);
765 }
766
767 WikiPage page = pageVersions.get(pageVersions.size() - 1);
768
769
771 WikiPageResource wikiPageResource =
772 wikiPageResourcePersistence.findByPrimaryKey(
773 page.getResourcePrimKey());
774
775 wikiPageResource.setTitle(newTitle);
776
777 wikiPageResourcePersistence.update(wikiPageResource, false);
778
779
781 String uuid = null;
782 double version = WikiPageImpl.DEFAULT_VERSION;
783 String format = page.getFormat();
784 boolean head = true;
785 String parentTitle = page.getParentTitle();
786 String redirectTitle = page.getTitle();
787 String content =
788 StringPool.DOUBLE_OPEN_BRACKET + redirectTitle +
789 StringPool.DOUBLE_CLOSE_BRACKET;
790 String summary = WikiPageImpl.MOVED + " to " + title;
791
792 addPage(
793 uuid, userId, nodeId, title, version, content, summary, false,
794 format, head, parentTitle, redirectTitle, null, prefs,
795 themeDisplay);
796
797
799 List<WikiPage> redirectedPages = wikiPagePersistence.findByN_R(
800 nodeId, title);
801
802 for (WikiPage redirectedPage : redirectedPages) {
803 redirectedPage.setRedirectTitle(newTitle);
804
805 wikiPagePersistence.update(redirectedPage, false);
806 }
807
808
810 String[] tagsEntries = tagsEntryLocalService.getEntryNames(
811 WikiPage.class.getName(), page.getResourcePrimKey());
812
813 updateTagsAsset(userId, page, tagsEntries);
814
815
817 try {
818 WikiNode node = page.getNode();
819
820 Indexer.updatePage(
821 page.getCompanyId(), node.getGroupId(), nodeId, newTitle,
822 page.getContent(), page.getModifiedDate(), tagsEntries);
823
824 Indexer.deletePage(page.getCompanyId(), node.getGroupId(), title);
825 }
826 catch (SearchException se) {
827 _log.error("Indexing " + newTitle, se);
828 }
829 }
830
831 public WikiPage revertPage(
832 long userId, long nodeId, String title, double version,
833 PortletPreferences prefs, ThemeDisplay themeDisplay)
834 throws PortalException, SystemException {
835
836 WikiPage oldPage = getPage(nodeId, title, version);
837
838 return updatePage(
839 userId, nodeId, title, 0, oldPage.getContent(),
840 WikiPageImpl.REVERTED + " to " + version, false,
841 oldPage.getFormat(), null, oldPage.getRedirectTitle(), null, prefs,
842 themeDisplay);
843 }
844
845 public void subscribePage(long userId, long nodeId, String title)
846 throws PortalException, SystemException {
847
848 WikiPage page = getPage(nodeId, title);
849
850 subscriptionLocalService.addSubscription(
851 userId, WikiPage.class.getName(), page.getResourcePrimKey());
852 }
853
854 public void unsubscribePage(long userId, long nodeId, String title)
855 throws PortalException, SystemException {
856
857 WikiPage page = getPage(nodeId, title);
858
859 subscriptionLocalService.deleteSubscription(
860 userId, WikiPage.class.getName(), page.getResourcePrimKey());
861 }
862
863 public WikiPage updatePage(
864 long userId, long nodeId, String title, double version,
865 String content, String summary, boolean minorEdit, String format,
866 String parentTitle, String redirectTitle, String[] tagsEntries,
867 PortletPreferences prefs, ThemeDisplay themeDisplay)
868 throws PortalException, SystemException {
869
870
872 User user = userPersistence.findByPrimaryKey(userId);
873 Date now = new Date();
874
875 validate(nodeId, content, format);
876
877 WikiPage page = null;
878
879 try {
880 page = getPage(nodeId, title);
881 }
882 catch (NoSuchPageException nspe) {
883 return addPage(
884 null, userId, nodeId, title, WikiPageImpl.DEFAULT_VERSION,
885 content, summary, minorEdit, format, true, parentTitle,
886 redirectTitle, tagsEntries, prefs, themeDisplay);
887 }
888
889 double oldVersion = page.getVersion();
890
891 if ((version > 0) && (version != oldVersion)) {
892 throw new PageVersionException();
893 }
894
895 long resourcePrimKey = page.getResourcePrimKey();
896
897 page.setHead(false);
898 page.setModifiedDate(now);
899
900 wikiPagePersistence.update(page, false);
901
902 double newVersion = MathUtil.format(oldVersion + 0.1, 1, 1);
903
904 long pageId = counterLocalService.increment();
905
906 page = wikiPagePersistence.create(pageId);
907
908 page.setResourcePrimKey(resourcePrimKey);
909 page.setCompanyId(user.getCompanyId());
910 page.setUserId(user.getUserId());
911 page.setUserName(user.getFullName());
912 page.setCreateDate(now);
913 page.setModifiedDate(now);
914 page.setNodeId(nodeId);
915 page.setTitle(title);
916 page.setVersion(newVersion);
917 page.setMinorEdit(minorEdit);
918 page.setContent(content);
919 page.setSummary(summary);
920 page.setFormat(format);
921 page.setHead(true);
922
923 if (Validator.isNotNull(parentTitle)) {
924 page.setParentTitle(parentTitle);
925 }
926
927 if (Validator.isNotNull(redirectTitle)) {
928 page.setRedirectTitle(redirectTitle);
929 }
930
931 wikiPagePersistence.update(page, false);
932
933
935 WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
936
937 node.setLastPostDate(now);
938
939 wikiNodePersistence.update(node, false);
940
941
943 socialActivityLocalService.addActivity(
944 userId, node.getGroupId(), WikiPage.class.getName(),
945 page.getResourcePrimKey(), WikiActivityKeys.UPDATE_PAGE,
946 StringPool.BLANK, 0);
947
948
950 if (!minorEdit && NotificationThreadLocal.isNotificationEnabled()) {
951 notifySubscribers(node, page, prefs, themeDisplay, true);
952 }
953
954
956 updateTagsAsset(userId, page, tagsEntries);
957
958
960 try {
961 if (Validator.isNull(page.getRedirectTitle())) {
962 Indexer.updatePage(
963 node.getCompanyId(), node.getGroupId(), nodeId, title,
964 content, page.getModifiedDate(), tagsEntries);
965 }
966 }
967 catch (SearchException se) {
968 _log.error("Indexing " + page.getPrimaryKey(), se);
969 }
970
971
973 clearPageCache(page);
974
975 return page;
976 }
977
978 public void updateTagsAsset(
979 long userId, WikiPage page, String[] tagsEntries)
980 throws PortalException, SystemException {
981
982 tagsAssetLocalService.updateAsset(
983 userId, page.getNode().getGroupId(), WikiPage.class.getName(),
984 page.getResourcePrimKey(), tagsEntries, null, null, null, null,
985 ContentTypes.TEXT_HTML, page.getTitle(), null, null, null, 0, 0,
986 null, false);
987 }
988
989 public void validateTitle(String title) throws PortalException {
990 if (title.equals("all_pages") || title.equals("orphan_pages") ||
991 title.equals("recent_changes")) {
992
993 throw new PageTitleException(title + " is reserved");
994 }
995
996 if (Validator.isNotNull(PropsValues.WIKI_PAGE_TITLES_REGEXP)) {
997 Pattern pattern = Pattern.compile(
998 PropsValues.WIKI_PAGE_TITLES_REGEXP);
999
1000 Matcher matcher = pattern.matcher(title);
1001
1002 if (!matcher.matches()) {
1003 throw new PageTitleException();
1004 }
1005 }
1006 }
1007
1008 protected void clearPageCache(WikiPage page) {
1009 if (!WikiCacheThreadLocal.isClearCache()) {
1010 return;
1011 }
1012
1013 WikiCacheUtil.clearCache(page.getNodeId(), page.getTitle());
1014 }
1015
1016 protected void clearReferralsCache(WikiPage page)
1017 throws PortalException, SystemException {
1018
1019 if (!WikiCacheThreadLocal.isClearCache()) {
1020 return;
1021 }
1022
1023 List<WikiPage> links = getIncomingLinks(
1024 page.getNodeId(), page.getTitle());
1025
1026 for (WikiPage curPage : links) {
1027 WikiCacheUtil.clearCache(curPage.getNodeId(), curPage.getTitle());
1028 }
1029 }
1030
1031 protected boolean isLinkedTo(WikiPage page, String targetTitle)
1032 throws PortalException {
1033
1034 Map<String, Boolean> links = WikiCacheUtil.getOutgoingLinks(page);
1035
1036 Boolean link = links.get(targetTitle);
1037
1038 if (link != null) {
1039 return true;
1040 }
1041 else {
1042 return false;
1043 }
1044 }
1045
1046 protected boolean isUsedTitle(long nodeId, String title)
1047 throws SystemException {
1048
1049 if (getPagesCount(nodeId, title, true) > 0) {
1050 return true;
1051 }
1052 else {
1053 return false;
1054 }
1055 }
1056
1057 protected void notifySubscribers(
1058 WikiNode node, WikiPage page, PortletPreferences prefs,
1059 ThemeDisplay themeDisplay, boolean update)
1060 throws PortalException, SystemException {
1061
1062 if (prefs == null) {
1063 long ownerId = node.getGroupId();
1064 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
1065 long plid = PortletKeys.PREFS_PLID_SHARED;
1066 String portletId = PortletKeys.WIKI;
1067 String defaultPreferences = null;
1068
1069 prefs = portletPreferencesLocalService.getPreferences(
1070 node.getCompanyId(), ownerId, ownerType, plid, portletId,
1071 defaultPreferences);
1072 }
1073
1074 if (!update && WikiUtil.getEmailPageAddedEnabled(prefs)) {
1075 }
1076 else if (update && WikiUtil.getEmailPageUpdatedEnabled(prefs)) {
1077 }
1078 else {
1079 return;
1080 }
1081
1082 Company company = companyPersistence.findByPrimaryKey(
1083 page.getCompanyId());
1084
1085 Group group = groupPersistence.findByPrimaryKey(node.getGroupId());
1086
1087 User user = userPersistence.findByPrimaryKey(page.getUserId());
1088
1089 String pageURL = StringPool.BLANK;
1090
1091 if (themeDisplay != null) {
1092 String portalURL = PortalUtil.getPortalURL(themeDisplay);
1093 String layoutURL = PortalUtil.getLayoutURL(themeDisplay);
1094
1095 pageURL =
1096 portalURL + layoutURL + "/-/wiki/" + node.getNodeId() + "/" +
1097 HttpUtil.encodeURL(page.getTitle());
1098 }
1099
1100 String portletName = PortalUtil.getPortletTitle(
1101 PortletKeys.WIKI, user);
1102
1103 String fromName = WikiUtil.getEmailFromName(prefs);
1104 String fromAddress = WikiUtil.getEmailFromAddress(prefs);
1105
1106 String replyToAddress = fromAddress;
1107 String mailId = WikiUtil.getMailId(
1108 company.getMx(), page.getNodeId(), page.getPageId());
1109
1110 fromName = StringUtil.replace(
1111 fromName,
1112 new String[] {
1113 "[$COMPANY_ID$]",
1114 "[$COMPANY_MX$]",
1115 "[$COMPANY_NAME$]",
1116 "[$COMMUNITY_NAME$]",
1117 "[$PAGE_USER_ADDRESS$]",
1118 "[$PAGE_USER_NAME$]",
1119 "[$PORTLET_NAME$]"
1120 },
1121 new String[] {
1122 String.valueOf(company.getCompanyId()),
1123 company.getMx(),
1124 company.getName(),
1125 group.getName(),
1126 user.getEmailAddress(),
1127 user.getFullName(),
1128 portletName
1129 });
1130
1131 fromAddress = StringUtil.replace(
1132 fromAddress,
1133 new String[] {
1134 "[$COMPANY_ID$]",
1135 "[$COMPANY_MX$]",
1136 "[$COMPANY_NAME$]",
1137 "[$COMMUNITY_NAME$]",
1138 "[$PAGE_USER_ADDRESS$]",
1139 "[$PAGE_USER_NAME$]",
1140 "[$PORTLET_NAME$]"
1141 },
1142 new String[] {
1143 String.valueOf(company.getCompanyId()),
1144 company.getMx(),
1145 company.getName(),
1146 group.getName(),
1147 user.getEmailAddress(),
1148 user.getFullName(),
1149 portletName
1150 });
1151
1152 String subjectPrefix = null;
1153 String body = null;
1154 String signature = null;
1155
1156 if (update) {
1157 subjectPrefix = WikiUtil.getEmailPageUpdatedSubjectPrefix(prefs);
1158 body = WikiUtil.getEmailPageUpdatedBody(prefs);
1159 signature = WikiUtil.getEmailPageUpdatedSignature(prefs);
1160 }
1161 else {
1162 subjectPrefix = WikiUtil.getEmailPageAddedSubjectPrefix(prefs);
1163 body = WikiUtil.getEmailPageAddedBody(prefs);
1164 signature = WikiUtil.getEmailPageAddedSignature(prefs);
1165 }
1166
1167 if (Validator.isNotNull(signature)) {
1168 body += "\n--\n" + signature;
1169 }
1170
1171 subjectPrefix = StringUtil.replace(
1172 subjectPrefix,
1173 new String[] {
1174 "[$COMPANY_ID$]",
1175 "[$COMPANY_MX$]",
1176 "[$COMPANY_NAME$]",
1177 "[$COMMUNITY_NAME$]",
1178 "[$FROM_ADDRESS$]",
1179 "[$FROM_NAME$]",
1180 "[$NODE_NAME$]",
1181 "[$PAGE_CONTENT$]",
1182 "[$PAGE_ID$]",
1183 "[$PAGE_TITLE$]",
1184 "[$PAGE_USER_ADDRESS$]",
1185 "[$PAGE_USER_NAME$]",
1186 "[$PORTAL_URL$]",
1187 "[$PORTLET_NAME$]"
1188 },
1189 new String[] {
1190 String.valueOf(company.getCompanyId()),
1191 company.getMx(),
1192 company.getName(),
1193 group.getName(),
1194 fromAddress,
1195 fromName,
1196 node.getName(),
1197 page.getContent(),
1198 String.valueOf(page.getPageId()),
1199 page.getTitle(),
1200 user.getEmailAddress(),
1201 user.getFullName(),
1202 company.getVirtualHost(),
1203 portletName
1204 });
1205
1206 body = StringUtil.replace(
1207 body,
1208 new String[] {
1209 "[$COMPANY_ID$]",
1210 "[$COMPANY_MX$]",
1211 "[$COMPANY_NAME$]",
1212 "[$COMMUNITY_NAME$]",
1213 "[$FROM_ADDRESS$]",
1214 "[$FROM_NAME$]",
1215 "[$NODE_NAME$]",
1216 "[$PAGE_CONTENT$]",
1217 "[$PAGE_ID$]",
1218 "[$PAGE_TITLE$]",
1219 "[$PAGE_URL$]",
1220 "[$PAGE_USER_ADDRESS$]",
1221 "[$PAGE_USER_NAME$]",
1222 "[$PORTAL_URL$]",
1223 "[$PORTLET_NAME$]"
1224 },
1225 new String[] {
1226 String.valueOf(company.getCompanyId()),
1227 company.getMx(),
1228 company.getName(),
1229 group.getName(),
1230 fromAddress,
1231 fromName,
1232 node.getName(),
1233 page.getContent(),
1234 String.valueOf(page.getPageId()),
1235 page.getTitle(),
1236 pageURL,
1237 user.getEmailAddress(),
1238 user.getFullName(),
1239 company.getVirtualHost(),
1240 portletName
1241 });
1242
1243 String subject = page.getTitle();
1244
1245 if (subject.indexOf(subjectPrefix) == -1) {
1246 subject = subjectPrefix + subject;
1247 }
1248
1249 Message message = new Message();
1250
1251 message.put("companyId", node.getCompanyId());
1252 message.put("userId", node.getUserId());
1253 message.put("nodeId", node.getNodeId());
1254 message.put("pageResourcePrimKey", page.getResourcePrimKey());
1255 message.put("fromName", fromName);
1256 message.put("fromAddress", fromAddress);
1257 message.put("subject", subject);
1258 message.put("body", body);
1259 message.put("replyToAddress", replyToAddress);
1260 message.put("mailId", mailId);
1261
1262 MessageBusUtil.sendMessage(DestinationNames.WIKI, message);
1263 }
1264
1265 protected void validate(long nodeId, String content, String format)
1266 throws PortalException {
1267
1268 if (!WikiUtil.validate(nodeId, content, format)) {
1269 throw new PageContentException();
1270 }
1271 }
1272
1273 protected void validate(
1274 String title, long nodeId, String content, String format)
1275 throws PortalException {
1276
1277 if (Validator.isNull(title)) {
1278 throw new PageTitleException();
1279 }
1280
1281 validateTitle(title);
1282
1283 validate(nodeId, content, format);
1284 }
1285
1286 private static Log _log =
1287 LogFactoryUtil.getLog(WikiPageLocalServiceImpl.class);
1288
1289}