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