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