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