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