1
14
15 package com.liferay.portlet.wiki.service.impl;
16
17 import com.liferay.documentlibrary.DuplicateDirectoryException;
18 import com.liferay.documentlibrary.DuplicateFileException;
19 import com.liferay.documentlibrary.NoSuchDirectoryException;
20 import com.liferay.documentlibrary.NoSuchFileException;
21 import com.liferay.portal.PortalException;
22 import com.liferay.portal.SystemException;
23 import com.liferay.portal.kernel.log.Log;
24 import com.liferay.portal.kernel.log.LogFactoryUtil;
25 import com.liferay.portal.kernel.messaging.DestinationNames;
26 import com.liferay.portal.kernel.messaging.Message;
27 import com.liferay.portal.kernel.messaging.MessageBusUtil;
28 import com.liferay.portal.kernel.search.SearchEngineUtil;
29 import com.liferay.portal.kernel.search.SearchException;
30 import com.liferay.portal.kernel.util.CalendarFactoryUtil;
31 import com.liferay.portal.kernel.util.ContentTypes;
32 import com.liferay.portal.kernel.util.HttpUtil;
33 import com.liferay.portal.kernel.util.ListUtil;
34 import com.liferay.portal.kernel.util.MathUtil;
35 import com.liferay.portal.kernel.util.NotificationThreadLocal;
36 import com.liferay.portal.kernel.util.ObjectValuePair;
37 import com.liferay.portal.kernel.util.OrderByComparator;
38 import com.liferay.portal.kernel.util.StringPool;
39 import com.liferay.portal.kernel.util.StringUtil;
40 import com.liferay.portal.kernel.util.Validator;
41 import com.liferay.portal.model.Company;
42 import com.liferay.portal.model.CompanyConstants;
43 import com.liferay.portal.model.Group;
44 import com.liferay.portal.model.GroupConstants;
45 import com.liferay.portal.model.ResourceConstants;
46 import com.liferay.portal.model.User;
47 import com.liferay.portal.theme.ThemeDisplay;
48 import com.liferay.portal.util.Portal;
49 import com.liferay.portal.util.PortalUtil;
50 import com.liferay.portal.util.PortletKeys;
51 import com.liferay.portal.util.PropsValues;
52 import com.liferay.portlet.wiki.DuplicatePageException;
53 import com.liferay.portlet.wiki.NoSuchPageException;
54 import com.liferay.portlet.wiki.PageContentException;
55 import com.liferay.portlet.wiki.PageTitleException;
56 import com.liferay.portlet.wiki.PageVersionException;
57 import com.liferay.portlet.wiki.model.WikiNode;
58 import com.liferay.portlet.wiki.model.WikiPage;
59 import com.liferay.portlet.wiki.model.WikiPageDisplay;
60 import com.liferay.portlet.wiki.model.WikiPageResource;
61 import com.liferay.portlet.wiki.model.impl.WikiPageDisplayImpl;
62 import com.liferay.portlet.wiki.model.impl.WikiPageImpl;
63 import com.liferay.portlet.wiki.service.base.WikiPageLocalServiceBaseImpl;
64 import com.liferay.portlet.wiki.social.WikiActivityKeys;
65 import com.liferay.portlet.wiki.util.Indexer;
66 import com.liferay.portlet.wiki.util.WikiCacheThreadLocal;
67 import com.liferay.portlet.wiki.util.WikiCacheUtil;
68 import com.liferay.portlet.wiki.util.WikiUtil;
69 import com.liferay.portlet.wiki.util.comparator.PageCreateDateComparator;
70 import com.liferay.util.UniqueList;
71
72 import java.rmi.RemoteException;
73
74 import java.util.ArrayList;
75 import java.util.Calendar;
76 import java.util.Date;
77 import java.util.HashSet;
78 import java.util.Iterator;
79 import java.util.LinkedHashMap;
80 import java.util.List;
81 import java.util.Map;
82 import java.util.Set;
83 import java.util.regex.Matcher;
84 import java.util.regex.Pattern;
85
86 import javax.portlet.PortletPreferences;
87 import javax.portlet.PortletURL;
88
89
96 public class WikiPageLocalServiceImpl extends WikiPageLocalServiceBaseImpl {
97
98 public WikiPage addPage(
99 long userId, long nodeId, String title, String content,
100 String summary, boolean minorEdit, PortletPreferences prefs,
101 ThemeDisplay themeDisplay)
102 throws PortalException, SystemException {
103
104 String uuid = null;
105 double version = WikiPageImpl.DEFAULT_VERSION;
106 String format = WikiPageImpl.DEFAULT_FORMAT;
107 boolean head = true;
108 String parentTitle = null;
109 String redirectTitle = null;
110 String[] tagsEntries = null;
111
112 return addPage(
113 uuid, userId, nodeId, title, version, content, summary, minorEdit,
114 format, head, parentTitle, redirectTitle, tagsEntries, prefs,
115 themeDisplay);
116 }
117
118 public WikiPage addPage(
119 String uuid, long userId, long nodeId, String title, double version,
120 String content, String summary, boolean minorEdit, String format,
121 boolean head, String parentTitle, String redirectTitle,
122 String[] tagsEntries, PortletPreferences prefs,
123 ThemeDisplay themeDisplay)
124 throws PortalException, SystemException {
125
126
128 User user = userPersistence.findByPrimaryKey(userId);
129 WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
130
131 Date now = new Date();
132
133 validate(title, nodeId, content, format);
134
135 long pageId = counterLocalService.increment();
136
137 long resourcePrimKey =
138 wikiPageResourceLocalService.getPageResourcePrimKey(nodeId, title);
139
140 WikiPage page = wikiPagePersistence.create(pageId);
141
142 page.setUuid(uuid);
143 page.setResourcePrimKey(resourcePrimKey);
144 page.setGroupId(node.getGroupId());
145 page.setCompanyId(user.getCompanyId());
146 page.setUserId(user.getUserId());
147 page.setUserName(user.getFullName());
148 page.setCreateDate(now);
149 page.setModifiedDate(now);
150 page.setNodeId(nodeId);
151 page.setTitle(title);
152 page.setVersion(version);
153 page.setMinorEdit(minorEdit);
154 page.setContent(content);
155 page.setSummary(summary);
156 page.setFormat(format);
157 page.setHead(head);
158 page.setParentTitle(parentTitle);
159 page.setRedirectTitle(redirectTitle);
160
161 wikiPagePersistence.update(page, false);
162
163
165 addPageResources(page, true, true);
166
167
169 node.setLastPostDate(now);
170
171 wikiNodePersistence.update(node, false);
172
173
175 if (PropsValues.WIKI_PAGE_COMMENTS_ENABLED) {
176 mbMessageLocalService.addDiscussionMessage(
177 userId, page.getUserName(), WikiPage.class.getName(),
178 resourcePrimKey);
179 }
180
181
183 socialActivityLocalService.addActivity(
184 userId, page.getGroupId(), WikiPage.class.getName(),
185 page.getResourcePrimKey(), WikiActivityKeys.ADD_PAGE,
186 StringPool.BLANK, 0);
187
188
190 if (!minorEdit && NotificationThreadLocal.isEnabled()) {
191 notifySubscribers(node, page, prefs, themeDisplay, false);
192 }
193
194
196 updateTagsAsset(userId, page, tagsEntries);
197
198
200 reIndex(page);
201
202
204 clearPageCache(page);
205 clearReferralsCache(page);
206
207 return page;
208 }
209
210 public void addPageAttachments(
211 long nodeId, String title,
212 List<ObjectValuePair<String, byte[]>> files)
213 throws PortalException, SystemException {
214
215 if (files.size() == 0) {
216 return;
217 }
218
219 WikiPage page = getPage(nodeId, title);
220
221 long companyId = page.getCompanyId();
222 String portletId = CompanyConstants.SYSTEM_STRING;
223 long groupId = GroupConstants.DEFAULT_PARENT_GROUP_ID;
224 long repositoryId = CompanyConstants.SYSTEM;
225 String dirName = page.getAttachmentsDir();
226
227 try {
228 try {
229 dlService.addDirectory(companyId, repositoryId, dirName);
230 }
231 catch (DuplicateDirectoryException dde) {
232 }
233
234 for (int i = 0; i < files.size(); i++) {
235 ObjectValuePair<String, byte[]> ovp = files.get(i);
236
237 String fileName = ovp.getKey();
238 byte[] bytes = ovp.getValue();
239
240 if (Validator.isNull(fileName)) {
241 continue;
242 }
243
244 try {
245 dlService.addFile(
246 companyId, portletId, groupId, repositoryId,
247 dirName + "/" + fileName, StringPool.BLANK,
248 page.getModifiedDate(), new String[0], bytes);
249 }
250 catch (DuplicateFileException dfe) {
251 }
252 }
253 }
254 catch (RemoteException re) {
255 throw new SystemException(re);
256 }
257 }
258
259 public void addPageResources(
260 long nodeId, String title, boolean addCommunityPermissions,
261 boolean addGuestPermissions)
262 throws PortalException, SystemException {
263
264 WikiPage page = getPage(nodeId, title);
265
266 addPageResources(page, addCommunityPermissions, addGuestPermissions);
267 }
268
269 public void addPageResources(
270 WikiPage page, boolean addCommunityPermissions,
271 boolean addGuestPermissions)
272 throws PortalException, SystemException {
273
274 resourceLocalService.addResources(
275 page.getCompanyId(), page.getGroupId(), page.getUserId(),
276 WikiPage.class.getName(), page.getResourcePrimKey(), false,
277 addCommunityPermissions, addGuestPermissions);
278 }
279
280 public void addPageResources(
281 long nodeId, String title, String[] communityPermissions,
282 String[] guestPermissions)
283 throws PortalException, SystemException {
284
285 WikiPage page = getPage(nodeId, title);
286
287 addPageResources(page, communityPermissions, guestPermissions);
288 }
289
290 public void addPageResources(
291 WikiPage page, String[] communityPermissions,
292 String[] guestPermissions)
293 throws PortalException, SystemException {
294
295 resourceLocalService.addModelResources(
296 page.getCompanyId(), page.getGroupId(), page.getUserId(),
297 WikiPage.class.getName(), page.getResourcePrimKey(),
298 communityPermissions, guestPermissions);
299 }
300
301 public void changeParent(
302 long userId, long nodeId, String title, String newParentTitle,
303 PortletPreferences prefs, ThemeDisplay themeDisplay)
304 throws PortalException, SystemException {
305
306 if (Validator.isNotNull(newParentTitle)) {
307 WikiPage parentPage = getPage(nodeId, newParentTitle);
308
309 if (Validator.isNotNull(parentPage.getRedirectTitle())) {
310 newParentTitle = parentPage.getRedirectTitle();
311 }
312 }
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_H_P(
362 page.getNodeId(), true, 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_P(
467 nodeId, true, StringPool.BLANK).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().toLowerCase()) != 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 (title.equalsIgnoreCase(newTitle)) {
745 throw new DuplicatePageException(newTitle);
746 }
747
748 if (isUsedTitle(nodeId, newTitle)) {
749 WikiPage page = getPage(nodeId, newTitle);
750
751
753 if (((page.getVersion() == WikiPageImpl.DEFAULT_VERSION) &&
754 (page.getContent().length() < 200)) ||
755 !strict) {
756
757 deletePage(nodeId, newTitle);
758 }
759 else {
760 throw new DuplicatePageException(newTitle);
761 }
762 }
763
764
766 List<WikiPage> pageVersions = wikiPagePersistence.findByN_T(
767 nodeId, title);
768
769 if (pageVersions.size() == 0) {
770 return;
771 }
772
773 for (WikiPage page : pageVersions) {
774 page.setTitle(newTitle);
775
776 wikiPagePersistence.update(page, false);
777 }
778
779
781 List<WikiPage> children = wikiPagePersistence.findByN_P(nodeId, title);
782
783 for (WikiPage page : children) {
784 page.setParentTitle(newTitle);
785
786 wikiPagePersistence.update(page, false);
787 }
788
789 WikiPage page = pageVersions.get(pageVersions.size() - 1);
790
791
793 WikiPageResource wikiPageResource =
794 wikiPageResourcePersistence.findByPrimaryKey(
795 page.getResourcePrimKey());
796
797 wikiPageResource.setTitle(newTitle);
798
799 wikiPageResourcePersistence.update(wikiPageResource, false);
800
801
803 String uuid = null;
804 double version = WikiPageImpl.DEFAULT_VERSION;
805 String format = page.getFormat();
806 boolean head = true;
807 String parentTitle = page.getParentTitle();
808 String redirectTitle = page.getTitle();
809 String content =
810 StringPool.DOUBLE_OPEN_BRACKET + redirectTitle +
811 StringPool.DOUBLE_CLOSE_BRACKET;
812 String summary = WikiPageImpl.MOVED + " to " + title;
813
814 addPage(
815 uuid, userId, nodeId, title, version, content, summary, false,
816 format, head, parentTitle, redirectTitle, null, prefs,
817 themeDisplay);
818
819
821 List<WikiPage> redirectedPages = wikiPagePersistence.findByN_R(
822 nodeId, title);
823
824 for (WikiPage redirectedPage : redirectedPages) {
825 redirectedPage.setRedirectTitle(newTitle);
826
827 wikiPagePersistence.update(redirectedPage, false);
828 }
829
830
832 String[] tagsEntries = tagsEntryLocalService.getEntryNames(
833 WikiPage.class.getName(), page.getResourcePrimKey());
834
835 updateTagsAsset(userId, page, tagsEntries);
836
837
839 try {
840 Indexer.deletePage(page.getCompanyId(), page.getNodeId(), title);
841 }
842 catch (SearchException se) {
843 _log.error("Indexing " + title, se);
844 }
845
846 reIndex(page);
847 }
848
849 public void reIndex(long resourcePrimKey) throws SystemException {
850 if (SearchEngineUtil.isIndexReadOnly()) {
851 return;
852 }
853
854 WikiPage page = null;
855
856 try {
857 page = wikiPageFinder.findByResourcePrimKey(resourcePrimKey);
858 }
859 catch (NoSuchPageException nspe) {
860 return;
861 }
862
863 reIndex(page);
864 }
865
866 public void reIndex(WikiPage page) throws SystemException {
867 if (Validator.isNotNull(page.getRedirectTitle())) {
868 return;
869 }
870
871 long companyId = page.getCompanyId();
872 long groupId = page.getGroupId();
873 long resourcePrimKey = page.getResourcePrimKey();
874 long nodeId = page.getNodeId();
875 String title = page.getTitle();
876 String content = page.getContent();
877 Date modifiedDate = page.getModifiedDate();
878
879 String[] tagsEntries = tagsEntryLocalService.getEntryNames(
880 WikiPage.class.getName(), resourcePrimKey);
881
882 try {
883 Indexer.updatePage(
884 companyId, groupId, nodeId, title, content, modifiedDate,
885 tagsEntries);
886 }
887 catch (SearchException se) {
888 _log.error("Reindexing " + page.getPrimaryKey(), se);
889 }
890 }
891
892 public WikiPage revertPage(
893 long userId, long nodeId, String title, double version,
894 PortletPreferences prefs, ThemeDisplay themeDisplay)
895 throws PortalException, SystemException {
896
897 WikiPage oldPage = getPage(nodeId, title, version);
898
899 return updatePage(
900 userId, nodeId, title, 0, oldPage.getContent(),
901 WikiPageImpl.REVERTED + " to " + version, false,
902 oldPage.getFormat(), null, getParentPageTitle(oldPage), null, prefs,
903 themeDisplay);
904 }
905
906 public void subscribePage(long userId, long nodeId, String title)
907 throws PortalException, SystemException {
908
909 WikiPage page = getPage(nodeId, title);
910
911 subscriptionLocalService.addSubscription(
912 userId, WikiPage.class.getName(), page.getResourcePrimKey());
913 }
914
915 public void unsubscribePage(long userId, long nodeId, String title)
916 throws PortalException, SystemException {
917
918 WikiPage page = getPage(nodeId, title);
919
920 subscriptionLocalService.deleteSubscription(
921 userId, WikiPage.class.getName(), page.getResourcePrimKey());
922 }
923
924 public WikiPage updatePage(
925 long userId, long nodeId, String title, double version,
926 String content, String summary, boolean minorEdit, String format,
927 String parentTitle, String redirectTitle, String[] tagsEntries,
928 PortletPreferences prefs, ThemeDisplay themeDisplay)
929 throws PortalException, SystemException {
930
931
933 User user = userPersistence.findByPrimaryKey(userId);
934 Date now = new Date();
935
936 validate(nodeId, content, format);
937
938 WikiPage page = null;
939
940 try {
941 page = getPage(nodeId, title);
942 }
943 catch (NoSuchPageException nspe) {
944 return addPage(
945 null, userId, nodeId, title, WikiPageImpl.DEFAULT_VERSION,
946 content, summary, minorEdit, format, true, parentTitle,
947 redirectTitle, tagsEntries, prefs, themeDisplay);
948 }
949
950 double oldVersion = page.getVersion();
951
952 if ((version > 0) && (version != oldVersion)) {
953 throw new PageVersionException();
954 }
955
956 long resourcePrimKey = page.getResourcePrimKey();
957 long groupId = page.getGroupId();
958
959 page.setHead(false);
960 page.setModifiedDate(now);
961
962 wikiPagePersistence.update(page, false);
963
964 double newVersion = MathUtil.format(oldVersion + 0.1, 1, 1);
965
966 long pageId = counterLocalService.increment();
967
968 page = wikiPagePersistence.create(pageId);
969
970 page.setResourcePrimKey(resourcePrimKey);
971 page.setGroupId(groupId);
972 page.setCompanyId(user.getCompanyId());
973 page.setUserId(user.getUserId());
974 page.setUserName(user.getFullName());
975 page.setCreateDate(now);
976 page.setModifiedDate(now);
977 page.setNodeId(nodeId);
978 page.setTitle(title);
979 page.setVersion(newVersion);
980 page.setMinorEdit(minorEdit);
981 page.setContent(content);
982 page.setSummary(summary);
983 page.setFormat(format);
984 page.setHead(true);
985
986 if (Validator.isNotNull(parentTitle)) {
987 page.setParentTitle(parentTitle);
988 }
989
990 if (Validator.isNotNull(redirectTitle)) {
991 page.setRedirectTitle(redirectTitle);
992 }
993
994 wikiPagePersistence.update(page, false);
995
996
998 WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
999
1000 node.setLastPostDate(now);
1001
1002 wikiNodePersistence.update(node, false);
1003
1004
1006 socialActivityLocalService.addActivity(
1007 userId, page.getGroupId(), WikiPage.class.getName(),
1008 page.getResourcePrimKey(), WikiActivityKeys.UPDATE_PAGE,
1009 StringPool.BLANK, 0);
1010
1011
1013 if (!minorEdit && NotificationThreadLocal.isEnabled()) {
1014 notifySubscribers(node, page, prefs, themeDisplay, true);
1015 }
1016
1017
1019 updateTagsAsset(userId, page, tagsEntries);
1020
1021
1023 reIndex(page);
1024
1025
1027 clearPageCache(page);
1028
1029 return page;
1030 }
1031
1032 public void updateTagsAsset(
1033 long userId, WikiPage page, String[] tagsEntries)
1034 throws PortalException, SystemException {
1035
1036 tagsAssetLocalService.updateAsset(
1037 userId, page.getGroupId(), WikiPage.class.getName(),
1038 page.getResourcePrimKey(), tagsEntries, null, null, null, null,
1039 ContentTypes.TEXT_HTML, page.getTitle(), null, null, null, 0, 0,
1040 null, false);
1041 }
1042
1043 public void validateTitle(String title) throws PortalException {
1044 if (title.equals("all_pages") || title.equals("orphan_pages") ||
1045 title.equals("recent_changes")) {
1046
1047 throw new PageTitleException(title + " is reserved");
1048 }
1049
1050 if (Validator.isNotNull(PropsValues.WIKI_PAGE_TITLES_REGEXP)) {
1051 Pattern pattern = Pattern.compile(
1052 PropsValues.WIKI_PAGE_TITLES_REGEXP);
1053
1054 Matcher matcher = pattern.matcher(title);
1055
1056 if (!matcher.matches()) {
1057 throw new PageTitleException();
1058 }
1059 }
1060 }
1061
1062 protected void clearPageCache(WikiPage page) {
1063 if (!WikiCacheThreadLocal.isClearCache()) {
1064 return;
1065 }
1066
1067 WikiCacheUtil.clearCache(page.getNodeId(), page.getTitle());
1068 }
1069
1070 protected void clearReferralsCache(WikiPage page)
1071 throws PortalException, SystemException {
1072
1073 if (!WikiCacheThreadLocal.isClearCache()) {
1074 return;
1075 }
1076
1077 List<WikiPage> links = getIncomingLinks(
1078 page.getNodeId(), page.getTitle());
1079
1080 for (WikiPage curPage : links) {
1081 WikiCacheUtil.clearCache(curPage.getNodeId(), curPage.getTitle());
1082 }
1083 }
1084
1085 protected String getParentPageTitle(WikiPage page) {
1086 try {
1087 WikiPage parentPage = getPage(
1088 page.getNodeId(), page.getParentTitle());
1089
1090 return parentPage.getTitle();
1091 }
1092 catch (Exception e) {
1093 return null;
1094 }
1095 }
1096
1097 protected boolean isLinkedTo(WikiPage page, String targetTitle)
1098 throws PortalException {
1099
1100 Map<String, Boolean> links = WikiCacheUtil.getOutgoingLinks(page);
1101
1102 Boolean link = links.get(targetTitle.toLowerCase());
1103
1104 if (link != null) {
1105 return true;
1106 }
1107 else {
1108 return false;
1109 }
1110 }
1111
1112 protected boolean isUsedTitle(long nodeId, String title)
1113 throws SystemException {
1114
1115 if (getPagesCount(nodeId, title, true) > 0) {
1116 return true;
1117 }
1118 else {
1119 return false;
1120 }
1121 }
1122
1123 protected void notifySubscribers(
1124 WikiNode node, WikiPage page, PortletPreferences prefs,
1125 ThemeDisplay themeDisplay, boolean update)
1126 throws PortalException, SystemException {
1127
1128 if (prefs == null) {
1129 long ownerId = node.getGroupId();
1130 int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
1131 long plid = PortletKeys.PREFS_PLID_SHARED;
1132 String portletId = PortletKeys.WIKI;
1133 String defaultPreferences = null;
1134
1135 prefs = portletPreferencesLocalService.getPreferences(
1136 node.getCompanyId(), ownerId, ownerType, plid, portletId,
1137 defaultPreferences);
1138 }
1139
1140 if (!update && WikiUtil.getEmailPageAddedEnabled(prefs)) {
1141 }
1142 else if (update && WikiUtil.getEmailPageUpdatedEnabled(prefs)) {
1143 }
1144 else {
1145 return;
1146 }
1147
1148 Company company = companyPersistence.findByPrimaryKey(
1149 page.getCompanyId());
1150
1151 Group group = groupPersistence.findByPrimaryKey(node.getGroupId());
1152
1153 User user = userPersistence.findByPrimaryKey(page.getUserId());
1154
1155 String pageURL = StringPool.BLANK;
1156
1157 if (themeDisplay != null) {
1158 String layoutFullURL = PortalUtil.getLayoutFullURL(themeDisplay);
1159
1160 pageURL =
1161 layoutFullURL + Portal.FRIENDLY_URL_SEPARATOR + "wiki/" +
1162 node.getNodeId() + StringPool.SLASH +
1163 HttpUtil.encodeURL(page.getTitle());
1164 }
1165
1166 String portletName = PortalUtil.getPortletTitle(
1167 PortletKeys.WIKI, user);
1168
1169 String fromName = WikiUtil.getEmailFromName(prefs);
1170 String fromAddress = WikiUtil.getEmailFromAddress(prefs);
1171
1172 String replyToAddress = fromAddress;
1173 String mailId = WikiUtil.getMailId(
1174 company.getMx(), page.getNodeId(), page.getPageId());
1175
1176 fromName = StringUtil.replace(
1177 fromName,
1178 new String[] {
1179 "[$COMPANY_ID$]",
1180 "[$COMPANY_MX$]",
1181 "[$COMPANY_NAME$]",
1182 "[$COMMUNITY_NAME$]",
1183 "[$PAGE_USER_ADDRESS$]",
1184 "[$PAGE_USER_NAME$]",
1185 "[$PORTLET_NAME$]"
1186 },
1187 new String[] {
1188 String.valueOf(company.getCompanyId()),
1189 company.getMx(),
1190 company.getName(),
1191 group.getName(),
1192 user.getEmailAddress(),
1193 user.getFullName(),
1194 portletName
1195 });
1196
1197 fromAddress = StringUtil.replace(
1198 fromAddress,
1199 new String[] {
1200 "[$COMPANY_ID$]",
1201 "[$COMPANY_MX$]",
1202 "[$COMPANY_NAME$]",
1203 "[$COMMUNITY_NAME$]",
1204 "[$PAGE_USER_ADDRESS$]",
1205 "[$PAGE_USER_NAME$]",
1206 "[$PORTLET_NAME$]"
1207 },
1208 new String[] {
1209 String.valueOf(company.getCompanyId()),
1210 company.getMx(),
1211 company.getName(),
1212 group.getName(),
1213 user.getEmailAddress(),
1214 user.getFullName(),
1215 portletName
1216 });
1217
1218 String subjectPrefix = null;
1219 String body = null;
1220 String signature = null;
1221
1222 if (update) {
1223 subjectPrefix = WikiUtil.getEmailPageUpdatedSubjectPrefix(prefs);
1224 body = WikiUtil.getEmailPageUpdatedBody(prefs);
1225 signature = WikiUtil.getEmailPageUpdatedSignature(prefs);
1226 }
1227 else {
1228 subjectPrefix = WikiUtil.getEmailPageAddedSubjectPrefix(prefs);
1229 body = WikiUtil.getEmailPageAddedBody(prefs);
1230 signature = WikiUtil.getEmailPageAddedSignature(prefs);
1231 }
1232
1233 if (Validator.isNotNull(signature)) {
1234 body += "\n--\n" + signature;
1235 }
1236
1237 subjectPrefix = StringUtil.replace(
1238 subjectPrefix,
1239 new String[] {
1240 "[$COMPANY_ID$]",
1241 "[$COMPANY_MX$]",
1242 "[$COMPANY_NAME$]",
1243 "[$COMMUNITY_NAME$]",
1244 "[$FROM_ADDRESS$]",
1245 "[$FROM_NAME$]",
1246 "[$NODE_NAME$]",
1247 "[$PAGE_CONTENT$]",
1248 "[$PAGE_ID$]",
1249 "[$PAGE_TITLE$]",
1250 "[$PAGE_USER_ADDRESS$]",
1251 "[$PAGE_USER_NAME$]",
1252 "[$PORTAL_URL$]",
1253 "[$PORTLET_NAME$]"
1254 },
1255 new String[] {
1256 String.valueOf(company.getCompanyId()),
1257 company.getMx(),
1258 company.getName(),
1259 group.getName(),
1260 fromAddress,
1261 fromName,
1262 node.getName(),
1263 page.getContent(),
1264 String.valueOf(page.getPageId()),
1265 page.getTitle(),
1266 user.getEmailAddress(),
1267 user.getFullName(),
1268 company.getVirtualHost(),
1269 portletName
1270 });
1271
1272 body = StringUtil.replace(
1273 body,
1274 new String[] {
1275 "[$COMPANY_ID$]",
1276 "[$COMPANY_MX$]",
1277 "[$COMPANY_NAME$]",
1278 "[$COMMUNITY_NAME$]",
1279 "[$FROM_ADDRESS$]",
1280 "[$FROM_NAME$]",
1281 "[$NODE_NAME$]",
1282 "[$PAGE_CONTENT$]",
1283 "[$PAGE_ID$]",
1284 "[$PAGE_TITLE$]",
1285 "[$PAGE_URL$]",
1286 "[$PAGE_USER_ADDRESS$]",
1287 "[$PAGE_USER_NAME$]",
1288 "[$PORTAL_URL$]",
1289 "[$PORTLET_NAME$]"
1290 },
1291 new String[] {
1292 String.valueOf(company.getCompanyId()),
1293 company.getMx(),
1294 company.getName(),
1295 group.getName(),
1296 fromAddress,
1297 fromName,
1298 node.getName(),
1299 page.getContent(),
1300 String.valueOf(page.getPageId()),
1301 page.getTitle(),
1302 pageURL,
1303 user.getEmailAddress(),
1304 user.getFullName(),
1305 company.getVirtualHost(),
1306 portletName
1307 });
1308
1309 String subject = page.getTitle();
1310
1311 if (subject.indexOf(subjectPrefix) == -1) {
1312 subject = subjectPrefix + subject;
1313 }
1314
1315 Message message = new Message();
1316
1317 message.put("companyId", node.getCompanyId());
1318 message.put("userId", node.getUserId());
1319 message.put("nodeId", node.getNodeId());
1320 message.put("pageResourcePrimKey", page.getResourcePrimKey());
1321 message.put("fromName", fromName);
1322 message.put("fromAddress", fromAddress);
1323 message.put("subject", subject);
1324 message.put("body", body);
1325 message.put("replyToAddress", replyToAddress);
1326 message.put("mailId", mailId);
1327
1328 MessageBusUtil.sendMessage(DestinationNames.WIKI, message);
1329 }
1330
1331 protected void validate(long nodeId, String content, String format)
1332 throws PortalException {
1333
1334 if (!WikiUtil.validate(nodeId, content, format)) {
1335 throw new PageContentException();
1336 }
1337 }
1338
1339 protected void validate(
1340 String title, long nodeId, String content, String format)
1341 throws PortalException, SystemException {
1342
1343 if (Validator.isNull(title)) {
1344 throw new PageTitleException();
1345 }
1346
1347 if (isUsedTitle(nodeId, title)) {
1348 throw new DuplicatePageException();
1349 }
1350
1351 validateTitle(title);
1352
1353 validate(nodeId, content, format);
1354 }
1355
1356 private static Log _log = LogFactoryUtil.getLog(
1357 WikiPageLocalServiceImpl.class);
1358
1359}