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 WikiPage page = getPage(nodeId, title);
315
316 String originalParentTitle = page.getParentTitle();
317
318 double version = page.getVersion();
319 String content = page.getContent();
320 String summary = themeDisplay.translate(
321 "changed-parent-from-x", originalParentTitle);
322 boolean minorEdit = false;
323 String format = page.getFormat();
324 String redirectTitle = page.getRedirectTitle();
325 String[] tagsEntries = tagsEntryLocalService.getEntryNames(
326 WikiPage.class.getName(), page.getResourcePrimKey());
327
328 updatePage(
329 userId, nodeId, title, version, content, summary, minorEdit,
330 format, newParentTitle, redirectTitle, tagsEntries, prefs,
331 themeDisplay);
332
333 List<WikiPage> oldPages = wikiPagePersistence.findByN_T_H(
334 nodeId, title, false);
335
336 for (WikiPage oldPage : oldPages) {
337 oldPage.setParentTitle(originalParentTitle);
338
339 wikiPagePersistence.update(oldPage, false);
340 }
341 }
342
343 public void deletePage(long nodeId, String title)
344 throws PortalException, SystemException {
345
346 List<WikiPage> pages = wikiPagePersistence.findByN_T_H(
347 nodeId, title, true, 0, 1);
348
349 if (pages.size() > 0) {
350 WikiPage page = pages.iterator().next();
351
352 deletePage(page);
353 }
354 }
355
356 public void deletePage(WikiPage page)
357 throws PortalException, SystemException {
358
359
361 List<WikiPage> children = wikiPagePersistence.findByN_P(
362 page.getNodeId(), page.getTitle());
363
364 for (WikiPage curPage : children) {
365 deletePage(curPage);
366 }
367
368
370 try {
371 Indexer.deletePage(
372 page.getCompanyId(), page.getNodeId(), page.getTitle());
373 }
374 catch (SearchException se) {
375 _log.error("Deleting index " + page.getPrimaryKey(), se);
376 }
377
378
380 long companyId = page.getCompanyId();
381 String portletId = CompanyConstants.SYSTEM_STRING;
382 long repositoryId = CompanyConstants.SYSTEM;
383 String dirName = page.getAttachmentsDir();
384
385 try {
386 dlService.deleteDirectory(
387 companyId, portletId, repositoryId, dirName);
388 }
389 catch (NoSuchDirectoryException nsde) {
390 }
391 catch (RemoteException re) {
392 throw new SystemException(re);
393 }
394
395
397 tagsAssetLocalService.deleteAsset(
398 WikiPage.class.getName(), page.getResourcePrimKey());
399
400
402 subscriptionLocalService.deleteSubscriptions(
403 page.getCompanyId(), WikiPage.class.getName(), page.getPageId());
404
405
407 socialActivityLocalService.deleteActivities(
408 WikiPage.class.getName(), page.getResourcePrimKey());
409
410
412 mbMessageLocalService.deleteDiscussionMessages(
413 WikiPage.class.getName(), page.getResourcePrimKey());
414
415
417 resourceLocalService.deleteResource(
418 page.getCompanyId(), WikiPage.class.getName(),
419 ResourceConstants.SCOPE_INDIVIDUAL, page.getResourcePrimKey());
420
421
423 wikiPageResourceLocalService.deletePageResource(
424 page.getNodeId(), page.getTitle());
425
426
428 wikiPagePersistence.removeByN_T(page.getNodeId(), page.getTitle());
429
430
432 wikiPagePersistence.removeByN_R(page.getNodeId(), page.getTitle());
433
434
436 clearPageCache(page);
437 clearReferralsCache(page);
438 }
439
440 public void deletePageAttachment(long nodeId, String title, String fileName)
441 throws PortalException, SystemException {
442
443 if (Validator.isNull(fileName)) {
444 return;
445 }
446
447 WikiPage page = getPage(nodeId, title);
448
449 long companyId = page.getCompanyId();
450 String portletId = CompanyConstants.SYSTEM_STRING;
451 long repositoryId = CompanyConstants.SYSTEM;
452
453 try {
454 dlService.deleteFile(companyId, portletId, repositoryId, fileName);
455 }
456 catch (NoSuchFileException nsfe) {
457 }
458 catch (RemoteException re) {
459 throw new SystemException(re);
460 }
461 }
462
463 public void deletePages(long nodeId)
464 throws PortalException, SystemException {
465
466 Iterator<WikiPage> itr = wikiPagePersistence.findByN_H(
467 nodeId, true).iterator();
468
469 while (itr.hasNext()) {
470 WikiPage page = itr.next();
471
472 deletePage(page);
473 }
474 }
475
476 public List<WikiPage> getChildren(
477 long nodeId, boolean head, String parentTitle)
478 throws SystemException {
479
480 return wikiPagePersistence.findByN_H_P(nodeId, head, parentTitle);
481 }
482
483 public List<WikiPage> getIncomingLinks(long nodeId, String title)
484 throws PortalException, SystemException {
485
486 List<WikiPage> links = new UniqueList<WikiPage>();
487
488 List<WikiPage> pages = wikiPagePersistence.findByN_H(nodeId, true);
489
490 for (WikiPage page : pages) {
491 if (isLinkedTo(page, title)) {
492 links.add(page);
493 }
494 }
495
496 List<WikiPage> referrals = wikiPagePersistence.findByN_R(nodeId, title);
497
498 for (WikiPage referral : referrals) {
499 for (WikiPage page : pages) {
500 if (isLinkedTo(page, referral.getTitle())) {
501 links.add(page);
502 }
503 }
504 }
505
506 return ListUtil.sort(links);
507 }
508
509 public List<WikiPage> getNoAssetPages() throws SystemException {
510 return wikiPageFinder.findByNoAssets();
511 }
512
513 public List<WikiPage> getOrphans(long nodeId)
514 throws PortalException, SystemException {
515
516 List<Map<String, Boolean>> pageTitles =
517 new ArrayList<Map<String, Boolean>>();
518
519 List<WikiPage> pages = wikiPagePersistence.findByN_H(nodeId, true);
520
521 for (WikiPage page : pages) {
522 pageTitles.add(WikiCacheUtil.getOutgoingLinks(page));
523 }
524
525 Set<WikiPage> notOrphans = new HashSet<WikiPage>();
526
527 for (WikiPage page : pages) {
528 for (Map<String, Boolean> pageTitle : pageTitles) {
529 if (pageTitle.get(page.getTitle()) != null) {
530 notOrphans.add(page);
531
532 break;
533 }
534 }
535 }
536
537 List<WikiPage> orphans = new ArrayList<WikiPage>();
538
539 for (WikiPage page : pages) {
540 if (!notOrphans.contains(page)) {
541 orphans.add(page);
542 }
543 }
544
545 orphans = ListUtil.sort(orphans);
546
547 return orphans;
548 }
549
550 public List<WikiPage> getOutgoingLinks(long nodeId, String title)
551 throws PortalException, SystemException {
552
553 WikiPage page = getPage(nodeId, title);
554
555 Map<String, WikiPage> pages = new LinkedHashMap<String, WikiPage>();
556
557 Map<String, Boolean> links = WikiCacheUtil.getOutgoingLinks(page);
558
559 for (String curTitle : links.keySet()) {
560 Boolean exists = links.get(curTitle);
561
562 if (exists) {
563 if (!pages.containsKey(curTitle)) {
564 pages.put(curTitle, getPage(nodeId, curTitle));
565 }
566 }
567 else {
568 WikiPageImpl newPage = new WikiPageImpl();
569
570 newPage.setNew(true);
571 newPage.setNodeId(nodeId);
572 newPage.setTitle(curTitle);
573
574 if (!pages.containsKey(curTitle)) {
575 pages.put(curTitle, newPage);
576 }
577 }
578 }
579
580 return ListUtil.fromCollection(pages.values());
581 }
582
583 public WikiPage getPage(long resourcePrimKey)
584 throws PortalException, SystemException {
585
586 WikiPageResource wikiPageResource =
587 wikiPageResourceLocalService.getPageResource(resourcePrimKey);
588
589 return getPage(
590 wikiPageResource.getNodeId(), wikiPageResource.getTitle());
591 }
592
593 public WikiPage getPage(long nodeId, String title)
594 throws PortalException, SystemException {
595
596 List<WikiPage> pages = wikiPagePersistence.findByN_T_H(
597 nodeId, title, true, 0, 1);
598
599 if (pages.size() > 0) {
600 return pages.get(0);
601 }
602 else {
603 throw new NoSuchPageException();
604 }
605 }
606
607 public WikiPage getPage(long nodeId, String title, double version)
608 throws PortalException, SystemException {
609
610 WikiPage page = null;
611
612 if (version == 0) {
613 page = getPage(nodeId, title);
614 }
615 else {
616 page = wikiPagePersistence.findByN_T_V(nodeId, title, version);
617 }
618
619 return page;
620 }
621
622 public WikiPageDisplay getPageDisplay(
623 long nodeId, String title, PortletURL viewPageURL,
624 PortletURL editPageURL, String attachmentURLPrefix)
625 throws PortalException, SystemException {
626
627 WikiPage page = getPage(nodeId, title);
628
629 String formattedContent = WikiUtil.convert(
630 page, viewPageURL, editPageURL, attachmentURLPrefix);
631
632 return new WikiPageDisplayImpl(
633 page.getUserId(), page.getNodeId(), page.getTitle(),
634 page.getVersion(), page.getContent(), formattedContent,
635 page.getFormat(), page.getHead(), page.getAttachmentsFiles());
636 }
637
638 public List<WikiPage> getPages(long nodeId, int start, int end)
639 throws SystemException {
640
641 return wikiPagePersistence.findByNodeId(
642 nodeId, start, end, new PageCreateDateComparator(false));
643 }
644
645 public List<WikiPage> getPages(String format) throws SystemException {
646 return wikiPagePersistence.findByFormat(format);
647 }
648
649 public List<WikiPage> getPages(
650 long nodeId, String title, int start, int end)
651 throws SystemException {
652
653 return wikiPagePersistence.findByN_T(
654 nodeId, title, start, end, new PageCreateDateComparator(false));
655 }
656
657 public List<WikiPage> getPages(
658 long nodeId, String title, int start, int end,
659 OrderByComparator obc)
660 throws SystemException {
661
662 return wikiPagePersistence.findByN_T(nodeId, title, start, end, obc);
663 }
664
665 public List<WikiPage> getPages(
666 long nodeId, boolean head, int start, int end)
667 throws SystemException {
668
669 return wikiPagePersistence.findByN_H(
670 nodeId, head, start, end, new PageCreateDateComparator(false));
671 }
672
673 public List<WikiPage> getPages(
674 long nodeId, String title, boolean head, int start, int end)
675 throws SystemException {
676
677 return wikiPagePersistence.findByN_T_H(
678 nodeId, title, head, start, end,
679 new PageCreateDateComparator(false));
680 }
681
682 public int getPagesCount(long nodeId) throws SystemException {
683 return wikiPagePersistence.countByNodeId(nodeId);
684 }
685
686 public int getPagesCount(long nodeId, String title)
687 throws SystemException {
688
689 return wikiPagePersistence.countByN_T(nodeId, title);
690 }
691
692 public int getPagesCount(long nodeId, boolean head)
693 throws SystemException {
694
695 return wikiPagePersistence.countByN_H(nodeId, head);
696 }
697
698 public int getPagesCount(long nodeId, String title, boolean head)
699 throws SystemException {
700
701 return wikiPagePersistence.countByN_T_H(nodeId, title, head);
702 }
703
704 public int getPagesCount(String format) throws SystemException {
705 return wikiPagePersistence.countByFormat(format);
706 }
707
708 public List<WikiPage> getRecentChanges(long nodeId, int start, int end)
709 throws SystemException {
710
711 Calendar cal = CalendarFactoryUtil.getCalendar();
712
713 cal.add(Calendar.WEEK_OF_YEAR, -1);
714
715 return wikiPageFinder.findByCreateDate(
716 nodeId, cal.getTime(), false, start, end);
717 }
718
719 public int getRecentChangesCount(long nodeId) throws SystemException {
720 Calendar cal = CalendarFactoryUtil.getCalendar();
721
722 cal.add(Calendar.WEEK_OF_YEAR, -1);
723
724 return wikiPageFinder.countByCreateDate(nodeId, cal.getTime(), false);
725 }
726
727 public void movePage(
728 long userId, long nodeId, String title, String newTitle,
729 PortletPreferences prefs, ThemeDisplay themeDisplay)
730 throws PortalException, SystemException {
731
732 movePage(userId, nodeId, title, newTitle, true, prefs, themeDisplay);
733 }
734
735 public void movePage(
736 long userId, long nodeId, String title, String newTitle,
737 boolean strict, PortletPreferences prefs, ThemeDisplay themeDisplay)
738 throws PortalException, SystemException {
739
740 validateTitle(newTitle);
741
742
744 if (isUsedTitle(nodeId, newTitle)) {
745 WikiPage page = getPage(nodeId, newTitle);
746
747
749 if (((page.getVersion() == WikiPageImpl.DEFAULT_VERSION) &&
750 (page.getContent().length() < 200)) ||
751 !strict) {
752
753 deletePage(nodeId, newTitle);
754 }
755 else {
756 throw new DuplicatePageException(newTitle);
757 }
758 }
759
760
762 List<WikiPage> pageVersions = wikiPagePersistence.findByN_T(
763 nodeId, title);
764
765 if (pageVersions.size() == 0) {
766 return;
767 }
768
769 for (WikiPage page : pageVersions) {
770 page.setTitle(newTitle);
771
772 wikiPagePersistence.update(page, false);
773 }
774
775
777 List<WikiPage> children = wikiPagePersistence.findByN_P(nodeId, title);
778
779 for (WikiPage page : children) {
780 page.setParentTitle(newTitle);
781
782 wikiPagePersistence.update(page, false);
783 }
784
785 WikiPage page = pageVersions.get(pageVersions.size() - 1);
786
787
789 WikiPageResource wikiPageResource =
790 wikiPageResourcePersistence.findByPrimaryKey(
791 page.getResourcePrimKey());
792
793 wikiPageResource.setTitle(newTitle);
794
795 wikiPageResourcePersistence.update(wikiPageResource, false);
796
797
799 String uuid = null;
800 double version = WikiPageImpl.DEFAULT_VERSION;
801 String format = page.getFormat();
802 boolean head = true;
803 String parentTitle = page.getParentTitle();
804 String redirectTitle = page.getTitle();
805 String content =
806 StringPool.DOUBLE_OPEN_BRACKET + redirectTitle +
807 StringPool.DOUBLE_CLOSE_BRACKET;
808 String summary = WikiPageImpl.MOVED + " to " + title;
809
810 addPage(
811 uuid, userId, nodeId, title, version, content, summary, false,
812 format, head, parentTitle, redirectTitle, null, prefs,
813 themeDisplay);
814
815
817 List<WikiPage> redirectedPages = wikiPagePersistence.findByN_R(
818 nodeId, title);
819
820 for (WikiPage redirectedPage : redirectedPages) {
821 redirectedPage.setRedirectTitle(newTitle);
822
823 wikiPagePersistence.update(redirectedPage, false);
824 }
825
826
828 String[] tagsEntries = tagsEntryLocalService.getEntryNames(
829 WikiPage.class.getName(), page.getResourcePrimKey());
830
831 updateTagsAsset(userId, page, tagsEntries);
832
833
835 try {
836 Indexer.deletePage(page.getCompanyId(), page.getGroupId(), title);
837 }
838 catch (SearchException se) {
839 _log.error("Indexing " + newTitle, se);
840 }
841
842 reIndex(page);
843 }
844
845 public void reIndex(long resourcePrimKey) throws SystemException {
846 if (SearchEngineUtil.isIndexReadOnly()) {
847 return;
848 }
849
850 WikiPage page = null;
851
852 try {
853 page = wikiPageFinder.findByResourcePrimKey(resourcePrimKey);
854 }
855 catch (NoSuchPageException nspe) {
856 return;
857 }
858
859 reIndex(page);
860 }
861
862 public void reIndex(WikiPage page) throws SystemException {
863 if (Validator.isNotNull(page.getRedirectTitle())) {
864 return;
865 }
866
867 long companyId = page.getCompanyId();
868 long groupId = page.getGroupId();
869 long resourcePrimKey = page.getResourcePrimKey();
870 long nodeId = page.getNodeId();
871 String title = page.getTitle();
872 String content = page.getContent();
873 Date modifiedDate = page.getModifiedDate();
874
875 String[] tagsEntries = tagsEntryLocalService.getEntryNames(
876 WikiPage.class.getName(), resourcePrimKey);
877
878 try {
879 Indexer.updatePage(
880 companyId, groupId, nodeId, title, content, modifiedDate,
881 tagsEntries);
882 }
883 catch (SearchException se) {
884 _log.error("Reindexing " + page.getPrimaryKey(), se);
885 }
886 }
887
888 public WikiPage revertPage(
889 long userId, long nodeId, String title, double version,
890 PortletPreferences prefs, ThemeDisplay themeDisplay)
891 throws PortalException, SystemException {
892
893 WikiPage oldPage = getPage(nodeId, title, version);
894
895 return updatePage(
896 userId, nodeId, title, 0, oldPage.getContent(),
897 WikiPageImpl.REVERTED + " to " + version, false,
898 oldPage.getFormat(), null, oldPage.getRedirectTitle(), null, prefs,
899 themeDisplay);
900 }
901
902 public void subscribePage(long userId, long nodeId, String title)
903 throws PortalException, SystemException {
904
905 WikiPage page = getPage(nodeId, title);
906
907 subscriptionLocalService.addSubscription(
908 userId, WikiPage.class.getName(), page.getResourcePrimKey());
909 }
910
911 public void unsubscribePage(long userId, long nodeId, String title)
912 throws PortalException, SystemException {
913
914 WikiPage page = getPage(nodeId, title);
915
916 subscriptionLocalService.deleteSubscription(
917 userId, WikiPage.class.getName(), page.getResourcePrimKey());
918 }
919
920 public WikiPage updatePage(
921 long userId, long nodeId, String title, double version,
922 String content, String summary, boolean minorEdit, String format,
923 String parentTitle, String redirectTitle, String[] tagsEntries,
924 PortletPreferences prefs, ThemeDisplay themeDisplay)
925 throws PortalException, SystemException {
926
927
929 User user = userPersistence.findByPrimaryKey(userId);
930 Date now = new Date();
931
932 validate(nodeId, content, format);
933
934 WikiPage page = null;
935
936 try {
937 page = getPage(nodeId, title);
938 }
939 catch (NoSuchPageException nspe) {
940 return addPage(
941 null, userId, nodeId, title, WikiPageImpl.DEFAULT_VERSION,
942 content, summary, minorEdit, format, true, parentTitle,
943 redirectTitle, tagsEntries, prefs, themeDisplay);
944 }
945
946 double oldVersion = page.getVersion();
947
948 if ((version > 0) && (version != oldVersion)) {
949 throw new PageVersionException();
950 }
951
952 long resourcePrimKey = page.getResourcePrimKey();
953 long groupId = page.getGroupId();
954
955 page.setHead(false);
956 page.setModifiedDate(now);
957
958 wikiPagePersistence.update(page, false);
959
960 double newVersion = MathUtil.format(oldVersion + 0.1, 1, 1);
961
962 long pageId = counterLocalService.increment();
963
964 page = wikiPagePersistence.create(pageId);
965
966 page.setResourcePrimKey(resourcePrimKey);
967 page.setGroupId(groupId);
968 page.setCompanyId(user.getCompanyId());
969 page.setUserId(user.getUserId());
970 page.setUserName(user.getFullName());
971 page.setCreateDate(now);
972 page.setModifiedDate(now);
973 page.setNodeId(nodeId);
974 page.setTitle(title);
975 page.setVersion(newVersion);
976 page.setMinorEdit(minorEdit);
977 page.setContent(content);
978 page.setSummary(summary);
979 page.setFormat(format);
980 page.setHead(true);
981
982 if (Validator.isNotNull(parentTitle)) {
983 page.setParentTitle(parentTitle);
984 }
985
986 if (Validator.isNotNull(redirectTitle)) {
987 page.setRedirectTitle(redirectTitle);
988 }
989
990 wikiPagePersistence.update(page, false);
991
992
994 WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
995
996 node.setLastPostDate(now);
997
998 wikiNodePersistence.update(node, false);
999
1000
1002 socialActivityLocalService.addActivity(
1003 userId, page.getGroupId(), WikiPage.class.getName(),
1004 page.getResourcePrimKey(), WikiActivityKeys.UPDATE_PAGE,
1005 StringPool.BLANK, 0);
1006
1007
1009 if (!minorEdit && NotificationThreadLocal.isNotificationEnabled()) {
1010 notifySubscribers(node, page, prefs, themeDisplay, true);
1011 }
1012
1013
1015 updateTagsAsset(userId, page, tagsEntries);
1016
1017
1019 reIndex(page);
1020
1021
1023 clearPageCache(page);
1024
1025 return page;
1026 }
1027
1028 public void updateTagsAsset(
1029 long userId, WikiPage page, String[] tagsEntries)
1030 throws PortalException, SystemException {
1031
1032 tagsAssetLocalService.updateAsset(
1033 userId, page.getGroupId(), WikiPage.class.getName(),
1034 page.getResourcePrimKey(), tagsEntries, null, null, null, null,
1035 ContentTypes.TEXT_HTML, page.getTitle(), null, null, null, 0, 0,
1036 null, false);
1037 }
1038
1039 public void validateTitle(String title) throws PortalException {
1040 if (title.equals("all_pages") || title.equals("orphan_pages") ||
1041 title.equals("recent_changes")) {
1042
1043 throw new PageTitleException(title + " is reserved");
1044 }
1045
1046 if (Validator.isNotNull(PropsValues.WIKI_PAGE_TITLES_REGEXP)) {
1047 Pattern pattern = Pattern.compile(
1048 PropsValues.WIKI_PAGE_TITLES_REGEXP);
1049
1050 Matcher matcher = pattern.matcher(title);
1051
1052 if (!matcher.matches()) {
1053 throw new PageTitleException();
1054 }
1055 }
1056 }
1057
1058 protected void clearPageCache(WikiPage page) {
1059 if (!WikiCacheThreadLocal.isClearCache()) {
1060 return;
1061 }
1062
1063 WikiCacheUtil.clearCache(page.getNodeId(), page.getTitle());
1064 }
1065
1066 protected void clearReferralsCache(WikiPage page)
1067 throws PortalException, SystemException {
1068
1069 if (!WikiCacheThreadLocal.isClearCache()) {
1070 return;
1071 }
1072
1073 List<WikiPage> links = getIncomingLinks(
1074 page.getNodeId(), page.getTitle());
1075
1076 for (WikiPage curPage : links) {
1077 WikiCacheUtil.clearCache(curPage.getNodeId(), curPage.getTitle());
1078 }
1079 }
1080
1081 protected boolean isLinkedTo(WikiPage page, String targetTitle)
1082 throws PortalException {
1083
1084 Map<String, Boolean> links = WikiCacheUtil.getOutgoingLinks(page);
1085
1086 Boolean link = links.get(targetTitle);
1087
1088 if (link != null) {
1089 return true;
1090 }
1091 else {
1092 return false;
1093 }
1094 }
1095
1096 protected boolean isUsedTitle(long nodeId, String title)
1097 throws SystemException {
1098
1099 if (getPagesCount(nodeId, title, true) > 0) {
1100 return true;
1101 }
1102 else {
1103 return false;
1104 }
1105 }
1106
1107 protected void notifySubscribers(
1108 WikiNode node, WikiPage page, PortletPreferences prefs,
1109 ThemeDisplay themeDisplay, boolean update)
1110 throws PortalException, SystemException {
1111
1112 if (prefs == null) {
1113 long ownerId = node.getGroupId();
1114 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
1115 long plid = PortletKeys.PREFS_PLID_SHARED;
1116 String portletId = PortletKeys.WIKI;
1117 String defaultPreferences = null;
1118
1119 prefs = portletPreferencesLocalService.getPreferences(
1120 node.getCompanyId(), ownerId, ownerType, plid, portletId,
1121 defaultPreferences);
1122 }
1123
1124 if (!update && WikiUtil.getEmailPageAddedEnabled(prefs)) {
1125 }
1126 else if (update && WikiUtil.getEmailPageUpdatedEnabled(prefs)) {
1127 }
1128 else {
1129 return;
1130 }
1131
1132 Company company = companyPersistence.findByPrimaryKey(
1133 page.getCompanyId());
1134
1135 Group group = groupPersistence.findByPrimaryKey(node.getGroupId());
1136
1137 User user = userPersistence.findByPrimaryKey(page.getUserId());
1138
1139 String pageURL = StringPool.BLANK;
1140
1141 if (themeDisplay != null) {
1142 String portalURL = PortalUtil.getPortalURL(themeDisplay);
1143 String layoutURL = PortalUtil.getLayoutURL(themeDisplay);
1144
1145 pageURL =
1146 portalURL + layoutURL + Portal.FRIENDLY_URL_SEPARATOR +
1147 "wiki/" + node.getNodeId() + StringPool.SLASH +
1148 HttpUtil.encodeURL(page.getTitle());
1149 }
1150
1151 String portletName = PortalUtil.getPortletTitle(
1152 PortletKeys.WIKI, user);
1153
1154 String fromName = WikiUtil.getEmailFromName(prefs);
1155 String fromAddress = WikiUtil.getEmailFromAddress(prefs);
1156
1157 String replyToAddress = fromAddress;
1158 String mailId = WikiUtil.getMailId(
1159 company.getMx(), page.getNodeId(), page.getPageId());
1160
1161 fromName = StringUtil.replace(
1162 fromName,
1163 new String[] {
1164 "[$COMPANY_ID$]",
1165 "[$COMPANY_MX$]",
1166 "[$COMPANY_NAME$]",
1167 "[$COMMUNITY_NAME$]",
1168 "[$PAGE_USER_ADDRESS$]",
1169 "[$PAGE_USER_NAME$]",
1170 "[$PORTLET_NAME$]"
1171 },
1172 new String[] {
1173 String.valueOf(company.getCompanyId()),
1174 company.getMx(),
1175 company.getName(),
1176 group.getName(),
1177 user.getEmailAddress(),
1178 user.getFullName(),
1179 portletName
1180 });
1181
1182 fromAddress = StringUtil.replace(
1183 fromAddress,
1184 new String[] {
1185 "[$COMPANY_ID$]",
1186 "[$COMPANY_MX$]",
1187 "[$COMPANY_NAME$]",
1188 "[$COMMUNITY_NAME$]",
1189 "[$PAGE_USER_ADDRESS$]",
1190 "[$PAGE_USER_NAME$]",
1191 "[$PORTLET_NAME$]"
1192 },
1193 new String[] {
1194 String.valueOf(company.getCompanyId()),
1195 company.getMx(),
1196 company.getName(),
1197 group.getName(),
1198 user.getEmailAddress(),
1199 user.getFullName(),
1200 portletName
1201 });
1202
1203 String subjectPrefix = null;
1204 String body = null;
1205 String signature = null;
1206
1207 if (update) {
1208 subjectPrefix = WikiUtil.getEmailPageUpdatedSubjectPrefix(prefs);
1209 body = WikiUtil.getEmailPageUpdatedBody(prefs);
1210 signature = WikiUtil.getEmailPageUpdatedSignature(prefs);
1211 }
1212 else {
1213 subjectPrefix = WikiUtil.getEmailPageAddedSubjectPrefix(prefs);
1214 body = WikiUtil.getEmailPageAddedBody(prefs);
1215 signature = WikiUtil.getEmailPageAddedSignature(prefs);
1216 }
1217
1218 if (Validator.isNotNull(signature)) {
1219 body += "\n--\n" + signature;
1220 }
1221
1222 subjectPrefix = StringUtil.replace(
1223 subjectPrefix,
1224 new String[] {
1225 "[$COMPANY_ID$]",
1226 "[$COMPANY_MX$]",
1227 "[$COMPANY_NAME$]",
1228 "[$COMMUNITY_NAME$]",
1229 "[$FROM_ADDRESS$]",
1230 "[$FROM_NAME$]",
1231 "[$NODE_NAME$]",
1232 "[$PAGE_CONTENT$]",
1233 "[$PAGE_ID$]",
1234 "[$PAGE_TITLE$]",
1235 "[$PAGE_USER_ADDRESS$]",
1236 "[$PAGE_USER_NAME$]",
1237 "[$PORTAL_URL$]",
1238 "[$PORTLET_NAME$]"
1239 },
1240 new String[] {
1241 String.valueOf(company.getCompanyId()),
1242 company.getMx(),
1243 company.getName(),
1244 group.getName(),
1245 fromAddress,
1246 fromName,
1247 node.getName(),
1248 page.getContent(),
1249 String.valueOf(page.getPageId()),
1250 page.getTitle(),
1251 user.getEmailAddress(),
1252 user.getFullName(),
1253 company.getVirtualHost(),
1254 portletName
1255 });
1256
1257 body = StringUtil.replace(
1258 body,
1259 new String[] {
1260 "[$COMPANY_ID$]",
1261 "[$COMPANY_MX$]",
1262 "[$COMPANY_NAME$]",
1263 "[$COMMUNITY_NAME$]",
1264 "[$FROM_ADDRESS$]",
1265 "[$FROM_NAME$]",
1266 "[$NODE_NAME$]",
1267 "[$PAGE_CONTENT$]",
1268 "[$PAGE_ID$]",
1269 "[$PAGE_TITLE$]",
1270 "[$PAGE_URL$]",
1271 "[$PAGE_USER_ADDRESS$]",
1272 "[$PAGE_USER_NAME$]",
1273 "[$PORTAL_URL$]",
1274 "[$PORTLET_NAME$]"
1275 },
1276 new String[] {
1277 String.valueOf(company.getCompanyId()),
1278 company.getMx(),
1279 company.getName(),
1280 group.getName(),
1281 fromAddress,
1282 fromName,
1283 node.getName(),
1284 page.getContent(),
1285 String.valueOf(page.getPageId()),
1286 page.getTitle(),
1287 pageURL,
1288 user.getEmailAddress(),
1289 user.getFullName(),
1290 company.getVirtualHost(),
1291 portletName
1292 });
1293
1294 String subject = page.getTitle();
1295
1296 if (subject.indexOf(subjectPrefix) == -1) {
1297 subject = subjectPrefix + subject;
1298 }
1299
1300 Message message = new Message();
1301
1302 message.put("companyId", node.getCompanyId());
1303 message.put("userId", node.getUserId());
1304 message.put("nodeId", node.getNodeId());
1305 message.put("pageResourcePrimKey", page.getResourcePrimKey());
1306 message.put("fromName", fromName);
1307 message.put("fromAddress", fromAddress);
1308 message.put("subject", subject);
1309 message.put("body", body);
1310 message.put("replyToAddress", replyToAddress);
1311 message.put("mailId", mailId);
1312
1313 MessageBusUtil.sendMessage(DestinationNames.WIKI, message);
1314 }
1315
1316 protected void validate(long nodeId, String content, String format)
1317 throws PortalException {
1318
1319 if (!WikiUtil.validate(nodeId, content, format)) {
1320 throw new PageContentException();
1321 }
1322 }
1323
1324 protected void validate(
1325 String title, long nodeId, String content, String format)
1326 throws PortalException, SystemException {
1327
1328 if (Validator.isNull(title)) {
1329 throw new PageTitleException();
1330 }
1331
1332 if (isUsedTitle(nodeId, title)) {
1333 throw new DuplicatePageException();
1334 }
1335
1336 validateTitle(title);
1337
1338 validate(nodeId, content, format);
1339 }
1340
1341 private static Log _log =
1342 LogFactoryUtil.getLog(WikiPageLocalServiceImpl.class);
1343
1344}