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 (Validator.isNotNull(PropsValues.WIKI_PAGE_TITLES_REGEXP)) {
980 Pattern pattern = Pattern.compile(
981 PropsValues.WIKI_PAGE_TITLES_REGEXP);
982
983 Matcher matcher = pattern.matcher(title);
984
985 if (!matcher.matches()) {
986 throw new PageTitleException();
987 }
988 }
989 }
990
991 protected void clearPageCache(WikiPage page) {
992 if (!WikiCacheThreadLocal.isClearCache()) {
993 return;
994 }
995
996 WikiCacheUtil.clearCache(page.getNodeId(), page.getTitle());
997 }
998
999 protected void clearReferralsCache(WikiPage page)
1000 throws PortalException, SystemException {
1001
1002 if (!WikiCacheThreadLocal.isClearCache()) {
1003 return;
1004 }
1005
1006 List<WikiPage> links = getIncomingLinks(
1007 page.getNodeId(), page.getTitle());
1008
1009 for (WikiPage curPage : links) {
1010 WikiCacheUtil.clearCache(curPage.getNodeId(), curPage.getTitle());
1011 }
1012 }
1013
1014 protected boolean isLinkedTo(WikiPage page, String targetTitle)
1015 throws PortalException {
1016
1017 Map<String, Boolean> links = WikiCacheUtil.getOutgoingLinks(page);
1018
1019 Boolean link = links.get(targetTitle);
1020
1021 if (link != null) {
1022 return true;
1023 }
1024 else {
1025 return false;
1026 }
1027 }
1028
1029 protected boolean isUsedTitle(long nodeId, String title)
1030 throws SystemException {
1031
1032 if (getPagesCount(nodeId, title, true) > 0) {
1033 return true;
1034 }
1035 else {
1036 return false;
1037 }
1038 }
1039
1040 protected void notifySubscribers(
1041 WikiNode node, WikiPage page, PortletPreferences prefs,
1042 ThemeDisplay themeDisplay, boolean update)
1043 throws PortalException, SystemException {
1044
1045 if (prefs == null) {
1046 long ownerId = node.getGroupId();
1047 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
1048 long plid = PortletKeys.PREFS_PLID_SHARED;
1049 String portletId = PortletKeys.WIKI;
1050 String defaultPreferences = null;
1051
1052 prefs = portletPreferencesLocalService.getPreferences(
1053 node.getCompanyId(), ownerId, ownerType, plid, portletId,
1054 defaultPreferences);
1055 }
1056
1057 if (!update && WikiUtil.getEmailPageAddedEnabled(prefs)) {
1058 }
1059 else if (update && WikiUtil.getEmailPageUpdatedEnabled(prefs)) {
1060 }
1061 else {
1062 return;
1063 }
1064
1065 Company company = companyPersistence.findByPrimaryKey(
1066 page.getCompanyId());
1067
1068 Group group = groupPersistence.findByPrimaryKey(node.getGroupId());
1069
1070 User user = userPersistence.findByPrimaryKey(page.getUserId());
1071
1072 String pageURL = StringPool.BLANK;
1073
1074 if (themeDisplay != null) {
1075 String portalURL = PortalUtil.getPortalURL(themeDisplay);
1076 String layoutURL = PortalUtil.getLayoutURL(themeDisplay);
1077
1078 pageURL =
1079 portalURL + layoutURL + "/wiki/" + node.getNodeId() + "/" +
1080 page.getTitle();
1081 }
1082
1083 String portletName = PortalUtil.getPortletTitle(
1084 PortletKeys.WIKI, user);
1085
1086 String fromName = WikiUtil.getEmailFromName(prefs);
1087 String fromAddress = WikiUtil.getEmailFromAddress(prefs);
1088
1089 String replyToAddress = fromAddress;
1090 String mailId = WikiUtil.getMailId(
1091 company.getMx(), page.getNodeId(), page.getPageId());
1092
1093 fromName = StringUtil.replace(
1094 fromName,
1095 new String[] {
1096 "[$COMPANY_ID$]",
1097 "[$COMPANY_MX$]",
1098 "[$COMPANY_NAME$]",
1099 "[$COMMUNITY_NAME$]",
1100 "[$PAGE_USER_ADDRESS$]",
1101 "[$PAGE_USER_NAME$]",
1102 "[$PORTLET_NAME$]"
1103 },
1104 new String[] {
1105 String.valueOf(company.getCompanyId()),
1106 company.getMx(),
1107 company.getName(),
1108 group.getName(),
1109 user.getEmailAddress(),
1110 user.getFullName(),
1111 portletName
1112 });
1113
1114 fromAddress = StringUtil.replace(
1115 fromAddress,
1116 new String[] {
1117 "[$COMPANY_ID$]",
1118 "[$COMPANY_MX$]",
1119 "[$COMPANY_NAME$]",
1120 "[$COMMUNITY_NAME$]",
1121 "[$PAGE_USER_ADDRESS$]",
1122 "[$PAGE_USER_NAME$]",
1123 "[$PORTLET_NAME$]"
1124 },
1125 new String[] {
1126 String.valueOf(company.getCompanyId()),
1127 company.getMx(),
1128 company.getName(),
1129 group.getName(),
1130 user.getEmailAddress(),
1131 user.getFullName(),
1132 portletName
1133 });
1134
1135 String subjectPrefix = null;
1136 String body = null;
1137 String signature = null;
1138
1139 if (update) {
1140 subjectPrefix = WikiUtil.getEmailPageUpdatedSubjectPrefix(prefs);
1141 body = WikiUtil.getEmailPageUpdatedBody(prefs);
1142 signature = WikiUtil.getEmailPageUpdatedSignature(prefs);
1143 }
1144 else {
1145 subjectPrefix = WikiUtil.getEmailPageAddedSubjectPrefix(prefs);
1146 body = WikiUtil.getEmailPageAddedBody(prefs);
1147 signature = WikiUtil.getEmailPageAddedSignature(prefs);
1148 }
1149
1150 if (Validator.isNotNull(signature)) {
1151 body += "\n--\n" + signature;
1152 }
1153
1154 subjectPrefix = StringUtil.replace(
1155 subjectPrefix,
1156 new String[] {
1157 "[$COMPANY_ID$]",
1158 "[$COMPANY_MX$]",
1159 "[$COMPANY_NAME$]",
1160 "[$COMMUNITY_NAME$]",
1161 "[$FROM_ADDRESS$]",
1162 "[$FROM_NAME$]",
1163 "[$NODE_NAME$]",
1164 "[$PAGE_CONTENT$]",
1165 "[$PAGE_ID$]",
1166 "[$PAGE_TITLE$]",
1167 "[$PAGE_USER_ADDRESS$]",
1168 "[$PAGE_USER_NAME$]",
1169 "[$PORTAL_URL$]",
1170 "[$PORTLET_NAME$]"
1171 },
1172 new String[] {
1173 String.valueOf(company.getCompanyId()),
1174 company.getMx(),
1175 company.getName(),
1176 group.getName(),
1177 fromAddress,
1178 fromName,
1179 node.getName(),
1180 page.getContent(),
1181 String.valueOf(page.getPageId()),
1182 page.getTitle(),
1183 user.getEmailAddress(),
1184 user.getFullName(),
1185 company.getVirtualHost(),
1186 portletName
1187 });
1188
1189 body = StringUtil.replace(
1190 body,
1191 new String[] {
1192 "[$COMPANY_ID$]",
1193 "[$COMPANY_MX$]",
1194 "[$COMPANY_NAME$]",
1195 "[$COMMUNITY_NAME$]",
1196 "[$FROM_ADDRESS$]",
1197 "[$FROM_NAME$]",
1198 "[$NODE_NAME$]",
1199 "[$PAGE_CONTENT$]",
1200 "[$PAGE_ID$]",
1201 "[$PAGE_TITLE$]",
1202 "[$PAGE_URL$]",
1203 "[$PAGE_USER_ADDRESS$]",
1204 "[$PAGE_USER_NAME$]",
1205 "[$PORTAL_URL$]",
1206 "[$PORTLET_NAME$]"
1207 },
1208 new String[] {
1209 String.valueOf(company.getCompanyId()),
1210 company.getMx(),
1211 company.getName(),
1212 group.getName(),
1213 fromAddress,
1214 fromName,
1215 node.getName(),
1216 page.getContent(),
1217 String.valueOf(page.getPageId()),
1218 page.getTitle(),
1219 pageURL,
1220 user.getEmailAddress(),
1221 user.getFullName(),
1222 company.getVirtualHost(),
1223 portletName
1224 });
1225
1226 String subject = page.getTitle();
1227
1228 if (subject.indexOf(subjectPrefix) == -1) {
1229 subject = subjectPrefix + subject;
1230 }
1231
1232 JSONObject jsonObj = JSONFactoryUtil.createJSONObject();
1233
1234 jsonObj.put("companyId", node.getCompanyId());
1235 jsonObj.put("userId", node.getUserId());
1236 jsonObj.put("nodeId", node.getNodeId());
1237 jsonObj.put("pageResourcePrimKey", page.getResourcePrimKey());
1238 jsonObj.put("fromName", fromName);
1239 jsonObj.put("fromAddress", fromAddress);
1240 jsonObj.put("subject", subject);
1241 jsonObj.put("body", body);
1242 jsonObj.put("replyToAddress", replyToAddress);
1243 jsonObj.put("mailId", mailId);
1244
1245 MessageBusUtil.sendMessage(DestinationNames.WIKI, jsonObj.toString());
1246 }
1247
1248 protected void validate(long nodeId, String content, String format)
1249 throws PortalException {
1250
1251 if (!WikiUtil.validate(nodeId, content, format)) {
1252 throw new PageContentException();
1253 }
1254 }
1255
1256 protected void validate(
1257 String title, long nodeId, String content, String format)
1258 throws PortalException {
1259
1260 if (Validator.isNull(title)) {
1261 throw new PageTitleException();
1262 }
1263
1264 validateTitle(title);
1265
1266 validate(nodeId, content, format);
1267 }
1268
1269 private static Log _log = LogFactory.getLog(WikiPageLocalServiceImpl.class);
1270
1271}