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