001
014
015 package com.liferay.portlet.wiki.service.impl;
016
017 import com.liferay.portal.kernel.exception.PortalException;
018 import com.liferay.portal.kernel.exception.SystemException;
019 import com.liferay.portal.kernel.sanitizer.SanitizerUtil;
020 import com.liferay.portal.kernel.search.Indexer;
021 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
022 import com.liferay.portal.kernel.util.CalendarFactoryUtil;
023 import com.liferay.portal.kernel.util.ContentTypes;
024 import com.liferay.portal.kernel.util.HttpUtil;
025 import com.liferay.portal.kernel.util.ListUtil;
026 import com.liferay.portal.kernel.util.MathUtil;
027 import com.liferay.portal.kernel.util.NotificationThreadLocal;
028 import com.liferay.portal.kernel.util.ObjectValuePair;
029 import com.liferay.portal.kernel.util.OrderByComparator;
030 import com.liferay.portal.kernel.util.StringBundler;
031 import com.liferay.portal.kernel.util.StringPool;
032 import com.liferay.portal.kernel.util.StringUtil;
033 import com.liferay.portal.kernel.util.TempFileUtil;
034 import com.liferay.portal.kernel.util.UniqueList;
035 import com.liferay.portal.kernel.util.Validator;
036 import com.liferay.portal.kernel.workflow.WorkflowConstants;
037 import com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil;
038 import com.liferay.portal.model.CompanyConstants;
039 import com.liferay.portal.model.ResourceConstants;
040 import com.liferay.portal.model.User;
041 import com.liferay.portal.service.ServiceContext;
042 import com.liferay.portal.service.ServiceContextUtil;
043 import com.liferay.portal.util.Portal;
044 import com.liferay.portal.util.PortletKeys;
045 import com.liferay.portal.util.PropsValues;
046 import com.liferay.portal.util.SubscriptionSender;
047 import com.liferay.portlet.asset.NoSuchEntryException;
048 import com.liferay.portlet.asset.model.AssetEntry;
049 import com.liferay.portlet.asset.model.AssetLink;
050 import com.liferay.portlet.asset.model.AssetLinkConstants;
051 import com.liferay.portlet.documentlibrary.DuplicateDirectoryException;
052 import com.liferay.portlet.documentlibrary.NoSuchDirectoryException;
053 import com.liferay.portlet.documentlibrary.NoSuchFileException;
054 import com.liferay.portlet.documentlibrary.store.DLStoreUtil;
055 import com.liferay.portlet.expando.model.ExpandoBridge;
056 import com.liferay.portlet.social.model.SocialActivityConstants;
057 import com.liferay.portlet.wiki.DuplicatePageException;
058 import com.liferay.portlet.wiki.NoSuchPageException;
059 import com.liferay.portlet.wiki.NoSuchPageResourceException;
060 import com.liferay.portlet.wiki.PageContentException;
061 import com.liferay.portlet.wiki.PageTitleException;
062 import com.liferay.portlet.wiki.PageVersionException;
063 import com.liferay.portlet.wiki.model.WikiNode;
064 import com.liferay.portlet.wiki.model.WikiPage;
065 import com.liferay.portlet.wiki.model.WikiPageConstants;
066 import com.liferay.portlet.wiki.model.WikiPageDisplay;
067 import com.liferay.portlet.wiki.model.WikiPageResource;
068 import com.liferay.portlet.wiki.model.impl.WikiPageDisplayImpl;
069 import com.liferay.portlet.wiki.model.impl.WikiPageImpl;
070 import com.liferay.portlet.wiki.service.base.WikiPageLocalServiceBaseImpl;
071 import com.liferay.portlet.wiki.social.WikiActivityKeys;
072 import com.liferay.portlet.wiki.util.WikiCacheThreadLocal;
073 import com.liferay.portlet.wiki.util.WikiCacheUtil;
074 import com.liferay.portlet.wiki.util.WikiUtil;
075 import com.liferay.portlet.wiki.util.comparator.PageCreateDateComparator;
076 import com.liferay.portlet.wiki.util.comparator.PageVersionComparator;
077
078 import java.io.File;
079 import java.io.InputStream;
080
081 import java.util.ArrayList;
082 import java.util.Calendar;
083 import java.util.Date;
084 import java.util.HashSet;
085 import java.util.LinkedHashMap;
086 import java.util.List;
087 import java.util.Map;
088 import java.util.Set;
089 import java.util.regex.Matcher;
090 import java.util.regex.Pattern;
091
092 import javax.portlet.PortletPreferences;
093 import javax.portlet.PortletURL;
094 import javax.portlet.WindowState;
095
096
107 public class WikiPageLocalServiceImpl extends WikiPageLocalServiceBaseImpl {
108
109 public WikiPage addPage(
110 long userId, long nodeId, String title, double version,
111 String content, String summary, boolean minorEdit, String format,
112 boolean head, String parentTitle, String redirectTitle,
113 ServiceContext serviceContext)
114 throws PortalException, SystemException {
115
116
117
118 User user = userPersistence.findByPrimaryKey(userId);
119 WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
120 Date now = new Date();
121
122 long pageId = counterLocalService.increment();
123
124 content = SanitizerUtil.sanitize(
125 user.getCompanyId(), node.getGroupId(), userId,
126 WikiPage.class.getName(), pageId, "text/" + format, content);
127
128 validate(title, nodeId, content, format);
129
130 long resourcePrimKey =
131 wikiPageResourceLocalService.getPageResourcePrimKey(nodeId, title);
132
133 WikiPage page = wikiPagePersistence.create(pageId);
134
135 page.setUuid(serviceContext.getUuid());
136 page.setResourcePrimKey(resourcePrimKey);
137 page.setGroupId(node.getGroupId());
138 page.setCompanyId(user.getCompanyId());
139 page.setUserId(user.getUserId());
140 page.setUserName(user.getFullName());
141 page.setCreateDate(serviceContext.getCreateDate(now));
142 page.setModifiedDate(serviceContext.getModifiedDate(now));
143 page.setNodeId(nodeId);
144 page.setTitle(title);
145 page.setVersion(version);
146 page.setMinorEdit(minorEdit);
147 page.setContent(content);
148 page.setStatus(WorkflowConstants.STATUS_DRAFT);
149 page.setSummary(summary);
150 page.setFormat(format);
151 page.setHead(head);
152 page.setParentTitle(parentTitle);
153 page.setRedirectTitle(redirectTitle);
154
155 wikiPagePersistence.update(page, false);
156
157
158
159 if (serviceContext.isAddGroupPermissions() ||
160 serviceContext.isAddGuestPermissions()) {
161
162 addPageResources(
163 page, serviceContext.isAddGroupPermissions(),
164 serviceContext.isAddGuestPermissions());
165 }
166 else {
167 addPageResources(
168 page, serviceContext.getGroupPermissions(),
169 serviceContext.getGuestPermissions());
170 }
171
172
173
174 node.setLastPostDate(serviceContext.getModifiedDate(now));
175
176 wikiNodePersistence.update(node, false);
177
178
179
180 updateAsset(
181 userId, page, serviceContext.getAssetCategoryIds(),
182 serviceContext.getAssetTagNames(),
183 serviceContext.getAssetLinkEntryIds());
184
185
186
187 ExpandoBridge expandoBridge = page.getExpandoBridge();
188
189 expandoBridge.setAttributes(serviceContext);
190
191
192
193 if (PropsValues.WIKI_PAGE_COMMENTS_ENABLED) {
194 mbMessageLocalService.addDiscussionMessage(
195 userId, page.getUserName(), page.getGroupId(),
196 WikiPage.class.getName(), resourcePrimKey,
197 WorkflowConstants.ACTION_PUBLISH);
198 }
199
200
201
202 WorkflowHandlerRegistryUtil.startWorkflowInstance(
203 user.getCompanyId(), page.getGroupId(), userId,
204 WikiPage.class.getName(), page.getPageId(), page, serviceContext);
205
206 return page;
207 }
208
209 public WikiPage addPage(
210 long userId, long nodeId, String title, String content,
211 String summary, boolean minorEdit, ServiceContext serviceContext)
212 throws PortalException, SystemException {
213
214 double version = WikiPageConstants.VERSION_DEFAULT;
215 String format = WikiPageConstants.DEFAULT_FORMAT;
216 boolean head = false;
217 String parentTitle = null;
218 String redirectTitle = null;
219
220 return addPage(
221 userId, nodeId, title, version, content, summary, minorEdit, format,
222 head, parentTitle, redirectTitle, serviceContext);
223 }
224
225 public void addPageAttachment(
226 long userId, long nodeId, String title, String fileName, File file)
227 throws PortalException, SystemException {
228
229 if (Validator.isNull(fileName)) {
230 return;
231 }
232
233 WikiPage page = getPage(nodeId, title);
234
235 if (userId == 0) {
236 userId = page.getUserId();
237 }
238
239 socialActivityLocalService.addActivity(
240 userId, page.getGroupId(), WikiPage.class.getName(),
241 page.getResourcePrimKey(),
242 SocialActivityConstants.TYPE_ADD_ATTACHMENT,
243 page.getAttachmentsDir() + "/" + fileName, 0);
244
245 try {
246 DLStoreUtil.addDirectory(
247 page.getCompanyId(), CompanyConstants.SYSTEM,
248 page.getAttachmentsDir());
249 }
250 catch (DuplicateDirectoryException dde) {
251 }
252
253 DLStoreUtil.addFile(
254 page.getCompanyId(), CompanyConstants.SYSTEM,
255 page.getAttachmentsDir() + "/" + fileName, file);
256 }
257
258 public void addPageAttachment(
259 long userId, long nodeId, String title, String fileName,
260 InputStream inputStream)
261 throws PortalException, SystemException {
262
263 if (Validator.isNull(fileName)) {
264 return;
265 }
266
267 WikiPage page = getPage(nodeId, title);
268
269 if (userId == 0) {
270 userId = page.getUserId();
271 }
272
273 socialActivityLocalService.addActivity(
274 userId, page.getGroupId(), WikiPage.class.getName(),
275 page.getResourcePrimKey(),
276 SocialActivityConstants.TYPE_ADD_ATTACHMENT,
277 page.getAttachmentsDir() + "/" + fileName, 0);
278
279 try {
280 DLStoreUtil.addDirectory(
281 page.getCompanyId(), CompanyConstants.SYSTEM,
282 page.getAttachmentsDir());
283 }
284 catch (DuplicateDirectoryException dde) {
285 }
286
287 DLStoreUtil.addFile(
288 page.getCompanyId(), CompanyConstants.SYSTEM,
289 page.getAttachmentsDir() + "/" + fileName, inputStream);
290 }
291
292 public void addPageAttachment(
293 long companyId, String dirName, Date modifiedDate, String fileName,
294 InputStream inputStream)
295 throws PortalException, SystemException {
296
297 if (inputStream == null) {
298 return;
299 }
300
301 long repositoryId = CompanyConstants.SYSTEM;
302
303 try {
304 DLStoreUtil.addDirectory(companyId, repositoryId, dirName);
305 }
306 catch (DuplicateDirectoryException dde) {
307 }
308
309 DLStoreUtil.addFile(
310 companyId, repositoryId, dirName + "/" + fileName, false,
311 inputStream);
312 }
313
314 public void addPageAttachments(
315 long userId, long nodeId, String title,
316 List<ObjectValuePair<String, InputStream>> inputStreams)
317 throws PortalException, SystemException {
318
319 if (inputStreams.size() == 0) {
320 return;
321 }
322
323 for (int i = 0; i < inputStreams.size(); i++) {
324 ObjectValuePair<String, InputStream> ovp = inputStreams.get(i);
325
326 String fileName = ovp.getKey();
327 InputStream inputStream = ovp.getValue();
328
329 addPageAttachment(userId, nodeId, title, fileName, inputStream);
330 }
331 }
332
333 public void addPageResources(
334 long nodeId, String title, boolean addGroupPermissions,
335 boolean addGuestPermissions)
336 throws PortalException, SystemException {
337
338 WikiPage page = getPage(nodeId, title);
339
340 addPageResources(page, addGroupPermissions, addGuestPermissions);
341 }
342
343 public void addPageResources(
344 long nodeId, String title, String[] groupPermissions,
345 String[] guestPermissions)
346 throws PortalException, SystemException {
347
348 WikiPage page = getPage(nodeId, title);
349
350 addPageResources(page, groupPermissions, guestPermissions);
351 }
352
353 public void addPageResources(
354 WikiPage page, boolean addGroupPermissions,
355 boolean addGuestPermissions)
356 throws PortalException, SystemException {
357
358 resourceLocalService.addResources(
359 page.getCompanyId(), page.getGroupId(), page.getUserId(),
360 WikiPage.class.getName(), page.getResourcePrimKey(), false,
361 addGroupPermissions, addGuestPermissions);
362 }
363
364 public void addPageResources(
365 WikiPage page, String[] groupPermissions, String[] guestPermissions)
366 throws PortalException, SystemException {
367
368 resourceLocalService.addModelResources(
369 page.getCompanyId(), page.getGroupId(), page.getUserId(),
370 WikiPage.class.getName(), page.getResourcePrimKey(),
371 groupPermissions, guestPermissions);
372 }
373
374 public String addTempPageAttachment(
375 long userId, String fileName, String tempFolderName,
376 InputStream inputStream)
377 throws PortalException, SystemException {
378
379 return TempFileUtil.addTempFile(
380 userId, fileName, tempFolderName, inputStream);
381 }
382
383 public void changeParent(
384 long userId, long nodeId, String title, String newParentTitle,
385 ServiceContext serviceContext)
386 throws PortalException, SystemException {
387
388 if (Validator.isNotNull(newParentTitle)) {
389 WikiPage parentPage = getPage(nodeId, newParentTitle);
390
391 if (Validator.isNotNull(parentPage.getRedirectTitle())) {
392 newParentTitle = parentPage.getRedirectTitle();
393 }
394 }
395
396 WikiPage page = getPage(nodeId, title);
397
398 String originalParentTitle = page.getParentTitle();
399
400 double version = page.getVersion();
401 String content = page.getContent();
402 String summary = serviceContext.translate(
403 "changed-parent-from-x", originalParentTitle);
404 boolean minorEdit = false;
405 String format = page.getFormat();
406 String redirectTitle = page.getRedirectTitle();
407
408 long[] assetCategoryIds = assetCategoryLocalService.getCategoryIds(
409 WikiPage.class.getName(), page.getResourcePrimKey());
410 String[] assetTagNames = assetTagLocalService.getTagNames(
411 WikiPage.class.getName(), page.getResourcePrimKey());
412
413 serviceContext.setAssetCategoryIds(assetCategoryIds);
414 serviceContext.setAssetLinkEntryIds(null);
415 serviceContext.setAssetTagNames(assetTagNames);
416
417 updatePage(
418 userId, nodeId, title, version, content, summary, minorEdit, format,
419 newParentTitle, redirectTitle, serviceContext);
420
421 List<WikiPage> oldPages = wikiPagePersistence.findByN_T_H(
422 nodeId, title, false);
423
424 for (WikiPage oldPage : oldPages) {
425 oldPage.setParentTitle(originalParentTitle);
426
427 wikiPagePersistence.update(oldPage, false);
428 }
429 }
430
431 public void deletePage(long nodeId, String title)
432 throws PortalException, SystemException {
433
434 List<WikiPage> pages = wikiPagePersistence.findByN_T_H(
435 nodeId, title, true, 0, 1);
436
437 if (!pages.isEmpty()) {
438 WikiPage page = pages.iterator().next();
439
440 deletePage(page);
441 }
442 }
443
444 public void deletePage(long nodeId, String title, double version)
445 throws PortalException, SystemException {
446
447 wikiPagePersistence.removeByN_T_V(nodeId, title, version);
448 }
449
450 public void deletePage(WikiPage page)
451 throws PortalException, SystemException {
452
453
454
455 List<WikiPage> children = wikiPagePersistence.findByN_H_P(
456 page.getNodeId(), true, page.getTitle());
457
458 for (WikiPage curPage : children) {
459 deletePage(curPage);
460 }
461
462
463
464 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
465 WikiPage.class);
466
467 indexer.delete(page);
468
469
470
471 long companyId = page.getCompanyId();
472 long repositoryId = CompanyConstants.SYSTEM;
473 String dirName = page.getAttachmentsDir();
474
475 try {
476 DLStoreUtil.deleteDirectory(companyId, repositoryId, dirName);
477 }
478 catch (NoSuchDirectoryException nsde) {
479 }
480
481
482
483 subscriptionLocalService.deleteSubscriptions(
484 page.getCompanyId(), WikiPage.class.getName(),
485 page.getResourcePrimKey());
486
487
488
489 mbMessageLocalService.deleteDiscussionMessages(
490 WikiPage.class.getName(), page.getResourcePrimKey());
491
492
493
494 expandoValueLocalService.deleteValues(
495 WikiPage.class.getName(), page.getResourcePrimKey());
496
497
498
499 List<WikiPage> pageVersions = wikiPagePersistence.findByN_T(
500 page.getNodeId(), page.getTitle());
501
502 for (WikiPage pageVersion : pageVersions) {
503 assetEntryLocalService.deleteEntry(
504 WikiPage.class.getName(), pageVersion.getPrimaryKey());
505 }
506
507 assetEntryLocalService.deleteEntry(
508 WikiPage.class.getName(), page.getResourcePrimKey());
509
510
511
512 resourceLocalService.deleteResource(
513 page.getCompanyId(), WikiPage.class.getName(),
514 ResourceConstants.SCOPE_INDIVIDUAL, page.getResourcePrimKey());
515
516
517
518 try {
519 wikiPageResourceLocalService.deletePageResource(
520 page.getNodeId(), page.getTitle());
521 }
522 catch (NoSuchPageResourceException nspre) {
523 }
524
525
526
527 List<WikiPage> pages = wikiPagePersistence.findByN_T(
528 page.getNodeId(), page.getTitle());
529
530 for (WikiPage curPage : pages) {
531
532
533
534 workflowInstanceLinkLocalService.deleteWorkflowInstanceLinks(
535 curPage.getCompanyId(), curPage.getGroupId(),
536 WikiPage.class.getName(), curPage.getPageId());
537 }
538
539 wikiPagePersistence.removeByN_T(page.getNodeId(), page.getTitle());
540
541
542
543 wikiPagePersistence.removeByN_R(page.getNodeId(), page.getTitle());
544
545
546
547 clearPageCache(page);
548 }
549
550 public void deletePageAttachment(long nodeId, String title, String fileName)
551 throws PortalException, SystemException {
552
553 if (Validator.isNull(fileName)) {
554 return;
555 }
556
557 WikiPage page = getPage(nodeId, title);
558
559 long companyId = page.getCompanyId();
560 long repositoryId = CompanyConstants.SYSTEM;
561
562 try {
563 DLStoreUtil.deleteFile(companyId, repositoryId, fileName);
564 }
565 catch (NoSuchFileException nsfe) {
566 }
567 }
568
569 public void deletePages(long nodeId)
570 throws PortalException, SystemException {
571
572 List<WikiPage> pages = wikiPagePersistence.findByN_H_P(
573 nodeId, true, StringPool.BLANK);
574
575 for (WikiPage page : pages) {
576 deletePage(page);
577 }
578
579 pages = wikiPagePersistence.findByN_H_P(
580 nodeId, false, StringPool.BLANK);
581
582 for (WikiPage page : pages) {
583 deletePage(page);
584 }
585 }
586
587 public void deleteTempPageAttachment(
588 long userId, String fileName, String tempFolderName)
589 throws PortalException, SystemException {
590
591 TempFileUtil.deleteTempFile(userId, fileName, tempFolderName);
592 }
593
594 public List<WikiPage> getChildren(
595 long nodeId, boolean head, String parentTitle)
596 throws SystemException {
597
598 return wikiPagePersistence.findByN_H_P_S(
599 nodeId, head, parentTitle, WorkflowConstants.STATUS_APPROVED);
600 }
601
602 public WikiPage getDraftPage(long nodeId, String title)
603 throws PortalException, SystemException {
604
605 List<WikiPage> pages = wikiPagePersistence.findByN_T_S(
606 nodeId, title, WorkflowConstants.STATUS_DRAFT, 0, 1);
607
608 if (!pages.isEmpty()) {
609 return pages.get(0);
610 }
611 else {
612 pages = wikiPagePersistence.findByN_T_S(
613 nodeId, title, WorkflowConstants.STATUS_PENDING, 0, 1);
614
615 if (!pages.isEmpty()) {
616 return pages.get(0);
617 }
618 else {
619 throw new NoSuchPageException();
620 }
621 }
622
623 }
624
625 public List<WikiPage> getIncomingLinks(long nodeId, String title)
626 throws PortalException, SystemException {
627
628 List<WikiPage> links = new UniqueList<WikiPage>();
629
630 List<WikiPage> pages = wikiPagePersistence.findByN_H(nodeId, true);
631
632 for (WikiPage page : pages) {
633 if (isLinkedTo(page, title)) {
634 links.add(page);
635 }
636 }
637
638 List<WikiPage> referrals = wikiPagePersistence.findByN_R(nodeId, title);
639
640 for (WikiPage referral : referrals) {
641 for (WikiPage page : pages) {
642 if (isLinkedTo(page, referral.getTitle())) {
643 links.add(page);
644 }
645 }
646 }
647
648 return ListUtil.sort(links);
649 }
650
651 public List<WikiPage> getNoAssetPages() throws SystemException {
652 return wikiPageFinder.findByNoAssets();
653 }
654
655 public List<WikiPage> getOrphans(long nodeId)
656 throws PortalException, SystemException {
657
658 List<Map<String, Boolean>> pageTitles =
659 new ArrayList<Map<String, Boolean>>();
660
661 List<WikiPage> pages = wikiPagePersistence.findByN_H_S(
662 nodeId, true, WorkflowConstants.STATUS_APPROVED);
663
664 for (WikiPage page : pages) {
665 pageTitles.add(WikiCacheUtil.getOutgoingLinks(page));
666 }
667
668 Set<WikiPage> notOrphans = new HashSet<WikiPage>();
669
670 for (WikiPage page : pages) {
671 for (Map<String, Boolean> pageTitle : pageTitles) {
672 if (pageTitle.get(page.getTitle().toLowerCase()) != null) {
673 notOrphans.add(page);
674
675 break;
676 }
677 }
678 }
679
680 List<WikiPage> orphans = new ArrayList<WikiPage>();
681
682 for (WikiPage page : pages) {
683 if (!notOrphans.contains(page)) {
684 orphans.add(page);
685 }
686 }
687
688 orphans = ListUtil.sort(orphans);
689
690 return orphans;
691 }
692
693 public List<WikiPage> getOutgoingLinks(long nodeId, String title)
694 throws PortalException, SystemException {
695
696 WikiPage page = getPage(nodeId, title);
697
698 Map<String, WikiPage> pages = new LinkedHashMap<String, WikiPage>();
699
700 Map<String, Boolean> links = WikiCacheUtil.getOutgoingLinks(page);
701
702 for (Map.Entry<String, Boolean> entry : links.entrySet()) {
703 String curTitle = entry.getKey();
704 Boolean exists = entry.getValue();
705
706 if (exists) {
707 WikiPage curPage = getPage(nodeId, curTitle);
708
709 if (!pages.containsKey(curPage.getTitle())) {
710 pages.put(curPage.getTitle(), curPage);
711 }
712 }
713 else {
714 WikiPageImpl newPage = new WikiPageImpl();
715
716 newPage.setNew(true);
717 newPage.setNodeId(nodeId);
718 newPage.setTitle(curTitle);
719
720 if (!pages.containsKey(curTitle)) {
721 pages.put(curTitle, newPage);
722 }
723 }
724 }
725
726 return ListUtil.fromMapValues(pages);
727 }
728
729 public WikiPage getPage(long resourcePrimKey)
730 throws PortalException, SystemException {
731
732 return getPage(resourcePrimKey, Boolean.TRUE);
733 }
734
735 public WikiPage getPage(long resourcePrimKey, Boolean head)
736 throws PortalException, SystemException {
737
738 WikiPageResource wikiPageResource =
739 wikiPageResourceLocalService.getPageResource(resourcePrimKey);
740
741 return getPage(
742 wikiPageResource.getNodeId(), wikiPageResource.getTitle(), head);
743 }
744
745 public WikiPage getPage(long nodeId, String title)
746 throws PortalException, SystemException {
747
748 List<WikiPage> pages = wikiPagePersistence.findByN_T_H(
749 nodeId, title, true, 0, 1);
750
751 if (!pages.isEmpty()) {
752 return pages.get(0);
753 }
754 else {
755 throw new NoSuchPageException();
756 }
757 }
758
759 public WikiPage getPage(long nodeId, String title, Boolean head)
760 throws PortalException, SystemException {
761
762 List<WikiPage> pages;
763
764 if (head == null) {
765 pages = wikiPagePersistence.findByN_T(nodeId, title, 0, 1);
766 }
767 else {
768 pages = wikiPagePersistence.findByN_T_H(nodeId, title, head, 0, 1);
769 }
770
771 if (!pages.isEmpty()) {
772 return pages.get(0);
773 }
774 else {
775 throw new NoSuchPageException();
776 }
777 }
778
779 public WikiPage getPage(long nodeId, String title, double version)
780 throws PortalException, SystemException {
781
782 WikiPage page = null;
783
784 if (version == 0) {
785 page = getPage(nodeId, title);
786 }
787 else {
788 page = wikiPagePersistence.findByN_T_V(nodeId, title, version);
789 }
790
791 return page;
792 }
793
794 public WikiPage getPageByPageId(long pageId)
795 throws PortalException, SystemException {
796
797 return wikiPagePersistence.findByPrimaryKey(pageId);
798 }
799
800 public WikiPageDisplay getPageDisplay(
801 long nodeId, String title, PortletURL viewPageURL,
802 PortletURL editPageURL, String attachmentURLPrefix)
803 throws PortalException, SystemException {
804
805 WikiPage page = getPage(nodeId, title);
806
807 return getPageDisplay(
808 page, viewPageURL, editPageURL, attachmentURLPrefix);
809 }
810
811 public WikiPageDisplay getPageDisplay(
812 WikiPage page, PortletURL viewPageURL, PortletURL editPageURL,
813 String attachmentURLPrefix)
814 throws PortalException, SystemException {
815
816 String formattedContent = WikiUtil.convert(
817 page, viewPageURL, editPageURL, attachmentURLPrefix);
818
819 return new WikiPageDisplayImpl(
820 page.getUserId(), page.getNodeId(), page.getTitle(),
821 page.getVersion(), page.getContent(), formattedContent,
822 page.getFormat(), page.getHead(), page.getAttachmentsFiles());
823 }
824
825 public List<WikiPage> getPages(
826 long nodeId, boolean head, int start, int end)
827 throws SystemException {
828
829 return getPages(
830 nodeId, head, start, end, new PageCreateDateComparator(false));
831 }
832
833 public List<WikiPage> getPages(
834 long nodeId, boolean head, int start, int end,
835 OrderByComparator obc)
836 throws SystemException {
837
838 return wikiPagePersistence.findByN_H_S(
839 nodeId, head, WorkflowConstants.STATUS_APPROVED, start, end, obc);
840 }
841
842 public List<WikiPage> getPages(long nodeId, int start, int end)
843 throws SystemException {
844
845 return getPages(
846 nodeId, start, end, new PageCreateDateComparator(false));
847 }
848
849 public List<WikiPage> getPages(
850 long nodeId, int start, int end, OrderByComparator obc)
851 throws SystemException {
852
853 return wikiPagePersistence.findByNodeId(nodeId, start, end, obc);
854 }
855
856 public List<WikiPage> getPages(
857 long resourcePrimKey, long nodeId, int status)
858 throws SystemException {
859
860 return wikiPagePersistence.findByR_N_S(resourcePrimKey, nodeId, status);
861 }
862
863 public List<WikiPage> getPages(
864 long userId, long nodeId, int status, int start, int end)
865 throws SystemException {
866
867 if (userId > 0) {
868 return wikiPagePersistence.findByU_N_S(
869 userId, nodeId, status, start, end,
870 new PageCreateDateComparator(false));
871 }
872 else {
873 return wikiPagePersistence.findByN_S(
874 nodeId, status, start, end,
875 new PageCreateDateComparator(false));
876 }
877 }
878
879 public List<WikiPage> getPages(
880 long nodeId, String title, boolean head, int start, int end)
881 throws SystemException {
882
883 return wikiPagePersistence.findByN_T_H(
884 nodeId, title, head, start, end,
885 new PageCreateDateComparator(false));
886 }
887
888 public List<WikiPage> getPages(
889 long nodeId, String title, int start, int end)
890 throws SystemException {
891
892 return wikiPagePersistence.findByN_T(
893 nodeId, title, start, end, new PageCreateDateComparator(false));
894 }
895
896 public List<WikiPage> getPages(
897 long nodeId, String title, int start, int end,
898 OrderByComparator obc)
899 throws SystemException {
900
901 return wikiPagePersistence.findByN_T(nodeId, title, start, end, obc);
902 }
903
904 public List<WikiPage> getPages(String format) throws SystemException {
905 return wikiPagePersistence.findByFormat(format);
906 }
907
908 public int getPagesCount(long nodeId) throws SystemException {
909 return wikiPagePersistence.countByNodeId(nodeId);
910 }
911
912 public int getPagesCount(long nodeId, boolean head) throws SystemException {
913 return wikiPagePersistence.countByN_H_S(
914 nodeId, head, WorkflowConstants.STATUS_APPROVED);
915 }
916
917 public int getPagesCount(long userId, long nodeId, int status)
918 throws SystemException {
919
920 if (userId > 0) {
921 return wikiPagePersistence.countByU_N_S(userId, nodeId, status);
922 }
923 else {
924 return wikiPagePersistence.countByN_S(nodeId, status);
925 }
926 }
927
928 public int getPagesCount(long nodeId, String title) throws SystemException {
929 return wikiPagePersistence.countByN_T(nodeId, title);
930 }
931
932 public int getPagesCount(long nodeId, String title, boolean head)
933 throws SystemException {
934
935 return wikiPagePersistence.countByN_T_H(nodeId, title, head);
936 }
937
938 public int getPagesCount(String format) throws SystemException {
939 return wikiPagePersistence.countByFormat(format);
940 }
941
942 public List<WikiPage> getRecentChanges(long nodeId, int start, int end)
943 throws SystemException {
944
945 Calendar cal = CalendarFactoryUtil.getCalendar();
946
947 cal.add(Calendar.WEEK_OF_YEAR, -1);
948
949 return wikiPageFinder.findByCreateDate(
950 nodeId, cal.getTime(), false, start, end);
951 }
952
953 public int getRecentChangesCount(long nodeId) throws SystemException {
954 Calendar cal = CalendarFactoryUtil.getCalendar();
955
956 cal.add(Calendar.WEEK_OF_YEAR, -1);
957
958 return wikiPageFinder.countByCreateDate(nodeId, cal.getTime(), false);
959 }
960
961 public String[] getTempPageAttachmentNames(
962 long userId, String tempFolderName) {
963
964 return TempFileUtil.getTempFileEntryNames(userId, tempFolderName);
965 }
966
967 public boolean hasDraftPage(long nodeId, String title)
968 throws SystemException {
969
970 int count = wikiPagePersistence.countByN_T_S(
971 nodeId, title, WorkflowConstants.STATUS_DRAFT);
972
973 if (count > 0) {
974 return true;
975 }
976 else {
977 return false;
978 }
979 }
980
981 public void movePage(
982 long userId, long nodeId, String title, String newTitle,
983 boolean strict, ServiceContext serviceContext)
984 throws PortalException, SystemException {
985
986 validateTitle(newTitle);
987
988
989
990 if (title.equalsIgnoreCase(newTitle)) {
991 throw new DuplicatePageException(newTitle);
992 }
993
994 if (isUsedTitle(nodeId, newTitle)) {
995 WikiPage page = getPage(nodeId, newTitle);
996
997
998
999 if (((page.getVersion() == WikiPageConstants.VERSION_DEFAULT) &&
1000 (page.getContent().length() < 200)) ||
1001 !strict) {
1002
1003 deletePage(nodeId, newTitle);
1004 }
1005 else {
1006 throw new DuplicatePageException(newTitle);
1007 }
1008 }
1009
1010
1011
1012 List<WikiPage> pageVersions = wikiPagePersistence.findByN_T(
1013 nodeId, title);
1014
1015 if (pageVersions.size() == 0) {
1016 return;
1017 }
1018
1019 for (WikiPage page : pageVersions) {
1020 page.setTitle(newTitle);
1021
1022 wikiPagePersistence.update(page, false);
1023 }
1024
1025
1026
1027 List<WikiPage> children = wikiPagePersistence.findByN_P(nodeId, title);
1028
1029 for (WikiPage page : children) {
1030 page.setParentTitle(newTitle);
1031
1032 wikiPagePersistence.update(page, false);
1033 }
1034
1035 WikiPage page = pageVersions.get(pageVersions.size() - 1);
1036
1037 long resourcePrimKey = page.getResourcePrimKey();
1038
1039
1040
1041 WikiPageResource wikiPageResource =
1042 wikiPageResourcePersistence.findByPrimaryKey(resourcePrimKey);
1043
1044 wikiPageResource.setTitle(newTitle);
1045
1046 wikiPageResourcePersistence.update(wikiPageResource, false);
1047
1048
1049
1050 double version = WikiPageConstants.VERSION_DEFAULT;
1051 String summary = WikiPageConstants.MOVED + " to " + title;
1052 String format = page.getFormat();
1053 boolean head = true;
1054 String parentTitle = page.getParentTitle();
1055 String redirectTitle = page.getTitle();
1056 String content =
1057 StringPool.DOUBLE_OPEN_BRACKET + redirectTitle +
1058 StringPool.DOUBLE_CLOSE_BRACKET;
1059
1060 serviceContext.setAddGroupPermissions(true);
1061 serviceContext.setAddGuestPermissions(true);
1062
1063 AssetEntry assetEntry = assetEntryLocalService.getEntry(
1064 WikiPage.class.getName(), page.getResourcePrimKey());
1065
1066 List<AssetLink> assetLinks = assetLinkLocalService.getDirectLinks(
1067 assetEntry.getEntryId(), AssetLinkConstants.TYPE_RELATED);
1068
1069 long[] assetLinkEntryIds = StringUtil.split(
1070 ListUtil.toString(assetLinks, AssetLink.ENTRY_ID2_ACCESSOR), 0L);
1071
1072 serviceContext.setAssetLinkEntryIds(assetLinkEntryIds);
1073
1074 addPage(
1075 userId, nodeId, title, version, content, summary, false, format,
1076 head, parentTitle, redirectTitle, serviceContext);
1077
1078
1079
1080 List<WikiPage> redirectedPages = wikiPagePersistence.findByN_R(
1081 nodeId, title);
1082
1083 for (WikiPage redirectedPage : redirectedPages) {
1084 redirectedPage.setRedirectTitle(newTitle);
1085
1086 wikiPagePersistence.update(redirectedPage, false);
1087 }
1088
1089
1090
1091 updateAsset(userId, page, null, null, null);
1092
1093
1094
1095 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1096 WikiPage.class);
1097
1098 indexer.delete(
1099 new Object[] {page.getCompanyId(), page.getNodeId(), title});
1100
1101 indexer.reindex(page);
1102 }
1103
1104 public void movePage(
1105 long userId, long nodeId, String title, String newTitle,
1106 ServiceContext serviceContext)
1107 throws PortalException, SystemException {
1108
1109 movePage(userId, nodeId, title, newTitle, true, serviceContext);
1110 }
1111
1112 public WikiPage revertPage(
1113 long userId, long nodeId, String title, double version,
1114 ServiceContext serviceContext)
1115 throws PortalException, SystemException {
1116
1117 WikiPage oldPage = getPage(nodeId, title, version);
1118
1119 return updatePage(
1120 userId, nodeId, title, 0, oldPage.getContent(),
1121 WikiPageConstants.REVERTED + " to " + version, false,
1122 oldPage.getFormat(), getParentPageTitle(oldPage),
1123 oldPage.getRedirectTitle(), serviceContext);
1124 }
1125
1126 public void subscribePage(long userId, long nodeId, String title)
1127 throws PortalException, SystemException {
1128
1129 WikiPage page = getPage(nodeId, title);
1130
1131 subscriptionLocalService.addSubscription(
1132 userId, page.getGroupId(), WikiPage.class.getName(),
1133 page.getResourcePrimKey());
1134 }
1135
1136 public void unsubscribePage(long userId, long nodeId, String title)
1137 throws PortalException, SystemException {
1138
1139 WikiPage page = getPage(nodeId, title);
1140
1141 subscriptionLocalService.deleteSubscription(
1142 userId, WikiPage.class.getName(), page.getResourcePrimKey());
1143 }
1144
1145 public void updateAsset(
1146 long userId, WikiPage page, long[] assetCategoryIds,
1147 String[] assetTagNames, long[] assetLinkEntryIds)
1148 throws PortalException, SystemException {
1149
1150 boolean addDraftAssetEntry = false;
1151
1152 if (!page.isApproved() &&
1153 (page.getVersion() != WikiPageConstants.VERSION_DEFAULT)) {
1154
1155 int approvedPagesCount = wikiPagePersistence.countByN_T_S(
1156 page.getNodeId(), page.getTitle(),
1157 WorkflowConstants.STATUS_APPROVED);
1158
1159 if (approvedPagesCount > 0) {
1160 addDraftAssetEntry = true;
1161 }
1162 }
1163
1164 AssetEntry assetEntry = null;
1165
1166 if (addDraftAssetEntry) {
1167 assetEntry = assetEntryLocalService.updateEntry(
1168 userId, page.getGroupId(), WikiPage.class.getName(),
1169 page.getPrimaryKey(), page.getUuid(), 0, assetCategoryIds,
1170 assetTagNames, false, null, null, null, null,
1171 ContentTypes.TEXT_HTML, page.getTitle(), null, null, null, null,
1172 0, 0, null, false);
1173 }
1174 else {
1175 assetEntry = assetEntryLocalService.updateEntry(
1176 userId, page.getGroupId(), WikiPage.class.getName(),
1177 page.getResourcePrimKey(), page.getUuid(), 0, assetCategoryIds,
1178 assetTagNames, page.isApproved(), null, null, null, null,
1179 ContentTypes.TEXT_HTML, page.getTitle(), null, null, null, null,
1180 0, 0, null, false);
1181 }
1182
1183 assetLinkLocalService.updateLinks(
1184 userId, assetEntry.getEntryId(), assetLinkEntryIds,
1185 AssetLinkConstants.TYPE_RELATED);
1186 }
1187
1188 public WikiPage updatePage(
1189 long userId, long nodeId, String title, double version,
1190 String content, String summary, boolean minorEdit, String format,
1191 String parentTitle, String redirectTitle,
1192 ServiceContext serviceContext)
1193 throws PortalException, SystemException {
1194
1195
1196
1197 User user = userPersistence.findByPrimaryKey(userId);
1198 Date now = new Date();
1199
1200 WikiPage oldPage = null;
1201
1202 try {
1203 oldPage = wikiPagePersistence.findByN_T_First(nodeId, title, null);
1204 }
1205 catch (NoSuchPageException nspe) {
1206 return addPage(
1207 userId, nodeId, title, WikiPageConstants.VERSION_DEFAULT,
1208 content, summary, minorEdit, format, true, parentTitle,
1209 redirectTitle, serviceContext);
1210 }
1211
1212 long pageId = 0;
1213
1214 if (oldPage.isApproved()) {
1215 pageId = counterLocalService.increment();
1216 }
1217 else {
1218 pageId = oldPage.getPageId();
1219 }
1220
1221 content = SanitizerUtil.sanitize(
1222 user.getCompanyId(), oldPage.getGroupId(), userId,
1223 WikiPage.class.getName(), pageId, "text/" + format, content);
1224
1225 validate(nodeId, content, format);
1226
1227 double oldVersion = oldPage.getVersion();
1228
1229 if ((version > 0) && (version != oldVersion)) {
1230 throw new PageVersionException();
1231 }
1232
1233 serviceContext.validateModifiedDate(
1234 oldPage, PageVersionException.class);
1235
1236 long resourcePrimKey =
1237 wikiPageResourceLocalService.getPageResourcePrimKey(nodeId, title);
1238 long groupId = oldPage.getGroupId();
1239
1240 WikiPage page = oldPage;
1241
1242 double newVersion = oldVersion;
1243
1244 if (oldPage.isApproved()) {
1245 newVersion = MathUtil.format(oldVersion + 0.1, 1, 1);
1246
1247 page = wikiPagePersistence.create(pageId);
1248 }
1249
1250 page.setResourcePrimKey(resourcePrimKey);
1251 page.setGroupId(groupId);
1252 page.setCompanyId(user.getCompanyId());
1253 page.setUserId(user.getUserId());
1254 page.setUserName(user.getFullName());
1255 page.setCreateDate(serviceContext.getModifiedDate(now));
1256 page.setModifiedDate(serviceContext.getModifiedDate(now));
1257 page.setNodeId(nodeId);
1258 page.setTitle(title);
1259 page.setVersion(newVersion);
1260 page.setMinorEdit(minorEdit);
1261 page.setContent(content);
1262
1263 if (oldPage.isPending()) {
1264 page.setStatus(oldPage.getStatus());
1265 }
1266 else {
1267 page.setStatus(WorkflowConstants.STATUS_DRAFT);
1268 }
1269
1270 page.setSummary(summary);
1271 page.setFormat(format);
1272
1273 if (Validator.isNotNull(parentTitle)) {
1274 page.setParentTitle(parentTitle);
1275 }
1276
1277 if (Validator.isNotNull(redirectTitle)) {
1278 page.setRedirectTitle(redirectTitle);
1279 }
1280
1281 wikiPagePersistence.update(page, false);
1282
1283
1284
1285 ExpandoBridge expandoBridge = page.getExpandoBridge();
1286
1287 expandoBridge.setAttributes(serviceContext);
1288
1289
1290
1291 WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
1292
1293 node.setLastPostDate(serviceContext.getModifiedDate(now));
1294
1295 wikiNodePersistence.update(node, false);
1296
1297
1298
1299 updateAsset(
1300 userId, page, serviceContext.getAssetCategoryIds(),
1301 serviceContext.getAssetTagNames(),
1302 serviceContext.getAssetLinkEntryIds());
1303
1304
1305
1306 WorkflowHandlerRegistryUtil.startWorkflowInstance(
1307 user.getCompanyId(), page.getGroupId(), userId,
1308 WikiPage.class.getName(), page.getPageId(), page, serviceContext);
1309
1310 return page;
1311 }
1312
1313 public WikiPage updateStatus(
1314 long userId, long resourcePrimKey, int status,
1315 ServiceContext serviceContext)
1316 throws PortalException, SystemException {
1317
1318 WikiPageResource wikiPageResource =
1319 wikiPageResourceLocalService.getPageResource(resourcePrimKey);
1320
1321 List<WikiPage> pages = wikiPagePersistence.findByN_T(
1322 wikiPageResource.getNodeId(), wikiPageResource.getTitle(), 0, 1,
1323 new PageVersionComparator());
1324
1325 WikiPage page = null;
1326
1327 if (!pages.isEmpty()) {
1328 page = pages.get(0);
1329 }
1330 else {
1331 throw new NoSuchPageException();
1332 }
1333
1334 return updateStatus(userId, page, status, serviceContext);
1335 }
1336
1337 public WikiPage updateStatus(
1338 long userId, WikiPage page, int status,
1339 ServiceContext serviceContext)
1340 throws PortalException, SystemException {
1341
1342
1343
1344 User user = userPersistence.findByPrimaryKey(userId);
1345 WikiNode node = wikiNodePersistence.findByPrimaryKey(page.getNodeId());
1346
1347 Date now = new Date();
1348
1349 int oldStatus = page.getStatus();
1350
1351 page.setStatus(status);
1352 page.setStatusByUserId(userId);
1353 page.setStatusByUserName(user.getFullName());
1354 page.setStatusDate(now);
1355
1356 if (status == WorkflowConstants.STATUS_APPROVED) {
1357
1358
1359
1360 if ((oldStatus != WorkflowConstants.STATUS_APPROVED) &&
1361 (page.getVersion() != WikiPageConstants.VERSION_DEFAULT)) {
1362
1363 try {
1364 AssetEntry draftAssetEntry =
1365 assetEntryLocalService.getEntry(
1366 WikiPage.class.getName(), page.getPrimaryKey());
1367
1368 long[] assetCategoryIds = draftAssetEntry.getCategoryIds();
1369 String[] assetTagNames = draftAssetEntry.getTagNames();
1370
1371 List<AssetLink> assetLinks =
1372 assetLinkLocalService.getDirectLinks(
1373 draftAssetEntry.getEntryId(),
1374 AssetLinkConstants.TYPE_RELATED);
1375
1376 long[] assetLinkEntryIds = StringUtil.split(
1377 ListUtil.toString(
1378 assetLinks, AssetLink.ENTRY_ID2_ACCESSOR), 0L);
1379
1380 AssetEntry assetEntry = assetEntryLocalService.updateEntry(
1381 userId, page.getGroupId(), WikiPage.class.getName(),
1382 page.getResourcePrimKey(), page.getUuid(), 0,
1383 assetCategoryIds, assetTagNames, true, null, null, null,
1384 null, ContentTypes.TEXT_HTML, page.getTitle(), null,
1385 null, null, null, 0, 0, null, false);
1386
1387
1388
1389 assetLinkLocalService.updateLinks(
1390 userId, assetEntry.getEntryId(), assetLinkEntryIds,
1391 AssetLinkConstants.TYPE_RELATED);
1392
1393 assetEntryLocalService.deleteEntry(
1394 draftAssetEntry.getEntryId());
1395 }
1396 catch (NoSuchEntryException nsee) {
1397 }
1398 }
1399
1400 assetEntryLocalService.updateVisible(
1401 WikiPage.class.getName(), page.getResourcePrimKey(), true);
1402
1403
1404
1405 if (!page.isMinorEdit() ||
1406 PropsValues.WIKI_PAGE_MINOR_EDIT_ADD_SOCIAL_ACTIVITY) {
1407
1408 int activity = WikiActivityKeys.ADD_PAGE;
1409
1410 if (page.getVersion() > WikiPageConstants.VERSION_DEFAULT) {
1411 activity = WikiActivityKeys.UPDATE_PAGE;
1412 }
1413
1414 socialActivityLocalService.addActivity(
1415 userId, page.getGroupId(), WikiPage.class.getName(),
1416 page.getResourcePrimKey(), activity, StringPool.BLANK, 0);
1417 }
1418
1419
1420
1421 if (NotificationThreadLocal.isEnabled() &&
1422 (!page.isMinorEdit() ||
1423 PropsValues.WIKI_PAGE_MINOR_EDIT_SEND_EMAIL)) {
1424
1425 boolean update = false;
1426
1427 if (page.getVersion() > WikiPageConstants.VERSION_DEFAULT) {
1428 update = true;
1429 }
1430
1431 notifySubscribers(node, page, serviceContext, update);
1432 }
1433
1434
1435
1436 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1437 WikiPage.class);
1438
1439 indexer.reindex(page);
1440
1441
1442
1443 clearPageCache(page);
1444
1445
1446
1447 page.setHead(true);
1448
1449 List<WikiPage> pages = wikiPagePersistence.findByN_T_H(
1450 page.getNodeId(), page.getTitle(), true);
1451
1452 for (WikiPage curPage : pages) {
1453 if (!curPage.equals(page)) {
1454 curPage.setHead(false);
1455
1456 wikiPagePersistence.update(curPage, false);
1457 }
1458 }
1459 }
1460 else {
1461
1462
1463
1464 page.setHead(false);
1465
1466 List<WikiPage> pages = wikiPagePersistence.findByN_T_S(
1467 page.getNodeId(), page.getTitle(),
1468 WorkflowConstants.STATUS_APPROVED);
1469
1470 for (WikiPage curPage : pages) {
1471 if (!curPage.equals(page)) {
1472 curPage.setHead(true);
1473
1474 wikiPagePersistence.update(curPage, false);
1475
1476 break;
1477 }
1478 }
1479 }
1480
1481 return wikiPagePersistence.update(page, false);
1482 }
1483
1484 public void validateTitle(String title) throws PortalException {
1485 if (title.equals("all_pages") || title.equals("orphan_pages") ||
1486 title.equals("recent_changes")) {
1487
1488 throw new PageTitleException(title + " is reserved");
1489 }
1490
1491 if (Validator.isNotNull(PropsValues.WIKI_PAGE_TITLES_REGEXP)) {
1492 Pattern pattern = Pattern.compile(
1493 PropsValues.WIKI_PAGE_TITLES_REGEXP);
1494
1495 Matcher matcher = pattern.matcher(title);
1496
1497 if (!matcher.matches()) {
1498 throw new PageTitleException();
1499 }
1500 }
1501 }
1502
1503 protected void clearPageCache(WikiPage page) {
1504 if (!WikiCacheThreadLocal.isClearCache()) {
1505 return;
1506 }
1507
1508 WikiCacheUtil.clearCache(page.getNodeId());
1509 }
1510
1511 protected String getParentPageTitle(WikiPage page) {
1512
1513
1514
1515 try {
1516 WikiPage parentPage = getPage(
1517 page.getNodeId(), page.getParentTitle());
1518
1519 return parentPage.getTitle();
1520 }
1521 catch (Exception e) {
1522 return null;
1523 }
1524 }
1525
1526 protected WikiPage getPreviousVersionPage(WikiPage page)
1527 throws PortalException, SystemException {
1528
1529 double previousVersion = MathUtil.format(page.getVersion() - 0.1, 1, 1);
1530
1531 if (previousVersion < 1) {
1532 return null;
1533 }
1534
1535 return getPage(page.getNodeId(), page.getTitle(), previousVersion);
1536 }
1537
1538 protected boolean isLinkedTo(WikiPage page, String targetTitle)
1539 throws PortalException {
1540
1541 Map<String, Boolean> links = WikiCacheUtil.getOutgoingLinks(page);
1542
1543 Boolean link = links.get(targetTitle.toLowerCase());
1544
1545 if (link != null) {
1546 return true;
1547 }
1548 else {
1549 return false;
1550 }
1551 }
1552
1553 protected boolean isUsedTitle(long nodeId, String title)
1554 throws SystemException {
1555
1556 if (getPagesCount(nodeId, title, true) > 0) {
1557 return true;
1558 }
1559 else {
1560 return false;
1561 }
1562 }
1563
1564 protected void notifySubscribers(
1565 WikiNode node, WikiPage page, ServiceContext serviceContext,
1566 boolean update)
1567 throws PortalException, SystemException {
1568
1569 PortletPreferences preferences = null;
1570
1571 String rootPortletId = serviceContext.getRootPortletId();
1572
1573 if (Validator.isNull(rootPortletId) ||
1574 rootPortletId.equals(PortletKeys.WIKI_DISPLAY)) {
1575
1576 preferences = ServiceContextUtil.getPortletPreferences(
1577 serviceContext);
1578 }
1579
1580 if (preferences == null) {
1581 preferences = portletPreferencesLocalService.getPreferences(
1582 node.getCompanyId(), node.getGroupId(),
1583 PortletKeys.PREFS_OWNER_TYPE_GROUP,
1584 PortletKeys.PREFS_PLID_SHARED, PortletKeys.WIKI_ADMIN, null);
1585 }
1586
1587 if (!update && WikiUtil.getEmailPageAddedEnabled(preferences)) {
1588 }
1589 else if (update && WikiUtil.getEmailPageUpdatedEnabled(preferences)) {
1590 }
1591 else {
1592 return;
1593 }
1594
1595 String portalURL = serviceContext.getPortalURL();
1596 String layoutFullURL = serviceContext.getLayoutFullURL();
1597
1598 WikiPage previousVersionPage = getPreviousVersionPage(page);
1599
1600 String attachmentURLPrefix =
1601 portalURL + serviceContext.getPathMain() +
1602 "/wiki/get_page_attachment?p_l_id=" + serviceContext.getPlid() +
1603 "&nodeId=" + page.getNodeId() + "&title=" +
1604 HttpUtil.encodeURL(page.getTitle()) + "&fileName=";
1605
1606 String pageDiffs = StringPool.BLANK;
1607
1608 try {
1609 pageDiffs = WikiUtil.diffHtml(
1610 previousVersionPage, page, null, null, attachmentURLPrefix);
1611 }
1612 catch (Exception e) {
1613 }
1614
1615 String pageContent = null;
1616
1617 if (Validator.equals(page.getFormat(), "creole")) {
1618 pageContent = WikiUtil.convert(
1619 page, null, null, attachmentURLPrefix);
1620 }
1621 else {
1622 pageContent = page.getContent();
1623 pageContent = WikiUtil.processContent(pageContent);
1624 }
1625
1626 String pageURL = StringPool.BLANK;
1627 String diffsURL = StringPool.BLANK;
1628
1629 if (Validator.isNotNull(layoutFullURL)) {
1630 pageURL =
1631 layoutFullURL + Portal.FRIENDLY_URL_SEPARATOR + "wiki/" +
1632 node.getNodeId() + StringPool.SLASH +
1633 HttpUtil.encodeURL(page.getTitle());
1634
1635 if (previousVersionPage != null) {
1636 StringBundler sb = new StringBundler(16);
1637
1638 sb.append(layoutFullURL);
1639 sb.append("?p_p_id=");
1640 sb.append(PortletKeys.WIKI);
1641 sb.append("&p_p_state=");
1642 sb.append(WindowState.MAXIMIZED);
1643 sb.append("&struts_action=");
1644 sb.append(HttpUtil.encodeURL("/wiki/compare_versions"));
1645 sb.append("&nodeId=");
1646 sb.append(node.getNodeId());
1647 sb.append("&title=");
1648 sb.append(HttpUtil.encodeURL(page.getTitle()));
1649 sb.append("&sourceVersion=");
1650 sb.append(previousVersionPage.getVersion());
1651 sb.append("&targetVersion=");
1652 sb.append(page.getVersion());
1653 sb.append("&type=html");
1654
1655 diffsURL = sb.toString();
1656 }
1657 }
1658
1659 String fromName = WikiUtil.getEmailFromName(
1660 preferences, page.getCompanyId());
1661 String fromAddress = WikiUtil.getEmailFromAddress(
1662 preferences, page.getCompanyId());
1663
1664 String subjectPrefix = null;
1665 String body = null;
1666 String signature = null;
1667
1668 if (update) {
1669 subjectPrefix = WikiUtil.getEmailPageUpdatedSubjectPrefix(
1670 preferences);
1671 body = WikiUtil.getEmailPageUpdatedBody(preferences);
1672 signature = WikiUtil.getEmailPageUpdatedSignature(preferences);
1673 }
1674 else {
1675 subjectPrefix = WikiUtil.getEmailPageAddedSubjectPrefix(
1676 preferences);
1677 body = WikiUtil.getEmailPageAddedBody(preferences);
1678 signature = WikiUtil.getEmailPageAddedSignature(preferences);
1679 }
1680
1681 String subject = page.getTitle();
1682
1683 if (subject.indexOf(subjectPrefix) == -1) {
1684 subject = subjectPrefix + StringPool.SPACE + subject;
1685 }
1686
1687 if (Validator.isNotNull(signature)) {
1688 body += "\n" + signature;
1689 }
1690
1691 SubscriptionSender subscriptionSender = new SubscriptionSender();
1692
1693 subscriptionSender.setBody(body);
1694 subscriptionSender.setCompanyId(page.getCompanyId());
1695 subscriptionSender.setContextAttributes(
1696 "[$DIFFS_URL$]", diffsURL, "[$NODE_NAME$]", node.getName(),
1697 "[$PAGE_DATE_UPDATE$]", page.getModifiedDate(), "[$PAGE_ID$]",
1698 page.getPageId(), "[$PAGE_SUMMARY$]", page.getSummary(),
1699 "[$PAGE_TITLE$]", page.getTitle(), "[$PAGE_URL$]", pageURL);
1700 subscriptionSender.setContextAttribute(
1701 "[$PAGE_CONTENT$]", pageContent, false);
1702 subscriptionSender.setContextAttribute(
1703 "[$PAGE_DIFFS$]", replaceStyles(pageDiffs), false);
1704 subscriptionSender.setContextUserPrefix("PAGE");
1705 subscriptionSender.setFrom(fromAddress, fromName);
1706 subscriptionSender.setHtmlFormat(true);
1707 subscriptionSender.setMailId(
1708 "wiki_page", page.getNodeId(), page.getPageId());
1709 subscriptionSender.setPortletId(PortletKeys.WIKI);
1710 subscriptionSender.setReplyToAddress(fromAddress);
1711 subscriptionSender.setScopeGroupId(node.getGroupId());
1712 subscriptionSender.setServiceContext(serviceContext);
1713 subscriptionSender.setSubject(subject);
1714 subscriptionSender.setUserId(page.getUserId());
1715
1716 subscriptionSender.addPersistedSubscribers(
1717 WikiNode.class.getName(), node.getNodeId());
1718 subscriptionSender.addPersistedSubscribers(
1719 WikiPage.class.getName(), page.getResourcePrimKey());
1720
1721 subscriptionSender.flushNotificationsAsync();
1722 }
1723
1724 protected String replaceStyles(String html) {
1725 return StringUtil.replace(
1726 html,
1727 new String[] {
1728 "class=\"diff-html-added\"", "class=\"diff-html-removed\"",
1729 "class=\"diff-html-changed\"",
1730 "changeType=\"diff-added-image\"",
1731 "changeType=\"diff-removed-image\"",
1732 "changeType=\"diff-changed-image\""
1733 },
1734 new String[] {
1735 "style=\"background-color: #CFC;\"",
1736 "style=\"background-color: #FDC6C6; text-decoration: " +
1737 "line-through;\"",
1738 "style=\"border-bottom: 2px dotted blue;\"",
1739 "style=\"border: 10px solid #CFC;\"",
1740 "style=\"border: 10px solid #FDC6C6;\"",
1741 "style=\"border: 10px solid blue;\""
1742 }
1743 );
1744 }
1745
1746 protected void validate(long nodeId, String content, String format)
1747 throws PortalException {
1748
1749 if (!WikiUtil.validate(nodeId, content, format)) {
1750 throw new PageContentException();
1751 }
1752 }
1753
1754 protected void validate(
1755 String title, long nodeId, String content, String format)
1756 throws PortalException, SystemException {
1757
1758 if (Validator.isNull(title)) {
1759 throw new PageTitleException();
1760 }
1761
1762 if (isUsedTitle(nodeId, title)) {
1763 throw new DuplicatePageException();
1764 }
1765
1766 validateTitle(title);
1767
1768 validate(nodeId, content, format);
1769 }
1770
1771 }