001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portlet.wiki.service.impl;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.exception.SystemException;
019    import com.liferay.portal.kernel.json.JSONFactoryUtil;
020    import com.liferay.portal.kernel.json.JSONObject;
021    import com.liferay.portal.kernel.repository.model.FileEntry;
022    import com.liferay.portal.kernel.repository.model.Folder;
023    import com.liferay.portal.kernel.sanitizer.SanitizerUtil;
024    import com.liferay.portal.kernel.search.Indexer;
025    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
026    import com.liferay.portal.kernel.systemevent.SystemEvent;
027    import com.liferay.portal.kernel.systemevent.SystemEventHierarchyEntryThreadLocal;
028    import com.liferay.portal.kernel.util.CalendarFactoryUtil;
029    import com.liferay.portal.kernel.util.ContentTypes;
030    import com.liferay.portal.kernel.util.FileUtil;
031    import com.liferay.portal.kernel.util.HttpUtil;
032    import com.liferay.portal.kernel.util.ListUtil;
033    import com.liferay.portal.kernel.util.MathUtil;
034    import com.liferay.portal.kernel.util.MimeTypesUtil;
035    import com.liferay.portal.kernel.util.NotificationThreadLocal;
036    import com.liferay.portal.kernel.util.ObjectValuePair;
037    import com.liferay.portal.kernel.util.OrderByComparator;
038    import com.liferay.portal.kernel.util.StringBundler;
039    import com.liferay.portal.kernel.util.StringPool;
040    import com.liferay.portal.kernel.util.StringUtil;
041    import com.liferay.portal.kernel.util.TempFileUtil;
042    import com.liferay.portal.kernel.util.UnicodeProperties;
043    import com.liferay.portal.kernel.util.UniqueList;
044    import com.liferay.portal.kernel.util.Validator;
045    import com.liferay.portal.kernel.workflow.WorkflowConstants;
046    import com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil;
047    import com.liferay.portal.kernel.workflow.WorkflowThreadLocal;
048    import com.liferay.portal.model.LayoutConstants;
049    import com.liferay.portal.model.ResourceConstants;
050    import com.liferay.portal.model.SystemEventConstants;
051    import com.liferay.portal.model.User;
052    import com.liferay.portal.portletfilerepository.PortletFileRepositoryUtil;
053    import com.liferay.portal.service.ServiceContext;
054    import com.liferay.portal.service.ServiceContextUtil;
055    import com.liferay.portal.util.Portal;
056    import com.liferay.portal.util.PortalUtil;
057    import com.liferay.portal.util.PortletKeys;
058    import com.liferay.portal.util.PropsValues;
059    import com.liferay.portal.util.SubscriptionSender;
060    import com.liferay.portlet.PortletURLFactoryUtil;
061    import com.liferay.portlet.asset.model.AssetEntry;
062    import com.liferay.portlet.asset.model.AssetLink;
063    import com.liferay.portlet.asset.model.AssetLinkConstants;
064    import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
065    import com.liferay.portlet.expando.model.ExpandoBridge;
066    import com.liferay.portlet.social.model.SocialActivity;
067    import com.liferay.portlet.social.model.SocialActivityConstants;
068    import com.liferay.portlet.trash.model.TrashEntry;
069    import com.liferay.portlet.trash.model.TrashVersion;
070    import com.liferay.portlet.trash.util.TrashUtil;
071    import com.liferay.portlet.wiki.DuplicatePageException;
072    import com.liferay.portlet.wiki.NoSuchPageException;
073    import com.liferay.portlet.wiki.PageContentException;
074    import com.liferay.portlet.wiki.PageTitleException;
075    import com.liferay.portlet.wiki.PageVersionException;
076    import com.liferay.portlet.wiki.model.WikiNode;
077    import com.liferay.portlet.wiki.model.WikiPage;
078    import com.liferay.portlet.wiki.model.WikiPageConstants;
079    import com.liferay.portlet.wiki.model.WikiPageDisplay;
080    import com.liferay.portlet.wiki.model.WikiPageResource;
081    import com.liferay.portlet.wiki.model.impl.WikiPageDisplayImpl;
082    import com.liferay.portlet.wiki.model.impl.WikiPageImpl;
083    import com.liferay.portlet.wiki.service.base.WikiPageLocalServiceBaseImpl;
084    import com.liferay.portlet.wiki.social.WikiActivityKeys;
085    import com.liferay.portlet.wiki.util.WikiCacheThreadLocal;
086    import com.liferay.portlet.wiki.util.WikiCacheUtil;
087    import com.liferay.portlet.wiki.util.WikiUtil;
088    import com.liferay.portlet.wiki.util.comparator.PageCreateDateComparator;
089    import com.liferay.portlet.wiki.util.comparator.PageVersionComparator;
090    
091    import java.io.File;
092    import java.io.IOException;
093    import java.io.InputStream;
094    
095    import java.util.ArrayList;
096    import java.util.Calendar;
097    import java.util.Date;
098    import java.util.LinkedHashMap;
099    import java.util.List;
100    import java.util.Map;
101    import java.util.regex.Matcher;
102    import java.util.regex.Pattern;
103    
104    import javax.portlet.PortletPreferences;
105    import javax.portlet.PortletRequest;
106    import javax.portlet.PortletURL;
107    
108    import javax.servlet.http.HttpServletRequest;
109    
110    /**
111     * Provides the local service for accessing, adding, deleting, moving,
112     * subscription handling of, trash handling of, updating, and validating wiki
113     * pages.
114     *
115     * @author Brian Wing Shun Chan
116     * @author Jorge Ferrer
117     * @author Raymond Aug??
118     * @author Bruno Farache
119     * @author Julio Camarero
120     * @author Wesley Gong
121     * @author Marcellus Tavares
122     * @author Zsigmond Rab
123     * @author Zsolt Berentey
124     */
125    public class WikiPageLocalServiceImpl extends WikiPageLocalServiceBaseImpl {
126    
127            @Override
128            public WikiPage addPage(
129                            long userId, long nodeId, String title, double version,
130                            String content, String summary, boolean minorEdit, String format,
131                            boolean head, String parentTitle, String redirectTitle,
132                            ServiceContext serviceContext)
133                    throws PortalException, SystemException {
134    
135                    // Page
136    
137                    User user = userPersistence.findByPrimaryKey(userId);
138                    WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
139                    Date now = new Date();
140    
141                    long pageId = counterLocalService.increment();
142    
143                    content = SanitizerUtil.sanitize(
144                            user.getCompanyId(), node.getGroupId(), userId,
145                            WikiPage.class.getName(), pageId, "text/" + format, content);
146    
147                    validate(title, nodeId, content, format);
148    
149                    long resourcePrimKey =
150                            wikiPageResourceLocalService.getPageResourcePrimKey(nodeId, title);
151    
152                    WikiPage page = wikiPagePersistence.create(pageId);
153    
154                    page.setUuid(serviceContext.getUuid());
155                    page.setResourcePrimKey(resourcePrimKey);
156                    page.setGroupId(node.getGroupId());
157                    page.setCompanyId(user.getCompanyId());
158                    page.setUserId(user.getUserId());
159                    page.setUserName(user.getFullName());
160                    page.setCreateDate(serviceContext.getCreateDate(now));
161                    page.setModifiedDate(serviceContext.getModifiedDate(now));
162                    page.setNodeId(nodeId);
163                    page.setTitle(title);
164                    page.setVersion(version);
165                    page.setMinorEdit(minorEdit);
166                    page.setContent(content);
167                    page.setSummary(summary);
168                    page.setFormat(format);
169                    page.setHead(head);
170                    page.setParentTitle(parentTitle);
171                    page.setRedirectTitle(redirectTitle);
172                    page.setStatus(WorkflowConstants.STATUS_DRAFT);
173                    page.setStatusByUserId(userId);
174                    page.setStatusDate(serviceContext.getModifiedDate(now));
175                    page.setExpandoBridgeAttributes(serviceContext);
176    
177                    wikiPagePersistence.update(page);
178    
179                    // Resources
180    
181                    if (serviceContext.isAddGroupPermissions() ||
182                            serviceContext.isAddGuestPermissions()) {
183    
184                            addPageResources(
185                                    page, serviceContext.isAddGroupPermissions(),
186                                    serviceContext.isAddGuestPermissions());
187                    }
188                    else {
189                            addPageResources(
190                                    page, serviceContext.getGroupPermissions(),
191                                    serviceContext.getGuestPermissions());
192                    }
193    
194                    // Node
195    
196                    node.setLastPostDate(serviceContext.getModifiedDate(now));
197    
198                    wikiNodePersistence.update(node);
199    
200                    // Asset
201    
202                    updateAsset(
203                            userId, page, serviceContext.getAssetCategoryIds(),
204                            serviceContext.getAssetTagNames(),
205                            serviceContext.getAssetLinkEntryIds());
206    
207                    // Message boards
208    
209                    if (PropsValues.WIKI_PAGE_COMMENTS_ENABLED) {
210                            mbMessageLocalService.addDiscussionMessage(
211                                    userId, page.getUserName(), page.getGroupId(),
212                                    WikiPage.class.getName(), resourcePrimKey,
213                                    WorkflowConstants.ACTION_PUBLISH);
214                    }
215    
216                    // Workflow
217    
218                    WorkflowHandlerRegistryUtil.startWorkflowInstance(
219                            user.getCompanyId(), page.getGroupId(), userId,
220                            WikiPage.class.getName(), page.getPageId(), page, serviceContext);
221    
222                    return page;
223            }
224    
225            @Override
226            public WikiPage addPage(
227                            long userId, long nodeId, String title, String content,
228                            String summary, boolean minorEdit, ServiceContext serviceContext)
229                    throws PortalException, SystemException {
230    
231                    double version = WikiPageConstants.VERSION_DEFAULT;
232                    String format = WikiPageConstants.DEFAULT_FORMAT;
233                    boolean head = false;
234                    String parentTitle = null;
235                    String redirectTitle = null;
236    
237                    return addPage(
238                            userId, nodeId, title, version, content, summary, minorEdit, format,
239                            head, parentTitle, redirectTitle, serviceContext);
240            }
241    
242            @Override
243            public void addPageAttachment(
244                            long userId, long nodeId, String title, String fileName, File file,
245                            String mimeType)
246                    throws PortalException, SystemException {
247    
248                    WikiPage page = getPage(nodeId, title);
249    
250                    Folder folder = page.addAttachmentsFolder();
251    
252                    FileEntry fileEntry = PortletFileRepositoryUtil.addPortletFileEntry(
253                            page.getGroupId(), userId, WikiPage.class.getName(),
254                            page.getResourcePrimKey(), PortletKeys.WIKI, folder.getFolderId(),
255                            file, fileName, mimeType, true);
256    
257                    if (userId == 0) {
258                            userId = page.getUserId();
259                    }
260    
261                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
262    
263                    extraDataJSONObject.put("fileEntryId", fileEntry.getFileEntryId());
264                    extraDataJSONObject.put("fileEntryTitle", fileEntry.getTitle());
265                    extraDataJSONObject.put("title", page.getTitle());
266                    extraDataJSONObject.put("version", page.getVersion());
267    
268                    socialActivityLocalService.addActivity(
269                            userId, page.getGroupId(), WikiPage.class.getName(),
270                            page.getResourcePrimKey(),
271                            SocialActivityConstants.TYPE_ADD_ATTACHMENT,
272                            extraDataJSONObject.toString(), 0);
273            }
274    
275            @Override
276            public void addPageAttachment(
277                            long userId, long nodeId, String title, String fileName,
278                            InputStream inputStream, String mimeType)
279                    throws PortalException, SystemException {
280    
281                    WikiPage page = getPage(nodeId, title);
282    
283                    Folder folder = page.addAttachmentsFolder();
284    
285                    FileEntry fileEntry = PortletFileRepositoryUtil.addPortletFileEntry(
286                            page.getGroupId(), userId, WikiPage.class.getName(),
287                            page.getResourcePrimKey(), PortletKeys.WIKI, folder.getFolderId(),
288                            inputStream, fileName, mimeType, true);
289    
290                    if (userId == 0) {
291                            userId = page.getUserId();
292                    }
293    
294                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
295    
296                    extraDataJSONObject.put("fileEntryId", fileEntry.getFileEntryId());
297                    extraDataJSONObject.put("fileEntryTitle", fileEntry.getTitle());
298                    extraDataJSONObject.put("title", page.getTitle());
299                    extraDataJSONObject.put("version", page.getVersion());
300    
301                    socialActivityLocalService.addActivity(
302                            userId, page.getGroupId(), WikiPage.class.getName(),
303                            page.getResourcePrimKey(),
304                            SocialActivityConstants.TYPE_ADD_ATTACHMENT,
305                            extraDataJSONObject.toString(), 0);
306            }
307    
308            @Override
309            public void addPageAttachments(
310                            long userId, long nodeId, String title,
311                            List<ObjectValuePair<String, InputStream>> inputStreamOVPs)
312                    throws PortalException, SystemException {
313    
314                    if (inputStreamOVPs.size() == 0) {
315                            return;
316                    }
317    
318                    for (int i = 0; i < inputStreamOVPs.size(); i++) {
319                            ObjectValuePair<String, InputStream> inputStreamOVP =
320                                    inputStreamOVPs.get(i);
321    
322                            String fileName = inputStreamOVP.getKey();
323                            InputStream inputStream = inputStreamOVP.getValue();
324    
325                            File file = null;
326    
327                            try {
328                                    file = FileUtil.createTempFile(inputStream);
329    
330                                    String mimeType = MimeTypesUtil.getContentType(file, fileName);
331    
332                                    addPageAttachment(
333                                            userId, nodeId, title, fileName, file, mimeType);
334                            }
335                            catch (IOException ioe) {
336                                    throw new SystemException(
337                                            "Unable to write temporary file", ioe);
338                            }
339                            finally {
340                                    FileUtil.delete(file);
341                            }
342                    }
343            }
344    
345            @Override
346            public void addPageResources(
347                            long nodeId, String title, boolean addGroupPermissions,
348                            boolean addGuestPermissions)
349                    throws PortalException, SystemException {
350    
351                    WikiPage page = getPage(nodeId, title);
352    
353                    addPageResources(page, addGroupPermissions, addGuestPermissions);
354            }
355    
356            @Override
357            public void addPageResources(
358                            long nodeId, String title, String[] groupPermissions,
359                            String[] guestPermissions)
360                    throws PortalException, SystemException {
361    
362                    WikiPage page = getPage(nodeId, title);
363    
364                    addPageResources(page, groupPermissions, guestPermissions);
365            }
366    
367            @Override
368            public void addPageResources(
369                            WikiPage page, boolean addGroupPermissions,
370                            boolean addGuestPermissions)
371                    throws PortalException, SystemException {
372    
373                    resourceLocalService.addResources(
374                            page.getCompanyId(), page.getGroupId(), page.getUserId(),
375                            WikiPage.class.getName(), page.getResourcePrimKey(), false,
376                            addGroupPermissions, addGuestPermissions);
377            }
378    
379            @Override
380            public void addPageResources(
381                            WikiPage page, String[] groupPermissions, String[] guestPermissions)
382                    throws PortalException, SystemException {
383    
384                    resourceLocalService.addModelResources(
385                            page.getCompanyId(), page.getGroupId(), page.getUserId(),
386                            WikiPage.class.getName(), page.getResourcePrimKey(),
387                            groupPermissions, guestPermissions);
388            }
389    
390            @Override
391            public void addTempPageAttachment(
392                            long groupId, long userId, String fileName, String tempFolderName,
393                            InputStream inputStream, String mimeType)
394                    throws PortalException, SystemException {
395    
396                    TempFileUtil.addTempFile(
397                            groupId, userId, fileName, tempFolderName, inputStream, mimeType);
398            }
399    
400            @Override
401            public void changeParent(
402                            long userId, long nodeId, String title, String newParentTitle,
403                            ServiceContext serviceContext)
404                    throws PortalException, SystemException {
405    
406                    if (Validator.isNotNull(newParentTitle)) {
407                            WikiPage parentPage = getPage(nodeId, newParentTitle);
408    
409                            if (Validator.isNotNull(parentPage.getRedirectTitle())) {
410                                    newParentTitle = parentPage.getRedirectTitle();
411                            }
412                    }
413    
414                    WikiPage page = getPage(nodeId, title);
415    
416                    String originalParentTitle = page.getParentTitle();
417    
418                    double version = page.getVersion();
419                    String content = page.getContent();
420                    String summary = serviceContext.translate(
421                            "changed-parent-from-x", originalParentTitle);
422                    boolean minorEdit = false;
423                    String format = page.getFormat();
424                    String redirectTitle = page.getRedirectTitle();
425    
426                    populateServiceContext(serviceContext, page);
427    
428                    updatePage(
429                            userId, nodeId, title, version, content, summary, minorEdit, format,
430                            newParentTitle, redirectTitle, serviceContext);
431    
432                    List<WikiPage> oldPages = wikiPagePersistence.findByN_T_H(
433                            nodeId, title, false);
434    
435                    for (WikiPage oldPage : oldPages) {
436                            if (!WorkflowThreadLocal.isEnabled()) {
437                                    oldPage.setParentTitle(originalParentTitle);
438    
439                                    wikiPagePersistence.update(oldPage);
440                            }
441                    }
442            }
443    
444            @Override
445            public void copyPageAttachments(
446                            long userId, long templateNodeId, String templateTitle, long nodeId,
447                            String title)
448                    throws PortalException, SystemException {
449    
450                    WikiPage templatePage = getPage(templateNodeId, templateTitle);
451    
452                    List<FileEntry> templateFileEntries =
453                            templatePage.getAttachmentsFileEntries();
454    
455                    for (FileEntry templateFileEntry : templateFileEntries) {
456                            addPageAttachment(
457                                    userId, nodeId, title, templateFileEntry.getTitle(),
458                                    templateFileEntry.getContentStream(),
459                                    templateFileEntry.getMimeType());
460                    }
461            }
462    
463            @Override
464            public void deletePage(long nodeId, String title)
465                    throws PortalException, SystemException {
466    
467                    List<WikiPage> pages = wikiPagePersistence.findByN_T_H(
468                            nodeId, title, true, 0, 1);
469    
470                    if (!pages.isEmpty()) {
471                            wikiPageLocalService.deletePage(pages.get(0));
472                    }
473            }
474    
475            /**
476             * @deprecated As of 6.2.0 replaced by {@link #discardDraft(long, String,
477             *             double)}
478             */
479            @Override
480            public void deletePage(long nodeId, String title, double version)
481                    throws PortalException, SystemException {
482    
483                    discardDraft(nodeId, title, version);
484            }
485    
486            @Override
487            @SystemEvent(
488                    action = SystemEventConstants.ACTION_SKIP, send = false,
489                    type = SystemEventConstants.TYPE_DELETE)
490            public void deletePage(WikiPage page)
491                    throws PortalException, SystemException {
492    
493                    // Children
494    
495                    List<WikiPage> childrenPages = wikiPagePersistence.findByN_P(
496                            page.getNodeId(), page.getTitle());
497    
498                    for (WikiPage childrenPage : childrenPages) {
499                            if (!childrenPage.isApproved()) {
500                                    childrenPage.setParentTitle(StringPool.BLANK);
501    
502                                    wikiPagePersistence.update(childrenPage);
503                            }
504                            else {
505                                    wikiPageLocalService.deletePage(childrenPage);
506                            }
507                    }
508    
509                    // Redirect Pages
510    
511                    List<WikiPage> redirectPages = wikiPagePersistence.findByN_R(
512                            page.getNodeId(), page.getTitle());
513    
514                    for (WikiPage redirectPage : redirectPages) {
515                            if (!redirectPage.isApproved()) {
516                                    redirectPage.setRedirectTitle(StringPool.BLANK);
517    
518                                    wikiPagePersistence.update(redirectPage);
519                            }
520                            else {
521                                    wikiPageLocalService.deletePage(redirectPage);
522                            }
523                    }
524    
525                    List<WikiPage> versionPages = wikiPagePersistence.findByN_T(
526                            page.getNodeId(), page.getTitle());
527    
528                    wikiPagePersistence.removeByN_T(page.getNodeId(), page.getTitle());
529    
530                    // References
531    
532                    wikiPagePersistence.removeByN_R(page.getNodeId(), page.getTitle());
533    
534                    // Resources
535    
536                    resourceLocalService.deleteResource(
537                            page.getCompanyId(), WikiPage.class.getName(),
538                            ResourceConstants.SCOPE_INDIVIDUAL, page.getResourcePrimKey());
539    
540                    // Resource
541    
542                    WikiPageResource pageResource =
543                            wikiPageResourceLocalService.fetchPageResource(
544                                    page.getNodeId(), page.getTitle());
545    
546                    if (pageResource != null) {
547                            wikiPageResourceLocalService.deleteWikiPageResource(pageResource);
548                    }
549    
550                    // Attachments
551    
552                    long folderId = page.getAttachmentsFolderId();
553    
554                    if (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
555                            PortletFileRepositoryUtil.deleteFolder(folderId);
556                    }
557    
558                    // Subscriptions
559    
560                    subscriptionLocalService.deleteSubscriptions(
561                            page.getCompanyId(), WikiPage.class.getName(),
562                            page.getResourcePrimKey());
563    
564                    // Asset
565    
566                    SystemEventHierarchyEntryThreadLocal.pop(
567                            page.getModelClass(), page.getPageId());
568    
569                    try {
570                            for (WikiPage versionPage : versionPages) {
571                                    assetEntryLocalService.deleteEntry(
572                                            WikiPage.class.getName(), versionPage.getPrimaryKey());
573                            }
574                    }
575                    finally {
576                            SystemEventHierarchyEntryThreadLocal.push(
577                                    page.getModelClass(), page.getPageId());
578                    }
579    
580                    assetEntryLocalService.deleteEntry(
581                            WikiPage.class.getName(), page.getResourcePrimKey());
582    
583                    // Expando
584    
585                    expandoRowLocalService.deleteRows(page.getPrimaryKey());
586    
587                    // Message boards
588    
589                    mbMessageLocalService.deleteDiscussionMessages(
590                            WikiPage.class.getName(), page.getResourcePrimKey());
591    
592                    // Trash
593    
594                    if (page.isInTrash()) {
595                            page.setTitle(TrashUtil.getOriginalTitle(page.getTitle()));
596    
597                            trashEntryLocalService.deleteEntry(
598                                    WikiPage.class.getName(), page.getResourcePrimKey());
599                    }
600    
601                    // Indexer
602    
603                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
604                            WikiPage.class);
605    
606                    indexer.delete(page);
607    
608                    // Cache
609    
610                    clearPageCache(page);
611    
612                    // All versions
613    
614                    for (WikiPage versionPage : versionPages) {
615    
616                            // Workflow
617    
618                            workflowInstanceLinkLocalService.deleteWorkflowInstanceLinks(
619                                    versionPage.getCompanyId(), versionPage.getGroupId(),
620                                    WikiPage.class.getName(), versionPage.getPageId());
621                    }
622    
623                    if (pageResource != null) {
624                            JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
625    
626                            extraDataJSONObject.put("version", page.getVersion());
627    
628                            systemEventLocalService.addSystemEvent(
629                                    0, page.getGroupId(), page.getModelClassName(),
630                                    page.getPrimaryKey(), pageResource.getUuid(), null,
631                                    SystemEventConstants.TYPE_DELETE,
632                                    extraDataJSONObject.toString());
633                    }
634            }
635    
636            @Override
637            public void deletePageAttachment(long nodeId, String title, String fileName)
638                    throws PortalException, SystemException {
639    
640                    WikiPage page = getPage(nodeId, title);
641    
642                    long folderId = page.getAttachmentsFolderId();
643    
644                    if (folderId == DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
645                            return;
646                    }
647    
648                    FileEntry fileEntry = PortletFileRepositoryUtil.getPortletFileEntry(
649                            page.getGroupId(), folderId, fileName);
650    
651                    deletePageAttachment(fileEntry.getFileEntryId());
652            }
653    
654            @Override
655            public void deletePageAttachments(long nodeId, String title)
656                    throws PortalException, SystemException {
657    
658                    WikiPage page = getPage(nodeId, title);
659    
660                    long folderId = page.getAttachmentsFolderId();
661    
662                    if (folderId == DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
663                            return;
664                    }
665    
666                    PortletFileRepositoryUtil.deletePortletFileEntries(
667                            page.getGroupId(), folderId);
668            }
669    
670            @Override
671            public void deletePages(long nodeId)
672                    throws PortalException, SystemException {
673    
674                    List<WikiPage> pages = wikiPagePersistence.findByN_H_P(
675                            nodeId, true, StringPool.BLANK);
676    
677                    for (WikiPage page : pages) {
678                            wikiPageLocalService.deletePage(page);
679                    }
680    
681                    pages = wikiPagePersistence.findByN_H_P(
682                            nodeId, false, StringPool.BLANK);
683    
684                    for (WikiPage page : pages) {
685                            wikiPageLocalService.deletePage(page);
686                    }
687            }
688    
689            @Override
690            public void deleteTempPageAttachment(
691                            long groupId, long userId, String fileName, String tempFolderName)
692                    throws PortalException, SystemException {
693    
694                    TempFileUtil.deleteTempFile(groupId, userId, fileName, tempFolderName);
695            }
696    
697            @Override
698            public void deleteTrashPageAttachments(long nodeId, String title)
699                    throws PortalException, SystemException {
700    
701                    WikiPage page = getPage(nodeId, title);
702    
703                    long folderId = page.getAttachmentsFolderId();
704    
705                    if (folderId == DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
706                            return;
707                    }
708    
709                    PortletFileRepositoryUtil.deletePortletFileEntries(
710                            page.getGroupId(), folderId, WorkflowConstants.STATUS_IN_TRASH);
711            }
712    
713            @Override
714            public void discardDraft(long nodeId, String title, double version)
715                    throws PortalException, SystemException {
716    
717                    wikiPagePersistence.removeByN_T_V(nodeId, title, version);
718            }
719    
720            @Override
721            public WikiPage fetchLatestPage(
722                            long resourcePrimKey, int status, boolean preferApproved)
723                    throws SystemException {
724    
725                    WikiPage page = null;
726    
727                    OrderByComparator orderByComparator = new PageVersionComparator();
728    
729                    if (status == WorkflowConstants.STATUS_ANY) {
730                            if (preferApproved) {
731                                    page = wikiPagePersistence.fetchByR_S_First(
732                                            resourcePrimKey, WorkflowConstants.STATUS_APPROVED,
733                                            orderByComparator);
734                            }
735    
736                            if (page == null) {
737                                    page = wikiPagePersistence.fetchByResourcePrimKey_First(
738                                            resourcePrimKey, orderByComparator);
739                            }
740                    }
741                    else {
742                            page = wikiPagePersistence.fetchByR_S_First(
743                                    resourcePrimKey, status, orderByComparator);
744                    }
745    
746                    return page;
747            }
748    
749            @Override
750            public WikiPage fetchLatestPage(
751                            long resourcePrimKey, long nodeId, int status,
752                            boolean preferApproved)
753                    throws SystemException {
754    
755                    WikiPage page = null;
756    
757                    OrderByComparator orderByComparator = new PageVersionComparator();
758    
759                    if (status == WorkflowConstants.STATUS_ANY) {
760                            if (preferApproved) {
761                                    page = wikiPagePersistence.fetchByR_N_S_First(
762                                            resourcePrimKey, nodeId, WorkflowConstants.STATUS_APPROVED,
763                                            orderByComparator);
764                            }
765    
766                            if (page == null) {
767                                    page = wikiPagePersistence.fetchByR_N_First(
768                                            resourcePrimKey, nodeId, orderByComparator);
769                            }
770                    }
771                    else {
772                            page = wikiPagePersistence.fetchByR_N_S_First(
773                                    resourcePrimKey, nodeId, status, orderByComparator);
774                    }
775    
776                    return page;
777            }
778    
779            @Override
780            public WikiPage fetchLatestPage(
781                            long nodeId, String title, int status, boolean preferApproved)
782                    throws SystemException {
783    
784                    WikiPage page = null;
785    
786                    OrderByComparator orderByComparator = new PageVersionComparator();
787    
788                    if (status == WorkflowConstants.STATUS_ANY) {
789                            if (preferApproved) {
790                                    page = wikiPagePersistence.fetchByN_T_S_First(
791                                            nodeId, title, WorkflowConstants.STATUS_APPROVED,
792                                            orderByComparator);
793                            }
794    
795                            if (page == null) {
796                                    page = wikiPagePersistence.fetchByN_T_First(
797                                            nodeId, title, orderByComparator);
798                            }
799                    }
800                    else {
801                            page = wikiPagePersistence.fetchByN_T_S_First(
802                                    nodeId, title, status, orderByComparator);
803                    }
804    
805                    return page;
806            }
807    
808            @Override
809            public WikiPage fetchPage(long nodeId, String title)
810                    throws SystemException {
811    
812                    return wikiPagePersistence.fetchByN_T_H_First(
813                            nodeId, title, true, null);
814            }
815    
816            @Override
817            public WikiPage fetchPage(long nodeId, String title, double version)
818                    throws SystemException {
819    
820                    if (version == 0) {
821                            return fetchPage(nodeId, title);
822                    }
823                    else {
824                            return wikiPagePersistence.fetchByN_T_V(nodeId, title, version);
825                    }
826            }
827    
828            @Override
829            public List<WikiPage> getChildren(
830                            long nodeId, boolean head, String parentTitle)
831                    throws SystemException {
832    
833                    return wikiPagePersistence.findByN_H_P_S(
834                            nodeId, head, parentTitle, WorkflowConstants.STATUS_APPROVED);
835            }
836    
837            @Override
838            public WikiPage getDraftPage(long nodeId, String title)
839                    throws PortalException, SystemException {
840    
841                    List<WikiPage> pages = wikiPagePersistence.findByN_T_S(
842                            nodeId, title, WorkflowConstants.STATUS_DRAFT, 0, 1);
843    
844                    if (!pages.isEmpty()) {
845                            return pages.get(0);
846                    }
847    
848                    pages = wikiPagePersistence.findByN_T_S(
849                            nodeId, title, WorkflowConstants.STATUS_PENDING, 0, 1);
850    
851                    if (!pages.isEmpty()) {
852                            return pages.get(0);
853                    }
854                    else {
855                            StringBundler sb = new StringBundler(5);
856    
857                            sb.append("{nodeId=");
858                            sb.append(nodeId);
859                            sb.append(", title=");
860                            sb.append(title);
861                            sb.append("}");
862    
863                            throw new NoSuchPageException(sb.toString());
864                    }
865            }
866    
867            @Override
868            public List<WikiPage> getIncomingLinks(long nodeId, String title)
869                    throws PortalException, SystemException {
870    
871                    List<WikiPage> links = new UniqueList<WikiPage>();
872    
873                    List<WikiPage> pages = wikiPagePersistence.findByN_H(nodeId, true);
874    
875                    for (WikiPage page : pages) {
876                            if (isLinkedTo(page, title)) {
877                                    links.add(page);
878                            }
879                    }
880    
881                    List<WikiPage> referrals = wikiPagePersistence.findByN_R(nodeId, title);
882    
883                    for (WikiPage referral : referrals) {
884                            for (WikiPage page : pages) {
885                                    if (isLinkedTo(page, referral.getTitle())) {
886                                            links.add(page);
887                                    }
888                            }
889                    }
890    
891                    return ListUtil.sort(links);
892            }
893    
894            @Override
895            public WikiPage getLatestPage(
896                            long resourcePrimKey, int status, boolean preferApproved)
897                    throws PortalException, SystemException {
898    
899                    WikiPage page = fetchLatestPage(
900                            resourcePrimKey, status, preferApproved);
901    
902                    if (page == null) {
903                            StringBundler sb = new StringBundler(5);
904    
905                            sb.append("{resourcePrimKey=");
906                            sb.append(resourcePrimKey);
907                            sb.append(", status=");
908                            sb.append(status);
909                            sb.append("}");
910    
911                            throw new NoSuchPageException(sb.toString());
912                    }
913    
914                    return page;
915            }
916    
917            @Override
918            public WikiPage getLatestPage(
919                            long resourcePrimKey, long nodeId, int status,
920                            boolean preferApproved)
921                    throws PortalException, SystemException {
922    
923                    WikiPage page = fetchLatestPage(
924                            resourcePrimKey, nodeId, status, preferApproved);
925    
926                    if (page == null) {
927                            StringBundler sb = new StringBundler(7);
928    
929                            sb.append("{resourcePrimKey=");
930                            sb.append(resourcePrimKey);
931                            sb.append(", nodeId=");
932                            sb.append(nodeId);
933                            sb.append(", status=");
934                            sb.append(status);
935                            sb.append("}");
936    
937                            throw new NoSuchPageException(sb.toString());
938                    }
939    
940                    return page;
941            }
942    
943            @Override
944            public WikiPage getLatestPage(
945                            long nodeId, String title, int status, boolean preferApproved)
946                    throws PortalException, SystemException {
947    
948                    WikiPage page = fetchLatestPage(nodeId, title, status, preferApproved);
949    
950                    if (page == null) {
951                            StringBundler sb = new StringBundler(7);
952    
953                            sb.append("{nodeId=");
954                            sb.append(nodeId);
955                            sb.append(", title=");
956                            sb.append(title);
957                            sb.append(", status=");
958                            sb.append(status);
959                            sb.append("}");
960    
961                            throw new NoSuchPageException(sb.toString());
962                    }
963    
964                    return page;
965            }
966    
967            @Override
968            public List<WikiPage> getNoAssetPages() throws SystemException {
969                    return wikiPageFinder.findByNoAssets();
970            }
971    
972            @Override
973            public List<WikiPage> getOrphans(long nodeId)
974                    throws PortalException, SystemException {
975    
976                    List<WikiPage> pages = wikiPagePersistence.findByN_H_S(
977                            nodeId, true, WorkflowConstants.STATUS_APPROVED);
978    
979                    return WikiUtil.filterOrphans(pages);
980            }
981    
982            @Override
983            public List<WikiPage> getOutgoingLinks(long nodeId, String title)
984                    throws PortalException, SystemException {
985    
986                    WikiPage page = getPage(nodeId, title);
987    
988                    Map<String, WikiPage> pages = new LinkedHashMap<String, WikiPage>();
989    
990                    Map<String, Boolean> links = WikiCacheUtil.getOutgoingLinks(page);
991    
992                    for (Map.Entry<String, Boolean> entry : links.entrySet()) {
993                            String curTitle = entry.getKey();
994                            Boolean exists = entry.getValue();
995    
996                            if (exists) {
997                                    WikiPage curPage = getPage(nodeId, curTitle);
998    
999                                    if (!pages.containsKey(curPage.getTitle())) {
1000                                            pages.put(curPage.getTitle(), curPage);
1001                                    }
1002                            }
1003                            else {
1004                                    WikiPageImpl newPage = new WikiPageImpl();
1005    
1006                                    newPage.setNew(true);
1007                                    newPage.setNodeId(nodeId);
1008                                    newPage.setTitle(curTitle);
1009    
1010                                    if (!pages.containsKey(curTitle)) {
1011                                            pages.put(curTitle, newPage);
1012                                    }
1013                            }
1014                    }
1015    
1016                    return ListUtil.fromMapValues(pages);
1017            }
1018    
1019            @Override
1020            public WikiPage getPage(long resourcePrimKey)
1021                    throws PortalException, SystemException {
1022    
1023                    return getPage(resourcePrimKey, Boolean.TRUE);
1024            }
1025    
1026            @Override
1027            public WikiPage getPage(long resourcePrimKey, Boolean head)
1028                    throws PortalException, SystemException {
1029    
1030                    WikiPageResource pageResource =
1031                            wikiPageResourceLocalService.getPageResource(resourcePrimKey);
1032    
1033                    return getPage(pageResource.getNodeId(), pageResource.getTitle(), head);
1034            }
1035    
1036            @Override
1037            public WikiPage getPage(long nodeId, String title)
1038                    throws PortalException, SystemException {
1039    
1040                    WikiPage page = fetchPage(nodeId, title);
1041    
1042                    if (page != null) {
1043                            return page;
1044                    }
1045                    else {
1046                            StringBundler sb = new StringBundler(5);
1047    
1048                            sb.append("{nodeId=");
1049                            sb.append(nodeId);
1050                            sb.append(", title=");
1051                            sb.append(title);
1052                            sb.append("}");
1053    
1054                            throw new NoSuchPageException(sb.toString());
1055                    }
1056            }
1057    
1058            @Override
1059            public WikiPage getPage(long nodeId, String title, Boolean head)
1060                    throws PortalException, SystemException {
1061    
1062                    List<WikiPage> pages;
1063    
1064                    if (head == null) {
1065                            pages = wikiPagePersistence.findByN_T(nodeId, title, 0, 1);
1066                    }
1067                    else {
1068                            pages = wikiPagePersistence.findByN_T_H(nodeId, title, head, 0, 1);
1069                    }
1070    
1071                    if (!pages.isEmpty()) {
1072                            return pages.get(0);
1073                    }
1074                    else {
1075                            StringBundler sb = new StringBundler(7);
1076    
1077                            sb.append("{nodeId=");
1078                            sb.append(nodeId);
1079                            sb.append(", title=");
1080                            sb.append(title);
1081                            sb.append(", head=");
1082                            sb.append(head);
1083                            sb.append("}");
1084    
1085                            throw new NoSuchPageException(sb.toString());
1086                    }
1087            }
1088    
1089            @Override
1090            public WikiPage getPage(long nodeId, String title, double version)
1091                    throws PortalException, SystemException {
1092    
1093                    WikiPage page = null;
1094    
1095                    if (version == 0) {
1096                            page = getPage(nodeId, title);
1097                    }
1098                    else {
1099                            page = wikiPagePersistence.findByN_T_V(nodeId, title, version);
1100                    }
1101    
1102                    return page;
1103            }
1104    
1105            @Override
1106            public WikiPage getPageByPageId(long pageId)
1107                    throws PortalException, SystemException {
1108    
1109                    return wikiPagePersistence.findByPrimaryKey(pageId);
1110            }
1111    
1112            @Override
1113            public WikiPageDisplay getPageDisplay(
1114                            long nodeId, String title, PortletURL viewPageURL,
1115                            PortletURL editPageURL, String attachmentURLPrefix)
1116                    throws PortalException, SystemException {
1117    
1118                    WikiPage page = getPage(nodeId, title);
1119    
1120                    return getPageDisplay(
1121                            page, viewPageURL, editPageURL, attachmentURLPrefix);
1122            }
1123    
1124            @Override
1125            public WikiPageDisplay getPageDisplay(
1126                            WikiPage page, PortletURL viewPageURL, PortletURL editPageURL,
1127                            String attachmentURLPrefix)
1128                    throws PortalException, SystemException {
1129    
1130                    String formattedContent = WikiUtil.convert(
1131                            page, viewPageURL, editPageURL, attachmentURLPrefix);
1132    
1133                    return new WikiPageDisplayImpl(
1134                            page.getUserId(), page.getNodeId(), page.getTitle(),
1135                            page.getVersion(), page.getContent(), formattedContent,
1136                            page.getFormat(), page.getHead(), page.getAttachmentsFileEntries());
1137            }
1138    
1139            @Override
1140            public List<WikiPage> getPages(
1141                            long nodeId, boolean head, int start, int end)
1142                    throws SystemException {
1143    
1144                    return getPages(
1145                            nodeId, head, start, end, new PageCreateDateComparator(false));
1146            }
1147    
1148            @Override
1149            public List<WikiPage> getPages(
1150                            long nodeId, boolean head, int status, int start, int end)
1151                    throws SystemException {
1152    
1153                    return getPages(
1154                            nodeId, head, status, start, end,
1155                            new PageCreateDateComparator(false));
1156            }
1157    
1158            @Override
1159            public List<WikiPage> getPages(
1160                            long nodeId, boolean head, int status, int start, int end,
1161                            OrderByComparator obc)
1162                    throws SystemException {
1163    
1164                    if (status == WorkflowConstants.STATUS_ANY) {
1165                            return wikiPagePersistence.findByN_H(nodeId, head, start, end, obc);
1166                    }
1167                    else {
1168                            return wikiPagePersistence.findByN_H_S(
1169                                    nodeId, head, status, start, end, obc);
1170                    }
1171            }
1172    
1173            @Override
1174            public List<WikiPage> getPages(
1175                            long nodeId, boolean head, int start, int end,
1176                            OrderByComparator obc)
1177                    throws SystemException {
1178    
1179                    return getPages(
1180                            nodeId, head, WorkflowConstants.STATUS_APPROVED, start, end, obc);
1181            }
1182    
1183            @Override
1184            public List<WikiPage> getPages(long nodeId, int start, int end)
1185                    throws SystemException {
1186    
1187                    return getPages(
1188                            nodeId, start, end, new PageCreateDateComparator(false));
1189            }
1190    
1191            @Override
1192            public List<WikiPage> getPages(
1193                            long nodeId, int start, int end, OrderByComparator obc)
1194                    throws SystemException {
1195    
1196                    return wikiPagePersistence.findByNodeId(nodeId, start, end, obc);
1197            }
1198    
1199            @Override
1200            public List<WikiPage> getPages(
1201                            long resourcePrimKey, long nodeId, int status)
1202                    throws SystemException {
1203    
1204                    return wikiPagePersistence.findByR_N_S(resourcePrimKey, nodeId, status);
1205            }
1206    
1207            @Override
1208            public List<WikiPage> getPages(
1209                            long userId, long nodeId, int status, int start, int end)
1210                    throws SystemException {
1211    
1212                    if (userId > 0) {
1213                            return wikiPagePersistence.findByU_N_S(
1214                                    userId, nodeId, status, start, end,
1215                                    new PageCreateDateComparator(false));
1216                    }
1217                    else {
1218                            return wikiPagePersistence.findByN_S(
1219                                    nodeId, status, start, end,
1220                                    new PageCreateDateComparator(false));
1221                    }
1222            }
1223    
1224            @Override
1225            public List<WikiPage> getPages(
1226                            long nodeId, String title, boolean head, int start, int end)
1227                    throws SystemException {
1228    
1229                    return wikiPagePersistence.findByN_T_H(
1230                            nodeId, title, head, start, end,
1231                            new PageCreateDateComparator(false));
1232            }
1233    
1234            @Override
1235            public List<WikiPage> getPages(
1236                            long nodeId, String title, int start, int end)
1237                    throws SystemException {
1238    
1239                    return wikiPagePersistence.findByN_T(
1240                            nodeId, title, start, end, new PageCreateDateComparator(false));
1241            }
1242    
1243            @Override
1244            public List<WikiPage> getPages(
1245                            long nodeId, String title, int start, int end,
1246                            OrderByComparator obc)
1247                    throws SystemException {
1248    
1249                    return wikiPagePersistence.findByN_T(nodeId, title, start, end, obc);
1250            }
1251    
1252            @Override
1253            public List<WikiPage> getPages(String format) throws SystemException {
1254                    return wikiPagePersistence.findByFormat(format);
1255            }
1256    
1257            @Override
1258            public int getPagesCount(long nodeId) throws SystemException {
1259                    return wikiPagePersistence.countByNodeId(nodeId);
1260            }
1261    
1262            @Override
1263            public int getPagesCount(long nodeId, boolean head) throws SystemException {
1264                    return wikiPagePersistence.countByN_H_S(
1265                            nodeId, head, WorkflowConstants.STATUS_APPROVED);
1266            }
1267    
1268            @Override
1269            public int getPagesCount(long nodeId, boolean head, int status)
1270                    throws SystemException {
1271    
1272                    if (status == WorkflowConstants.STATUS_ANY) {
1273                            return wikiPagePersistence.countByN_H_NotS(
1274                                    nodeId, head, WorkflowConstants.STATUS_IN_TRASH);
1275                    }
1276                    else {
1277                            return wikiPagePersistence.countByN_H_S(nodeId, head, status);
1278                    }
1279            }
1280    
1281            @Override
1282            public int getPagesCount(long nodeId, int status) throws SystemException {
1283                    return wikiPagePersistence.countByN_S(nodeId, status);
1284            }
1285    
1286            @Override
1287            public int getPagesCount(long userId, long nodeId, int status)
1288                    throws SystemException {
1289    
1290                    if (userId > 0) {
1291                            return wikiPagePersistence.countByU_N_S(userId, nodeId, status);
1292                    }
1293                    else {
1294                            return wikiPagePersistence.countByN_S(nodeId, status);
1295                    }
1296            }
1297    
1298            @Override
1299            public int getPagesCount(long nodeId, String title) throws SystemException {
1300                    return wikiPagePersistence.countByN_T(nodeId, title);
1301            }
1302    
1303            @Override
1304            public int getPagesCount(long nodeId, String title, boolean head)
1305                    throws SystemException {
1306    
1307                    return wikiPagePersistence.countByN_T_H(nodeId, title, head);
1308            }
1309    
1310            @Override
1311            public int getPagesCount(String format) throws SystemException {
1312                    return wikiPagePersistence.countByFormat(format);
1313            }
1314    
1315            /**
1316             * @deprecated As of 6.2.0, replaced by {@link #getRecentChanges(long, long,
1317             *             int, int)}
1318             */
1319            @Override
1320            public List<WikiPage> getRecentChanges(long nodeId, int start, int end)
1321                    throws PortalException, SystemException {
1322    
1323                    WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
1324    
1325                    return getRecentChanges(node.getGroupId(), nodeId, start, end);
1326            }
1327    
1328            @Override
1329            public List<WikiPage> getRecentChanges(
1330                            long groupId, long nodeId, int start, int end)
1331                    throws SystemException {
1332    
1333                    Calendar cal = CalendarFactoryUtil.getCalendar();
1334    
1335                    cal.add(Calendar.WEEK_OF_YEAR, -1);
1336    
1337                    return wikiPageFinder.findByCreateDate(
1338                            groupId, nodeId, cal.getTime(), false, start, end);
1339            }
1340    
1341            /**
1342             * @deprecated As of 6.2.0, replaced by {@link #getRecentChangesCount(long,
1343             *             long)}
1344             */
1345            @Override
1346            public int getRecentChangesCount(long nodeId)
1347                    throws PortalException, SystemException {
1348    
1349                    WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
1350    
1351                    return getRecentChangesCount(node.getGroupId(), nodeId);
1352            }
1353    
1354            @Override
1355            public int getRecentChangesCount(long groupId, long nodeId)
1356                    throws SystemException {
1357    
1358                    Calendar cal = CalendarFactoryUtil.getCalendar();
1359    
1360                    cal.add(Calendar.WEEK_OF_YEAR, -1);
1361    
1362                    return wikiPageFinder.countByCreateDate(
1363                            groupId, nodeId, cal.getTime(), false);
1364            }
1365    
1366            @Override
1367            public String[] getTempPageAttachmentNames(
1368                            long groupId, long userId, String tempFolderName)
1369                    throws PortalException, SystemException {
1370    
1371                    return TempFileUtil.getTempFileEntryNames(
1372                            groupId, userId, tempFolderName);
1373            }
1374    
1375            @Override
1376            public boolean hasDraftPage(long nodeId, String title)
1377                    throws SystemException {
1378    
1379                    int count = wikiPagePersistence.countByN_T_S(
1380                            nodeId, title, WorkflowConstants.STATUS_DRAFT);
1381    
1382                    if (count > 0) {
1383                            return true;
1384                    }
1385                    else {
1386                            return false;
1387                    }
1388            }
1389    
1390            @Override
1391            public void movePage(
1392                            long userId, long nodeId, String title, String newTitle,
1393                            boolean strict, ServiceContext serviceContext)
1394                    throws PortalException, SystemException {
1395    
1396                    validateTitle(newTitle);
1397    
1398                    // Check if the new title already exists
1399    
1400                    if (StringUtil.equalsIgnoreCase(title, newTitle)) {
1401                            throw new DuplicatePageException(newTitle);
1402                    }
1403    
1404                    if (isUsedTitle(nodeId, newTitle)) {
1405                            WikiPage page = getPage(nodeId, newTitle);
1406    
1407                            // Support moving back to a previously moved title
1408    
1409                            if (((page.getVersion() == WikiPageConstants.VERSION_DEFAULT) &&
1410                                     (page.getContent().length() < 200)) ||
1411                                    !strict) {
1412    
1413                                    deletePage(nodeId, newTitle);
1414                            }
1415                            else {
1416                                    throw new DuplicatePageException(newTitle);
1417                            }
1418                    }
1419    
1420                    // All versions
1421    
1422                    List<WikiPage> versionPages = wikiPagePersistence.findByN_T(
1423                            nodeId, title);
1424    
1425                    if (versionPages.size() == 0) {
1426                            return;
1427                    }
1428    
1429                    for (WikiPage page : versionPages) {
1430                            page.setTitle(newTitle);
1431    
1432                            wikiPagePersistence.update(page);
1433                    }
1434    
1435                    // Children
1436    
1437                    List<WikiPage> children = wikiPagePersistence.findByN_P(nodeId, title);
1438    
1439                    for (WikiPage page : children) {
1440                            page.setParentTitle(newTitle);
1441    
1442                            wikiPagePersistence.update(page);
1443                    }
1444    
1445                    WikiPage page = versionPages.get(versionPages.size() - 1);
1446    
1447                    long resourcePrimKey = page.getResourcePrimKey();
1448    
1449                    // Page resource
1450    
1451                    WikiPageResource pageResource =
1452                            wikiPageResourcePersistence.findByPrimaryKey(resourcePrimKey);
1453    
1454                    pageResource.setTitle(newTitle);
1455    
1456                    wikiPageResourcePersistence.update(pageResource);
1457    
1458                    // Create stub page at the old location
1459    
1460                    double version = WikiPageConstants.VERSION_DEFAULT;
1461                    String summary = WikiPageConstants.MOVED + " to " + newTitle;
1462                    String format = page.getFormat();
1463                    boolean head = true;
1464                    String parentTitle = page.getParentTitle();
1465                    String redirectTitle = page.getTitle();
1466                    String content =
1467                            StringPool.DOUBLE_OPEN_BRACKET + redirectTitle +
1468                                    StringPool.DOUBLE_CLOSE_BRACKET;
1469    
1470                    serviceContext.setAddGroupPermissions(true);
1471                    serviceContext.setAddGuestPermissions(true);
1472    
1473                    populateServiceContext(serviceContext, page);
1474    
1475                    addPage(
1476                            userId, nodeId, title, version, content, summary, false, format,
1477                            head, parentTitle, redirectTitle, serviceContext);
1478    
1479                    // Move redirects to point to the page with the new title
1480    
1481                    List<WikiPage> redirectedPages = wikiPagePersistence.findByN_R(
1482                            nodeId, title);
1483    
1484                    for (WikiPage redirectedPage : redirectedPages) {
1485                            redirectedPage.setRedirectTitle(newTitle);
1486    
1487                            wikiPagePersistence.update(redirectedPage);
1488                    }
1489    
1490                    // Asset
1491    
1492                    updateAsset(
1493                            userId, page, serviceContext.getAssetCategoryIds(),
1494                            serviceContext.getAssetTagNames(),
1495                            serviceContext.getAssetLinkEntryIds());
1496    
1497                    // Indexer
1498    
1499                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1500                            WikiPage.class);
1501    
1502                    indexer.delete(
1503                            new Object[] {page.getCompanyId(), page.getNodeId(), title});
1504    
1505                    indexer.reindex(page);
1506            }
1507    
1508            @Override
1509            public void movePage(
1510                            long userId, long nodeId, String title, String newTitle,
1511                            ServiceContext serviceContext)
1512                    throws PortalException, SystemException {
1513    
1514                    movePage(userId, nodeId, title, newTitle, true, serviceContext);
1515            }
1516    
1517            @Override
1518            public FileEntry movePageAttachmentToTrash(
1519                            long userId, long nodeId, String title, String fileName)
1520                    throws PortalException, SystemException {
1521    
1522                    WikiPage page = getPage(nodeId, title);
1523    
1524                    FileEntry fileEntry = PortletFileRepositoryUtil.getPortletFileEntry(
1525                            page.getGroupId(), page.getAttachmentsFolderId(), fileName);
1526    
1527                    fileEntry = PortletFileRepositoryUtil.movePortletFileEntryToTrash(
1528                            userId, fileEntry.getFileEntryId());
1529    
1530                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
1531    
1532                    extraDataJSONObject.put("fileEntryId", fileEntry.getFileEntryId());
1533                    extraDataJSONObject.put(
1534                            "fileEntryTitle", TrashUtil.getOriginalTitle(fileEntry.getTitle()));
1535                    extraDataJSONObject.put("title", page.getTitle());
1536                    extraDataJSONObject.put("version", page.getVersion());
1537    
1538                    socialActivityLocalService.addActivity(
1539                            userId, page.getGroupId(), WikiPage.class.getName(),
1540                            page.getResourcePrimKey(),
1541                            SocialActivityConstants.TYPE_MOVE_ATTACHMENT_TO_TRASH,
1542                            extraDataJSONObject.toString(), 0);
1543    
1544                    return fileEntry;
1545            }
1546    
1547            @Override
1548            public WikiPage movePageToTrash(long userId, long nodeId, String title)
1549                    throws PortalException, SystemException {
1550    
1551                    List<WikiPage> wikiPages = wikiPagePersistence.findByN_T_H(
1552                            nodeId, title, true, 0, 1);
1553    
1554                    if (!wikiPages.isEmpty()) {
1555                            return movePageToTrash(userId, wikiPages.get(0));
1556                    }
1557    
1558                    return null;
1559            }
1560    
1561            @Override
1562            public WikiPage movePageToTrash(
1563                            long userId, long nodeId, String title, double version)
1564                    throws PortalException, SystemException {
1565    
1566                    WikiPage page = wikiPagePersistence.findByN_T_V(nodeId, title, version);
1567    
1568                    return movePageToTrash(userId, page);
1569            }
1570    
1571            @Override
1572            public WikiPage movePageToTrash(long userId, WikiPage page)
1573                    throws PortalException, SystemException {
1574    
1575                    // Page
1576    
1577                    int oldStatus = page.getStatus();
1578                    String oldTitle = page.getTitle();
1579    
1580                    if (oldStatus == WorkflowConstants.STATUS_PENDING) {
1581                            page.setStatus(WorkflowConstants.STATUS_DRAFT);
1582    
1583                            wikiPagePersistence.update(page);
1584                    }
1585    
1586                    List<WikiPage> pageVersions = wikiPagePersistence.findByR_N_H(
1587                            page.getResourcePrimKey(), page.getNodeId(), false);
1588    
1589                    pageVersions = ListUtil.sort(pageVersions, new PageVersionComparator());
1590    
1591                    List<ObjectValuePair<Long, Integer>> pageVersionStatusOVPs =
1592                            new ArrayList<ObjectValuePair<Long, Integer>>();
1593    
1594                    if ((pageVersions != null) && !pageVersions.isEmpty()) {
1595                            pageVersionStatusOVPs = getPageVersionStatuses(pageVersions);
1596                    }
1597    
1598                    page = updateStatus(
1599                            userId, page, WorkflowConstants.STATUS_IN_TRASH,
1600                            new ServiceContext());
1601    
1602                    // Trash
1603    
1604                    WikiPageResource pageResource =
1605                            wikiPageResourcePersistence.fetchByPrimaryKey(
1606                                    page.getResourcePrimKey());
1607    
1608                    UnicodeProperties typeSettingsProperties = new UnicodeProperties();
1609    
1610                    typeSettingsProperties.put("title", page.getTitle());
1611    
1612                    TrashEntry trashEntry = trashEntryLocalService.addTrashEntry(
1613                            userId, page.getGroupId(), WikiPage.class.getName(),
1614                            page.getResourcePrimKey(), pageResource.getUuid(), null, oldStatus,
1615                            pageVersionStatusOVPs, typeSettingsProperties);
1616    
1617                    String trashTitle = TrashUtil.getTrashTitle(trashEntry.getEntryId());
1618    
1619                    for (WikiPage pageVersion : pageVersions) {
1620                            pageVersion.setTitle(trashTitle);
1621                            pageVersion.setStatus(WorkflowConstants.STATUS_IN_TRASH);
1622    
1623                            wikiPagePersistence.update(pageVersion);
1624                    }
1625    
1626                    pageResource.setTitle(trashTitle);
1627    
1628                    wikiPageResourcePersistence.update(pageResource);
1629    
1630                    page.setTitle(trashTitle);
1631    
1632                    wikiPagePersistence.update(page);
1633    
1634                    // Children
1635    
1636                    List<WikiPage> children = wikiPagePersistence.findByN_H_P(
1637                            page.getNodeId(), true, oldTitle);
1638    
1639                    for (WikiPage curPage : children) {
1640                            curPage.setParentTitle(trashTitle);
1641    
1642                            wikiPagePersistence.update(curPage);
1643    
1644                            if (!curPage.isInTrash()) {
1645                                    movePageToTrash(userId, curPage);
1646                            }
1647                    }
1648    
1649                    // Redirect Pages
1650    
1651                    List<WikiPage> redirectPages = wikiPagePersistence.findByN_H_R(
1652                            page.getNodeId(), true, oldTitle);
1653    
1654                    for (WikiPage curPage : redirectPages) {
1655                            curPage.setRedirectTitle(trashTitle);
1656    
1657                            wikiPagePersistence.update(curPage);
1658    
1659                            if (!curPage.isInTrash()) {
1660                                    movePageToTrash(userId, curPage);
1661                            }
1662                    }
1663    
1664                    // Asset
1665    
1666                    assetEntryLocalService.updateVisible(
1667                            WikiPage.class.getName(), page.getResourcePrimKey(), false);
1668    
1669                    // Social
1670    
1671                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
1672    
1673                    extraDataJSONObject.put(
1674                            "title", TrashUtil.getOriginalTitle(page.getTitle()));
1675                    extraDataJSONObject.put("version", page.getVersion());
1676    
1677                    socialActivityLocalService.addActivity(
1678                            userId, page.getGroupId(), WikiPage.class.getName(),
1679                            page.getResourcePrimKey(),
1680                            SocialActivityConstants.TYPE_MOVE_TO_TRASH,
1681                            extraDataJSONObject.toString(), 0);
1682    
1683                    if (!pageVersions.isEmpty()) {
1684                            Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1685                                    WikiPage.class);
1686    
1687                            for (WikiPage pageVersion : pageVersions) {
1688                                    indexer.reindex(pageVersion);
1689                            }
1690                    }
1691    
1692                    // Workflow
1693    
1694                    if (oldStatus == WorkflowConstants.STATUS_PENDING) {
1695                            workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
1696                                    page.getCompanyId(), page.getGroupId(),
1697                                    WikiPage.class.getName(), page.getPageId());
1698                    }
1699    
1700                    return page;
1701            }
1702    
1703            @Override
1704            public void restorePageAttachmentFromTrash(
1705                            long userId, long nodeId, String title, String fileName)
1706                    throws PortalException, SystemException {
1707    
1708                    WikiPage page = getPage(nodeId, title);
1709    
1710                    FileEntry fileEntry = PortletFileRepositoryUtil.getPortletFileEntry(
1711                            page.getGroupId(), page.getAttachmentsFolderId(), fileName);
1712    
1713                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
1714    
1715                    extraDataJSONObject.put("fileEntryId", fileEntry.getFileEntryId());
1716                    extraDataJSONObject.put("fileEntryTitle", TrashUtil.getOriginalTitle(
1717                            fileEntry.getTitle()));
1718                    extraDataJSONObject.put("title", page.getTitle());
1719                    extraDataJSONObject.put("version", page.getVersion());
1720    
1721                    PortletFileRepositoryUtil.restorePortletFileEntryFromTrash(
1722                            userId, fileEntry.getFileEntryId());
1723    
1724                    socialActivityLocalService.addActivity(
1725                            userId, page.getGroupId(), WikiPage.class.getName(),
1726                            page.getResourcePrimKey(),
1727                            SocialActivityConstants.TYPE_RESTORE_ATTACHMENT_FROM_TRASH,
1728                            extraDataJSONObject.toString(), 0);
1729            }
1730    
1731            @Override
1732            public void restorePageFromTrash(long userId, WikiPage page)
1733                    throws PortalException, SystemException {
1734    
1735                    String title = page.getTitle();
1736    
1737                    String originalTitle = TrashUtil.getOriginalTitle(title);
1738    
1739                    List<WikiPage> pageVersions = wikiPagePersistence.findByR_N_H(
1740                            page.getResourcePrimKey(), page.getNodeId(), false);
1741    
1742                    for (WikiPage pageVersion : pageVersions) {
1743                            pageVersion.setTitle(originalTitle);
1744    
1745                            wikiPagePersistence.update(pageVersion);
1746                    }
1747    
1748                    WikiPageResource pageResource =
1749                            wikiPageResourcePersistence.fetchByPrimaryKey(
1750                                    page.getResourcePrimKey());
1751    
1752                    pageResource.setTitle(originalTitle);
1753    
1754                    wikiPageResourcePersistence.update(pageResource);
1755    
1756                    page.setTitle(originalTitle);
1757    
1758                    WikiPage parentPage = page.getParentPage();
1759    
1760                    if ((parentPage != null) && parentPage.isInTrash()) {
1761                            page.setParentTitle(StringPool.BLANK);
1762                    }
1763    
1764                    WikiPage redirectPage = page.getRedirectPage();
1765    
1766                    if ((redirectPage != null) && redirectPage.isInTrash()) {
1767                            page.setRedirectTitle(StringPool.BLANK);
1768                    }
1769    
1770                    wikiPagePersistence.update(page);
1771    
1772                    TrashEntry trashEntry = trashEntryLocalService.getEntry(
1773                            WikiPage.class.getName(), page.getResourcePrimKey());
1774    
1775                    updateStatus(
1776                            userId, page, trashEntry.getStatus(), new ServiceContext());
1777    
1778                    // Children
1779    
1780                    List<WikiPage> children = wikiPagePersistence.findByN_H_P_S(
1781                            page.getNodeId(), true, title, WorkflowConstants.STATUS_IN_TRASH);
1782    
1783                    for (WikiPage curPage : children) {
1784                            curPage.setParentTitle(originalTitle);
1785    
1786                            wikiPagePersistence.update(curPage);
1787    
1788                            if (curPage.isInTrash()) {
1789                                    restorePageFromTrash(userId, curPage);
1790                            }
1791                    }
1792    
1793                    // Redirect Pages
1794    
1795                    List<WikiPage> redirectPages = wikiPagePersistence.findByN_H_R(
1796                            page.getNodeId(), true, title);
1797    
1798                    for (WikiPage curPage : redirectPages) {
1799                            curPage.setRedirectTitle(originalTitle);
1800    
1801                            wikiPagePersistence.update(curPage);
1802    
1803                            if (curPage.isInTrash()) {
1804                                    restorePageFromTrash(userId, curPage);
1805                            }
1806                    }
1807    
1808                    // Trash
1809    
1810                    List<TrashVersion> trashVersions = trashVersionLocalService.getVersions(
1811                            trashEntry.getEntryId());
1812    
1813                    for (TrashVersion trashVersion : trashVersions) {
1814                            WikiPage trashArticleVersion = wikiPagePersistence.findByPrimaryKey(
1815                                    trashVersion.getClassPK());
1816    
1817                            trashArticleVersion.setStatus(trashVersion.getStatus());
1818    
1819                            wikiPagePersistence.update(trashArticleVersion);
1820                    }
1821    
1822                    trashEntryLocalService.deleteEntry(
1823                            WikiPage.class.getName(), page.getResourcePrimKey());
1824    
1825                    // Social
1826    
1827                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
1828    
1829                    extraDataJSONObject.put("title", page.getTitle());
1830                    extraDataJSONObject.put("version", page.getVersion());
1831    
1832                    socialActivityLocalService.addActivity(
1833                            userId, page.getGroupId(), WikiPage.class.getName(),
1834                            page.getResourcePrimKey(),
1835                            SocialActivityConstants.TYPE_RESTORE_FROM_TRASH,
1836                            extraDataJSONObject.toString(), 0);
1837    
1838                    if (!pageVersions.isEmpty()) {
1839                            Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1840                                    WikiPage.class);
1841    
1842                            for (WikiPage pageVersion : pageVersions) {
1843                                    indexer.reindex(pageVersion);
1844                            }
1845                    }
1846            }
1847    
1848            @Override
1849            public WikiPage revertPage(
1850                            long userId, long nodeId, String title, double version,
1851                            ServiceContext serviceContext)
1852                    throws PortalException, SystemException {
1853    
1854                    WikiPage oldPage = getPage(nodeId, title, version);
1855    
1856                    populateServiceContext(serviceContext, oldPage);
1857    
1858                    return updatePage(
1859                            userId, nodeId, title, 0, oldPage.getContent(),
1860                            WikiPageConstants.REVERTED + " to " + version, false,
1861                            oldPage.getFormat(), getParentPageTitle(oldPage),
1862                            oldPage.getRedirectTitle(), serviceContext);
1863            }
1864    
1865            @Override
1866            public void subscribePage(long userId, long nodeId, String title)
1867                    throws PortalException, SystemException {
1868    
1869                    WikiPage page = getPage(nodeId, title);
1870    
1871                    subscriptionLocalService.addSubscription(
1872                            userId, page.getGroupId(), WikiPage.class.getName(),
1873                            page.getResourcePrimKey());
1874            }
1875    
1876            @Override
1877            public void unsubscribePage(long userId, long nodeId, String title)
1878                    throws PortalException, SystemException {
1879    
1880                    WikiPage page = getPage(nodeId, title);
1881    
1882                    subscriptionLocalService.deleteSubscription(
1883                            userId, WikiPage.class.getName(), page.getResourcePrimKey());
1884            }
1885    
1886            @Override
1887            public void updateAsset(
1888                            long userId, WikiPage page, long[] assetCategoryIds,
1889                            String[] assetTagNames, long[] assetLinkEntryIds)
1890                    throws PortalException, SystemException {
1891    
1892                    boolean addDraftAssetEntry = false;
1893    
1894                    if (!page.isApproved() &&
1895                            (page.getVersion() != WikiPageConstants.VERSION_DEFAULT)) {
1896    
1897                            int approvedPagesCount = wikiPagePersistence.countByN_T_S(
1898                                    page.getNodeId(), page.getTitle(),
1899                                    WorkflowConstants.STATUS_APPROVED);
1900    
1901                            if (approvedPagesCount > 0) {
1902                                    addDraftAssetEntry = true;
1903                            }
1904                    }
1905    
1906                    AssetEntry assetEntry = null;
1907    
1908                    if (addDraftAssetEntry) {
1909                            assetEntry = assetEntryLocalService.updateEntry(
1910                                    userId, page.getGroupId(), page.getCreateDate(),
1911                                    page.getModifiedDate(), WikiPage.class.getName(),
1912                                    page.getPrimaryKey(), page.getUuid(), 0, assetCategoryIds,
1913                                    assetTagNames, false, null, null, null, ContentTypes.TEXT_HTML,
1914                                    page.getTitle(), null, null, null, null, 0, 0, null, false);
1915                    }
1916                    else {
1917                            assetEntry = assetEntryLocalService.updateEntry(
1918                                    userId, page.getGroupId(), page.getCreateDate(),
1919                                    page.getModifiedDate(), WikiPage.class.getName(),
1920                                    page.getResourcePrimKey(), page.getUuid(), 0, assetCategoryIds,
1921                                    assetTagNames, page.isApproved(), null, null, null,
1922                                    ContentTypes.TEXT_HTML, page.getTitle(), null, null, null, null,
1923                                    0, 0, null, false);
1924                    }
1925    
1926                    assetLinkLocalService.updateLinks(
1927                            userId, assetEntry.getEntryId(), assetLinkEntryIds,
1928                            AssetLinkConstants.TYPE_RELATED);
1929            }
1930    
1931            @Override
1932            public WikiPage updatePage(
1933                            long userId, long nodeId, String title, double version,
1934                            String content, String summary, boolean minorEdit, String format,
1935                            String parentTitle, String redirectTitle,
1936                            ServiceContext serviceContext)
1937                    throws PortalException, SystemException {
1938    
1939                    // Page
1940    
1941                    User user = userPersistence.findByPrimaryKey(userId);
1942                    Date now = new Date();
1943    
1944                    WikiPage oldPage = null;
1945    
1946                    try {
1947                            oldPage = wikiPagePersistence.findByN_T_First(nodeId, title, null);
1948                    }
1949                    catch (NoSuchPageException nspe) {
1950                            return addPage(
1951                                    userId, nodeId, title, WikiPageConstants.VERSION_DEFAULT,
1952                                    content, summary, minorEdit, format, true, parentTitle,
1953                                    redirectTitle, serviceContext);
1954                    }
1955    
1956                    long pageId = 0;
1957    
1958                    if (oldPage.isApproved()) {
1959                            pageId = counterLocalService.increment();
1960                    }
1961                    else {
1962                            pageId = oldPage.getPageId();
1963                    }
1964    
1965                    content = SanitizerUtil.sanitize(
1966                            user.getCompanyId(), oldPage.getGroupId(), userId,
1967                            WikiPage.class.getName(), pageId, "text/" + format, content);
1968    
1969                    validate(nodeId, content, format);
1970    
1971                    double oldVersion = oldPage.getVersion();
1972    
1973                    if ((version > 0) && (version != oldVersion)) {
1974                            throw new PageVersionException();
1975                    }
1976    
1977                    serviceContext.validateModifiedDate(
1978                            oldPage, PageVersionException.class);
1979    
1980                    long resourcePrimKey =
1981                            wikiPageResourceLocalService.getPageResourcePrimKey(nodeId, title);
1982                    long groupId = oldPage.getGroupId();
1983    
1984                    WikiPage page = oldPage;
1985    
1986                    double newVersion = oldVersion;
1987    
1988                    if (oldPage.isApproved()) {
1989                            newVersion = MathUtil.format(oldVersion + 0.1, 1, 1);
1990    
1991                            page = wikiPagePersistence.create(pageId);
1992    
1993                            page.setUuid(serviceContext.getUuid());
1994                    }
1995    
1996                    page.setResourcePrimKey(resourcePrimKey);
1997                    page.setGroupId(groupId);
1998                    page.setCompanyId(user.getCompanyId());
1999                    page.setUserId(user.getUserId());
2000                    page.setUserName(user.getFullName());
2001                    page.setCreateDate(serviceContext.getModifiedDate(now));
2002                    page.setModifiedDate(serviceContext.getModifiedDate(now));
2003                    page.setNodeId(nodeId);
2004                    page.setTitle(title);
2005                    page.setVersion(newVersion);
2006                    page.setMinorEdit(minorEdit);
2007                    page.setContent(content);
2008    
2009                    if (oldPage.isPending()) {
2010                            page.setStatus(oldPage.getStatus());
2011                    }
2012                    else {
2013                            page.setStatus(WorkflowConstants.STATUS_DRAFT);
2014                    }
2015    
2016                    page.setSummary(summary);
2017                    page.setFormat(format);
2018    
2019                    if (Validator.isNotNull(parentTitle)) {
2020                            page.setParentTitle(parentTitle);
2021                    }
2022    
2023                    if (Validator.isNotNull(redirectTitle)) {
2024                            page.setRedirectTitle(redirectTitle);
2025                    }
2026    
2027                    page.setExpandoBridgeAttributes(serviceContext);
2028    
2029                    wikiPagePersistence.update(page);
2030    
2031                    // Node
2032    
2033                    WikiNode node = wikiNodePersistence.findByPrimaryKey(nodeId);
2034    
2035                    node.setLastPostDate(serviceContext.getModifiedDate(now));
2036    
2037                    wikiNodePersistence.update(node);
2038    
2039                    // Asset
2040    
2041                    updateAsset(
2042                            userId, page, serviceContext.getAssetCategoryIds(),
2043                            serviceContext.getAssetTagNames(),
2044                            serviceContext.getAssetLinkEntryIds());
2045    
2046                    // Social
2047    
2048                    if (!page.isMinorEdit() ||
2049                            PropsValues.WIKI_PAGE_MINOR_EDIT_ADD_SOCIAL_ACTIVITY) {
2050    
2051                            if (oldVersion == newVersion) {
2052                                    SocialActivity lastSocialActivity =
2053                                            socialActivityLocalService.fetchFirstActivity(
2054                                                    WikiPage.class.getName(), page.getResourcePrimKey(),
2055                                                    WikiActivityKeys.UPDATE_PAGE);
2056    
2057                                    if (lastSocialActivity != null) {
2058                                            lastSocialActivity.setCreateDate(now.getTime() + 1);
2059                                            lastSocialActivity.setUserId(serviceContext.getUserId());
2060    
2061                                            socialActivityPersistence.update(lastSocialActivity);
2062                                    }
2063                            }
2064                            else {
2065                                    JSONObject extraDataJSONObject =
2066                                            JSONFactoryUtil.createJSONObject();
2067    
2068                                    extraDataJSONObject.put("title", page.getTitle());
2069                                    extraDataJSONObject.put("version", page.getVersion());
2070    
2071                                    socialActivityLocalService.addActivity(
2072                                            userId, page.getGroupId(), WikiPage.class.getName(),
2073                                            page.getResourcePrimKey(), WikiActivityKeys.UPDATE_PAGE,
2074                                            extraDataJSONObject.toString(), 0);
2075                            }
2076                    }
2077    
2078                    // Workflow
2079    
2080                    WorkflowHandlerRegistryUtil.startWorkflowInstance(
2081                            user.getCompanyId(), page.getGroupId(), userId,
2082                            WikiPage.class.getName(), page.getPageId(), page, serviceContext);
2083    
2084                    return page;
2085            }
2086    
2087            @Override
2088            public WikiPage updateStatus(
2089                            long userId, long resourcePrimKey, int status,
2090                            ServiceContext serviceContext)
2091                    throws PortalException, SystemException {
2092    
2093                    WikiPageResource pageResource =
2094                            wikiPageResourceLocalService.getPageResource(resourcePrimKey);
2095    
2096                    List<WikiPage> pages = wikiPagePersistence.findByN_T(
2097                            pageResource.getNodeId(), pageResource.getTitle(), 0, 1,
2098                            new PageVersionComparator());
2099    
2100                    WikiPage page = null;
2101    
2102                    if (!pages.isEmpty()) {
2103                            page = pages.get(0);
2104                    }
2105                    else {
2106                            throw new NoSuchPageException(
2107                                    "{resourcePrimKey=" + resourcePrimKey + "}");
2108                    }
2109    
2110                    return updateStatus(userId, page, status, serviceContext);
2111            }
2112    
2113            @Override
2114            public WikiPage updateStatus(
2115                            long userId, WikiPage page, int status,
2116                            ServiceContext serviceContext)
2117                    throws PortalException, SystemException {
2118    
2119                    // Page
2120    
2121                    User user = userPersistence.findByPrimaryKey(userId);
2122                    WikiNode node = wikiNodePersistence.findByPrimaryKey(page.getNodeId());
2123    
2124                    Date now = new Date();
2125    
2126                    int oldStatus = page.getStatus();
2127    
2128                    page.setStatus(status);
2129                    page.setStatusByUserId(userId);
2130                    page.setStatusByUserName(user.getFullName());
2131                    page.setStatusDate(now);
2132    
2133                    wikiPagePersistence.update(page);
2134    
2135                    if (status == WorkflowConstants.STATUS_APPROVED) {
2136    
2137                            // Asset
2138    
2139                            if ((oldStatus != WorkflowConstants.STATUS_APPROVED) &&
2140                                    (page.getVersion() != WikiPageConstants.VERSION_DEFAULT)) {
2141    
2142                                    AssetEntry draftAssetEntry = assetEntryLocalService.fetchEntry(
2143                                            WikiPage.class.getName(), page.getPrimaryKey());
2144    
2145                                    if (draftAssetEntry != null) {
2146                                            long[] assetCategoryIds = draftAssetEntry.getCategoryIds();
2147                                            String[] assetTagNames = draftAssetEntry.getTagNames();
2148    
2149                                            List<AssetLink> assetLinks =
2150                                                    assetLinkLocalService.getDirectLinks(
2151                                                            draftAssetEntry.getEntryId(),
2152                                                            AssetLinkConstants.TYPE_RELATED);
2153    
2154                                            long[] assetLinkEntryIds = StringUtil.split(
2155                                                    ListUtil.toString(
2156                                                            assetLinks, AssetLink.ENTRY_ID2_ACCESSOR), 0L);
2157    
2158                                            AssetEntry assetEntry = assetEntryLocalService.updateEntry(
2159                                                    userId, page.getGroupId(), page.getCreateDate(),
2160                                                    page.getModifiedDate(), WikiPage.class.getName(),
2161                                                    page.getResourcePrimKey(), page.getUuid(), 0,
2162                                                    assetCategoryIds, assetTagNames, true, null, null, null,
2163                                                    ContentTypes.TEXT_HTML, page.getTitle(), null, null,
2164                                                    null, null, 0, 0, null, false);
2165    
2166                                            // Asset Links
2167    
2168                                            assetLinkLocalService.updateLinks(
2169                                                    userId, assetEntry.getEntryId(), assetLinkEntryIds,
2170                                                    AssetLinkConstants.TYPE_RELATED);
2171    
2172                                            SystemEventHierarchyEntryThreadLocal.push(WikiPage.class);
2173    
2174                                            try {
2175                                                    assetEntryLocalService.deleteEntry(
2176                                                            draftAssetEntry.getEntryId());
2177                                            }
2178                                            finally {
2179                                                    SystemEventHierarchyEntryThreadLocal.pop(
2180                                                            WikiPage.class);
2181                                            }
2182                                    }
2183                            }
2184    
2185                            assetEntryLocalService.updateVisible(
2186                                    WikiPage.class.getName(), page.getResourcePrimKey(), true);
2187    
2188                            // Social
2189    
2190                            if ((oldStatus != WorkflowConstants.STATUS_IN_TRASH) &&
2191                                    (page.getVersion() == WikiPageConstants.VERSION_DEFAULT) &&
2192                                    (!page.isMinorEdit() ||
2193                                     PropsValues.WIKI_PAGE_MINOR_EDIT_ADD_SOCIAL_ACTIVITY)) {
2194    
2195                                    JSONObject extraDataJSONObject =
2196                                            JSONFactoryUtil.createJSONObject();
2197    
2198                                    extraDataJSONObject.put("title", page.getTitle());
2199                                    extraDataJSONObject.put("version", page.getVersion());
2200    
2201                                    socialActivityLocalService.addActivity(
2202                                            userId, page.getGroupId(), WikiPage.class.getName(),
2203                                            page.getResourcePrimKey(), WikiActivityKeys.ADD_PAGE,
2204                                            extraDataJSONObject.toString(), 0);
2205                            }
2206    
2207                            // Subscriptions
2208    
2209                            if (NotificationThreadLocal.isEnabled() &&
2210                                    (!page.isMinorEdit() ||
2211                                     PropsValues.WIKI_PAGE_MINOR_EDIT_SEND_EMAIL)) {
2212    
2213                                    boolean update = false;
2214    
2215                                    if (page.getVersion() > WikiPageConstants.VERSION_DEFAULT) {
2216                                            update = true;
2217                                    }
2218    
2219                                    notifySubscribers(node, page, serviceContext, update);
2220                            }
2221    
2222                            // Cache
2223    
2224                            clearPageCache(page);
2225                    }
2226    
2227                    // Head
2228    
2229                    if (status == WorkflowConstants.STATUS_APPROVED) {
2230                            page.setHead(true);
2231    
2232                            List<WikiPage> pages = wikiPagePersistence.findByN_T_H(
2233                                    page.getNodeId(), page.getTitle(), true);
2234    
2235                            for (WikiPage curPage : pages) {
2236                                    if (!curPage.equals(page)) {
2237                                            curPage.setHead(false);
2238    
2239                                            wikiPagePersistence.update(curPage);
2240                                    }
2241                            }
2242                    }
2243                    else if (status != WorkflowConstants.STATUS_IN_TRASH) {
2244                            page.setHead(false);
2245    
2246                            List<WikiPage> pages = wikiPagePersistence.findByN_T_S(
2247                                    page.getNodeId(), page.getTitle(),
2248                                    WorkflowConstants.STATUS_APPROVED);
2249    
2250                            for (WikiPage curPage : pages) {
2251                                    if (!curPage.equals(page)) {
2252                                            curPage.setHead(true);
2253    
2254                                            wikiPagePersistence.update(curPage);
2255    
2256                                            break;
2257                                    }
2258                            }
2259                    }
2260    
2261                    // Indexer
2262    
2263                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
2264                            WikiPage.class);
2265    
2266                    indexer.reindex(page);
2267    
2268                    return wikiPagePersistence.update(page);
2269            }
2270    
2271            @Override
2272            public void validateTitle(String title) throws PortalException {
2273                    if (title.equals("all_pages") || title.equals("orphan_pages") ||
2274                            title.equals("recent_changes")) {
2275    
2276                            throw new PageTitleException(title + " is reserved");
2277                    }
2278    
2279                    if (Validator.isNotNull(PropsValues.WIKI_PAGE_TITLES_REGEXP)) {
2280                            Pattern pattern = Pattern.compile(
2281                                    PropsValues.WIKI_PAGE_TITLES_REGEXP);
2282    
2283                            Matcher matcher = pattern.matcher(title);
2284    
2285                            if (!matcher.matches()) {
2286                                    throw new PageTitleException();
2287                            }
2288                    }
2289            }
2290    
2291            protected void clearPageCache(WikiPage page) {
2292                    if (!WikiCacheThreadLocal.isClearCache()) {
2293                            return;
2294                    }
2295    
2296                    WikiCacheUtil.clearCache(page.getNodeId());
2297            }
2298    
2299            protected void deletePageAttachment(long fileEntryId)
2300                    throws PortalException, SystemException {
2301    
2302                    PortletFileRepositoryUtil.deletePortletFileEntry(fileEntryId);
2303            }
2304    
2305            protected String getDiffsURL(
2306                            WikiNode node, WikiPage page, WikiPage previousVersionPage,
2307                            ServiceContext serviceContext)
2308                    throws PortalException, SystemException {
2309    
2310                    if (previousVersionPage == null) {
2311                            return StringPool.BLANK;
2312                    }
2313    
2314                    HttpServletRequest request = serviceContext.getRequest();
2315    
2316                    if (request == null) {
2317                            return StringPool.BLANK;
2318                    }
2319    
2320                    String portletId = null;
2321                    long plid = LayoutConstants.DEFAULT_PLID;
2322                    String strutsAction = null;
2323    
2324                    if (serviceContext.getPlid() != LayoutConstants.DEFAULT_PLID) {
2325                            portletId = PortletKeys.WIKI;
2326                            plid = serviceContext.getPlid();
2327                            strutsAction = "/wiki/compare_versions";
2328                    }
2329                    else {
2330                            portletId = PortletKeys.WIKI_ADMIN;
2331                            plid = PortalUtil.getControlPanelPlid(
2332                                    serviceContext.getCompanyId());
2333                            strutsAction = "/wiki_admin/compare_versions";
2334                    }
2335    
2336                    PortletURL portletURL = PortletURLFactoryUtil.create(
2337                            request, portletId, plid, PortletRequest.RENDER_PHASE);
2338    
2339                    portletURL.setParameter("struts_action", strutsAction);
2340                    portletURL.setParameter("nodeId", String.valueOf(node.getNodeId()));
2341                    portletURL.setParameter("title", page.getTitle());
2342                    portletURL.setParameter(
2343                            "sourceVersion", String.valueOf(previousVersionPage.getVersion()));
2344                    portletURL.setParameter(
2345                            "targetVersion", String.valueOf(page.getVersion()));
2346                    portletURL.setParameter("type", "html");
2347    
2348                    return portletURL.toString();
2349            }
2350    
2351            protected String getPageURL(
2352                            WikiNode node, WikiPage page, ServiceContext serviceContext)
2353                    throws PortalException, SystemException {
2354    
2355                    HttpServletRequest request = serviceContext.getRequest();
2356    
2357                    if (request == null) {
2358                            return StringPool.BLANK;
2359                    }
2360    
2361                    String layoutFullURL = getLayoutURL(
2362                            node.getGroupId(), PortletKeys.WIKI, serviceContext);
2363    
2364                    if (Validator.isNotNull(layoutFullURL)) {
2365                            return layoutFullURL + Portal.FRIENDLY_URL_SEPARATOR + "wiki/" +
2366                                    node.getNodeId() + StringPool.SLASH +
2367                                            HttpUtil.encodeURL(WikiUtil.escapeName(page.getTitle()));
2368                    }
2369                    else {
2370                            long controlPanelPlid = PortalUtil.getControlPanelPlid(
2371                                    serviceContext.getCompanyId());
2372    
2373                            PortletURL portletURL = PortletURLFactoryUtil.create(
2374                                    request, PortletKeys.WIKI_ADMIN, controlPanelPlid,
2375                                    PortletRequest.RENDER_PHASE);
2376    
2377                            portletURL.setParameter(
2378                                    "struts_action", "/wiki_admin/view_page_activities");
2379                            portletURL.setParameter("nodeId", String.valueOf(node.getNodeId()));
2380                            portletURL.setParameter("title", page.getTitle());
2381    
2382                            return portletURL.toString();
2383                    }
2384            }
2385    
2386            protected List<ObjectValuePair<Long, Integer>> getPageVersionStatuses(
2387                    List<WikiPage> pages) {
2388    
2389                    List<ObjectValuePair<Long, Integer>> pageVersionStatusOVPs =
2390                            new ArrayList<ObjectValuePair<Long, Integer>>(pages.size());
2391    
2392                    for (WikiPage page : pages) {
2393                            int status = page.getStatus();
2394    
2395                            if (status == WorkflowConstants.STATUS_PENDING) {
2396                                    status = WorkflowConstants.STATUS_DRAFT;
2397                            }
2398    
2399                            ObjectValuePair<Long, Integer> pageVersionStatusOVP =
2400                                    new ObjectValuePair<Long, Integer>(page.getPageId(), status);
2401    
2402                            pageVersionStatusOVPs.add(pageVersionStatusOVP);
2403                    }
2404    
2405                    return pageVersionStatusOVPs;
2406            }
2407    
2408            protected String getParentPageTitle(WikiPage page) {
2409    
2410                    // LPS-4586
2411    
2412                    try {
2413                            WikiPage parentPage = getPage(
2414                                    page.getNodeId(), page.getParentTitle());
2415    
2416                            return parentPage.getTitle();
2417                    }
2418                    catch (Exception e) {
2419                            return null;
2420                    }
2421            }
2422    
2423            protected WikiPage getPreviousVersionPage(WikiPage page)
2424                    throws PortalException, SystemException {
2425    
2426                    double previousVersion = MathUtil.format(page.getVersion() - 0.1, 1, 1);
2427    
2428                    if (previousVersion < 1) {
2429                            return null;
2430                    }
2431    
2432                    return getPage(page.getNodeId(), page.getTitle(), previousVersion);
2433            }
2434    
2435            protected boolean isLinkedTo(WikiPage page, String targetTitle)
2436                    throws PortalException {
2437    
2438                    Map<String, Boolean> links = WikiCacheUtil.getOutgoingLinks(page);
2439    
2440                    Boolean link = links.get(StringUtil.toLowerCase(targetTitle));
2441    
2442                    if (link != null) {
2443                            return true;
2444                    }
2445                    else {
2446                            return false;
2447                    }
2448            }
2449    
2450            protected boolean isUsedTitle(long nodeId, String title)
2451                    throws SystemException {
2452    
2453                    if (getPagesCount(nodeId, title, true) > 0) {
2454                            return true;
2455                    }
2456                    else {
2457                            return false;
2458                    }
2459            }
2460    
2461            protected void notifySubscribers(
2462                            WikiNode node, WikiPage page, ServiceContext serviceContext,
2463                            boolean update)
2464                    throws PortalException, SystemException {
2465    
2466                    String layoutFullURL = serviceContext.getLayoutFullURL();
2467    
2468                    if (!page.isApproved() || Validator.isNull(layoutFullURL)) {
2469                            return;
2470                    }
2471    
2472                    PortletPreferences preferences = null;
2473    
2474                    String rootPortletId = serviceContext.getRootPortletId();
2475    
2476                    if (Validator.isNull(rootPortletId) ||
2477                            !rootPortletId.equals(PortletKeys.WIKI_DISPLAY)) {
2478    
2479                            preferences = ServiceContextUtil.getPortletPreferences(
2480                                    serviceContext);
2481                    }
2482    
2483                    if (preferences == null) {
2484                            preferences = portletPreferencesLocalService.getPreferences(
2485                                    node.getCompanyId(), node.getGroupId(),
2486                                    PortletKeys.PREFS_OWNER_TYPE_GROUP,
2487                                    PortletKeys.PREFS_PLID_SHARED, PortletKeys.WIKI_ADMIN, null);
2488                    }
2489    
2490                    if (!update && WikiUtil.getEmailPageAddedEnabled(preferences)) {
2491                    }
2492                    else if (update && WikiUtil.getEmailPageUpdatedEnabled(preferences)) {
2493                    }
2494                    else {
2495                            return;
2496                    }
2497    
2498                    String portalURL = serviceContext.getPortalURL();
2499    
2500                    WikiPage previousVersionPage = getPreviousVersionPage(page);
2501    
2502                    String attachmentURLPrefix = WikiUtil.getAttachmentURLPrefix(
2503                            serviceContext.getPathMain(), serviceContext.getPlid(),
2504                            page.getNodeId(), page.getTitle());
2505    
2506                    attachmentURLPrefix = portalURL + attachmentURLPrefix;
2507    
2508                    String pageDiffs = StringPool.BLANK;
2509    
2510                    try {
2511                            pageDiffs = WikiUtil.diffHtml(
2512                                    previousVersionPage, page, null, null, attachmentURLPrefix);
2513                    }
2514                    catch (Exception e) {
2515                    }
2516    
2517                    String pageContent = null;
2518    
2519                    if (Validator.equals(page.getFormat(), "creole")) {
2520                            pageContent = WikiUtil.convert(
2521                                    page, null, null, attachmentURLPrefix);
2522                    }
2523                    else {
2524                            pageContent = page.getContent();
2525                            pageContent = WikiUtil.processContent(pageContent);
2526                    }
2527    
2528                    String fromName = WikiUtil.getEmailFromName(
2529                            preferences, page.getCompanyId());
2530                    String fromAddress = WikiUtil.getEmailFromAddress(
2531                            preferences, page.getCompanyId());
2532    
2533                    String subject = null;
2534                    String body = null;
2535                    String signature = null;
2536    
2537                    if (update) {
2538                            subject = WikiUtil.getEmailPageUpdatedSubject(preferences);
2539                            body = WikiUtil.getEmailPageUpdatedBody(preferences);
2540                            signature = WikiUtil.getEmailPageUpdatedSignature(preferences);
2541                    }
2542                    else {
2543                            subject = WikiUtil.getEmailPageAddedSubject(preferences);
2544                            body = WikiUtil.getEmailPageAddedBody(preferences);
2545                            signature = WikiUtil.getEmailPageAddedSignature(preferences);
2546                    }
2547    
2548                    if (Validator.isNotNull(signature)) {
2549                            body += "\n" + signature;
2550                    }
2551    
2552                    SubscriptionSender subscriptionSender = new SubscriptionSender();
2553    
2554                    subscriptionSender.setBody(body);
2555                    subscriptionSender.setCompanyId(page.getCompanyId());
2556                    subscriptionSender.setContextAttributes(
2557                            "[$DIFFS_URL$]",
2558                            getDiffsURL(node, page, previousVersionPage, serviceContext),
2559                            "[$NODE_NAME$]", node.getName(), "[$PAGE_DATE_UPDATE$]",
2560                            page.getModifiedDate(), "[$PAGE_ID$]", page.getPageId(),
2561                            "[$PAGE_SUMMARY$]", page.getSummary(), "[$PAGE_TITLE$]",
2562                            page.getTitle(), "[$PAGE_URL$]",
2563                            getPageURL(node, page, serviceContext));
2564                    subscriptionSender.setContextAttribute(
2565                            "[$PAGE_CONTENT$]", pageContent, false);
2566                    subscriptionSender.setContextAttribute(
2567                            "[$PAGE_DIFFS$]", replaceStyles(pageDiffs), false);
2568                    subscriptionSender.setContextUserPrefix("PAGE");
2569                    subscriptionSender.setFrom(fromAddress, fromName);
2570                    subscriptionSender.setHtmlFormat(true);
2571                    subscriptionSender.setMailId(
2572                            "wiki_page", page.getNodeId(), page.getPageId());
2573                    subscriptionSender.setPortletId(PortletKeys.WIKI);
2574                    subscriptionSender.setReplyToAddress(fromAddress);
2575                    subscriptionSender.setScopeGroupId(node.getGroupId());
2576                    subscriptionSender.setServiceContext(serviceContext);
2577                    subscriptionSender.setSubject(subject);
2578                    subscriptionSender.setUserId(page.getUserId());
2579    
2580                    subscriptionSender.addPersistedSubscribers(
2581                            WikiNode.class.getName(), node.getNodeId());
2582                    subscriptionSender.addPersistedSubscribers(
2583                            WikiPage.class.getName(), page.getResourcePrimKey());
2584    
2585                    subscriptionSender.flushNotificationsAsync();
2586            }
2587    
2588            protected void populateServiceContext(
2589                            ServiceContext serviceContext, WikiPage page)
2590                    throws PortalException, SystemException {
2591    
2592                    long[] assetCategoryIds = assetCategoryLocalService.getCategoryIds(
2593                            WikiPage.class.getName(), page.getResourcePrimKey());
2594    
2595                    serviceContext.setAssetCategoryIds(assetCategoryIds);
2596    
2597                    AssetEntry assetEntry = assetEntryLocalService.getEntry(
2598                            WikiPage.class.getName(), page.getResourcePrimKey());
2599    
2600                    List<AssetLink> assetLinks = assetLinkLocalService.getLinks(
2601                            assetEntry.getEntryId());
2602    
2603                    long[] assetLinkEntryIds = StringUtil.split(
2604                            ListUtil.toString(assetLinks, AssetLink.ENTRY_ID2_ACCESSOR), 0L);
2605    
2606                    serviceContext.setAssetLinkEntryIds(assetLinkEntryIds);
2607    
2608                    String[] assetTagNames = assetTagLocalService.getTagNames(
2609                            WikiPage.class.getName(), page.getResourcePrimKey());
2610    
2611                    serviceContext.setAssetTagNames(assetTagNames);
2612    
2613                    ExpandoBridge expandoBridge = page.getExpandoBridge();
2614    
2615                    serviceContext.setExpandoBridgeAttributes(
2616                            expandoBridge.getAttributes());
2617            }
2618    
2619            protected String replaceStyles(String html) {
2620                    return StringUtil.replace(
2621                            html,
2622                            new String[] {
2623                                    "class=\"diff-html-added\"", "class=\"diff-html-removed\"",
2624                                    "class=\"diff-html-changed\"",
2625                                    "changeType=\"diff-added-image\"",
2626                                    "changeType=\"diff-removed-image\"",
2627                                    "changeType=\"diff-changed-image\""
2628                            },
2629                            new String[] {
2630                                    "style=\"background-color: #CFC;\"",
2631                                    "style=\"background-color: #FDC6C6; text-decoration: " +
2632                                            "line-through;\"",
2633                                    "style=\"border-bottom: 2px dotted blue;\"",
2634                                    "style=\"border: 10px solid #CFC;\"",
2635                                    "style=\"border: 10px solid #FDC6C6;\"",
2636                                    "style=\"border: 10px solid blue;\""
2637                            }
2638                    );
2639            }
2640    
2641            protected void validate(long nodeId, String content, String format)
2642                    throws PortalException {
2643    
2644                    if (!WikiUtil.validate(nodeId, content, format)) {
2645                            throw new PageContentException();
2646                    }
2647            }
2648    
2649            protected void validate(
2650                            String title, long nodeId, String content, String format)
2651                    throws PortalException, SystemException {
2652    
2653                    if (Validator.isNull(title)) {
2654                            throw new PageTitleException();
2655                    }
2656    
2657                    if (isUsedTitle(nodeId, title)) {
2658                            throw new DuplicatePageException("{nodeId=" + nodeId + "}");
2659                    }
2660    
2661                    validateTitle(title);
2662    
2663                    validate(nodeId, content, format);
2664            }
2665    
2666    }