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