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