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