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