DefaultWikiService.java
/*
* Copyright (C) 2003-2010 eXo Platform SAS.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see<http://www.gnu.org/licenses/>.
*/
package org.exoplatform.wiki.service.wysiwyg;
import org.apache.commons.lang.StringUtils;
import org.exoplatform.commons.utils.PageList;
import org.exoplatform.container.ExoContainerContext;
import org.exoplatform.container.PortalContainer;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.wiki.WikiException;
import org.exoplatform.wiki.mow.api.Page;
import org.exoplatform.wiki.mow.api.Wiki;
import org.exoplatform.wiki.mow.api.WikiType;
import org.exoplatform.wiki.resolver.TitleResolver;
import org.exoplatform.wiki.service.*;
import org.exoplatform.wiki.service.search.SearchResult;
import org.exoplatform.wiki.service.search.WikiSearchData;
import org.exoplatform.wiki.utils.Utils;
import org.xwiki.component.annotation.Component;
import org.xwiki.context.Execution;
import org.xwiki.gwt.wysiwyg.client.wiki.*;
import org.xwiki.gwt.wysiwyg.client.wiki.WikiService;
import org.xwiki.model.reference.DocumentReference;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@Component
public class DefaultWikiService implements WikiService {
/**
* Default Wiki logger to report errors correctly.
*/
private static Log log = ExoLogger.getLogger("wiki:GWTWikiService");
/** Execution context handler, needed for accessing the WikiContext. */
@Inject
private Execution execution;
/**
* The service used to create links.
*/
@Inject
private LinkService linkService;
/**
* The object used to convert between client and server entity reference.
*/
private final EntityReferenceConverter entityReferenceConverter = new EntityReferenceConverter();
private WikiContext getWikiContext() {
return (WikiContext) execution.getContext().getProperty(WikiContext.WIKICONTEXT);
}
/**
* {@inheritDoc}
*
* @see WikiService#isMultiWiki()
*/
@Override
public Boolean isMultiWiki() {
return false;
}
/**
* {@inheritDoc}
*
* @see WikiService#getVirtualWikiNames()
*/
@Override
public List<String> getVirtualWikiNames() {
List<String> virtualWikiNamesList = new ArrayList<String>();
return virtualWikiNamesList;
}
/**
* {@inheritDoc}
*
* @see WikiService#getSpaceNames(String)
*/
@Override
public List<String> getSpaceNames(String wikiType) {
List<String> spaceNames = new ArrayList<>();
org.exoplatform.wiki.service.WikiService wikiService = ExoContainerContext.getCurrentContainer()
.getComponentInstanceOfType(org.exoplatform.wiki.service.WikiService.class);
try {
Collection<Wiki> wikis = wikiService.getWikisByType(wikiType);
for (Wiki wiki : wikis) {
spaceNames.add(wiki.getOwner());
}
} catch(WikiException e) {
log.error("Cannot get space names - Cause : " + e.getMessage(), e);
}
return spaceNames;
}
/**
* {@inheritDoc}
*
* @see WikiService#getPageNames(String, String)
*/
@Override
public List<String> getPageNames(String wikiName, String spaceName) {
org.exoplatform.wiki.service.WikiService wservice = (org.exoplatform.wiki.service.WikiService) PortalContainer.getComponent(org.exoplatform.wiki.service.WikiService.class);
try {
WikiContext wikiContext = getWikiContext();
WikiSearchData data = new WikiSearchData("", null, wikiContext.getType(), wikiContext.getOwner());
PageList<SearchResult> results = wservice.search(data);
List<String> pagesNames = new ArrayList<String>();
if(results != null) {
List<DocumentReference> documentReferences = prepareDocumentReferenceList(results);
List<WikiPage> wikiPages = getWikiPages(documentReferences);
for (WikiPage page : wikiPages) {
String pageName = page.getTitle();
if (!pagesNames.contains(pageName)) {
pagesNames.add(pageName);
}
}
}
return pagesNames;
} catch (Exception e) {
log.error("Exception happened when list pages name", e);
throw new RuntimeException("Failed to list Wiki pages name.", e);
}
}
/**
* {@inheritDoc}
*
* @see WikiService#getRecentlyModifiedPages(String, int, int)
*/
public List<WikiPage> getRecentlyModifiedPages(String wikiName, int start, int count) {
WikiContext wikiContext = getWikiContext();
org.exoplatform.wiki.service.WikiService wservice =
(org.exoplatform.wiki.service.WikiService) PortalContainer.getComponent(org.exoplatform.wiki.service.WikiService.class);
// Create search condition by current user and recently
WikiSearchData data = new WikiSearchData(StringUtils.EMPTY, "*", wikiContext.getType(), wikiContext.getOwner());
// TODO add a property in the search data to get only recent pages
//data.addPropertyConstraint(String.format(" AND ( ( exo:lastModifier='%s' ) )",
// ConversationState.getCurrent().getIdentity().getUserId()));
data.setSort("exo:lastModifiedDate");
data.setOrder("DESC");
data.setLimit(count);
// Call wiki service to execute search
try {
PageList<SearchResult> results = wservice.search(data);
List<DocumentReference> documentReferences = prepareDocumentReferenceList(results);
return getWikiPages(documentReferences);
} catch (Exception e) {
log.error("Exception happened when searching pages", e);
throw new RuntimeException("Failed to search Wiki pages.", e);
}
}
/**
* {@inheritDoc}
*
* @see WikiService#getMatchingPages(String, String, int, int)
*/
public List<WikiPage> getMatchingPages(String wikiName, String keyword, int start, int count) {
String quote = "'";
String doubleQuote = "''";
String escapedKeyword = keyword.replaceAll(quote, doubleQuote).toLowerCase();
org.exoplatform.wiki.service.WikiService wservice = (org.exoplatform.wiki.service.WikiService) PortalContainer.getComponent(org.exoplatform.wiki.service.WikiService.class);
try {
WikiContext wikiContext = getWikiContext();
WikiSearchData data = new WikiSearchData(escapedKeyword, escapedKeyword, wikiContext.getType(), wikiContext.getOwner());
PageList<SearchResult> results = wservice.search(data);
List<DocumentReference> documentReferences = prepareDocumentReferenceList(results);
return getWikiPages(documentReferences);
} catch (Exception e) {
log.error("Exception happened when searching pages", e);
throw new RuntimeException("Failed to search Wiki pages.", e);
}
}
/**
* Helper function to create a list of {@link WikiPage}s from a list of
* document references.
*
* @param documentReferences a list of document references
* @return the list of {@link WikiPage}s corresponding to the given document
* references
* @throws Exception if anything goes wrong while creating the list of
* {@link WikiPage}s
*/
private List<WikiPage> getWikiPages(List<DocumentReference> documentReferences) throws Exception {
org.exoplatform.wiki.service.WikiService wservice = (org.exoplatform.wiki.service.WikiService) PortalContainer.getComponent(org.exoplatform.wiki.service.WikiService.class);
List<WikiPage> wikiPages = new ArrayList<>();
for (DocumentReference documentReference : documentReferences) {
WikiPage wikiPage = new WikiPage();
wikiPage.setReference(entityReferenceConverter.convert(documentReference).getEntityReference());
String pageId = documentReference.getName();
String wikiOwner = documentReference.getParent().getName();
String wikiType = documentReference.getParent().getParent().getName();
Page page = wservice.getPageByRootPermission(wikiType, wikiOwner, pageId);
wikiPage.setTitle(page.getTitle());
wikiPage.setUrl(pageId);
wikiPages.add(wikiPage);
}
return wikiPages;
}
/**
* {@inheritDoc}
*
* @see WikiService#getEntityConfig(org.xwiki.gwt.wysiwyg.client.wiki.EntityReference,
* ResourceReference)
*/
public EntityConfig getEntityConfig(org.xwiki.gwt.wysiwyg.client.wiki.EntityReference origin, ResourceReference destination) {
return linkService.getEntityConfig(origin, destination);
}
/**
* {@inheritDoc}
*
* @see WikiService#getAttachment(AttachmentReference)
*/
@Override
public Attachment getAttachment(AttachmentReference attachmentReference) {
// Clean attachment filename to be synchronized with all attachment operations.
String cleanedFileName = attachmentReference.getFileName();
cleanedFileName = Utils.escapeIllegalCharacterInName(cleanedFileName);
attachmentReference.setFileName(cleanedFileName);
WikiPageReference pageReference = attachmentReference.getWikiPageReference();
org.exoplatform.wiki.service.WikiService wservice = (org.exoplatform.wiki.service.WikiService) PortalContainer.getComponent(org.exoplatform.wiki.service.WikiService.class);
Page page;
try {
cleanedFileName = TitleResolver.getId(cleanedFileName, false);
page = wservice.getExsitedOrNewDraftPageById(pageReference.getWikiName(), pageReference.getSpaceName(), pageReference.getPageName());
if (page == null) {
return null;
}
org.exoplatform.wiki.mow.api.Attachment attachment = wservice.getAttachmentOfPageByName(cleanedFileName, page);
if (attachment == null) {
log.warn(String.format("Failed to get attachment: %s not found.", cleanedFileName));
return null;
}
Attachment attach = new Attachment();
attach.setReference(attachmentReference.getEntityReference());
attach.setUrl(attachment.getDownloadURL());
return attach;
} catch (Exception e) {
log.error("Failed to get attachment: there was a problem with getting the document on the server.", e);
return null;
}
}
/**
* {@inheritDoc}
*
* @see WikiService#getImageAttachments(WikiPageReference)
*/
public List<Attachment> getImageAttachments(WikiPageReference reference) {
List<Attachment> imageAttachments = new ArrayList<Attachment>();
List<Attachment> allAttachments = getAttachments(reference);
for (Attachment attachment : allAttachments) {
if (attachment.getMimeType().startsWith("image/")) {
imageAttachments.add(attachment);
}
}
return imageAttachments;
}
/**
* {@inheritDoc}
*
* @see WikiService#getAttachments(WikiPageReference)
*/
@Override
public List<Attachment> getAttachments(WikiPageReference documentReference) {
try {
String wikiName = documentReference.getWikiName();
String spaceName = documentReference.getSpaceName();
String pageName = documentReference.getPageName();
if (log.isTraceEnabled()) {
log.trace("Getting attachments of page : " + wikiName + "." + spaceName + "." + pageName);
}
List<Attachment> attachments = new ArrayList<Attachment>();
org.exoplatform.wiki.service.WikiService wservice = (org.exoplatform.wiki.service.WikiService) PortalContainer.getComponent(org.exoplatform.wiki.service.WikiService.class);
Page page = wservice.getExsitedOrNewDraftPageById(wikiName, spaceName, TitleResolver.getId(pageName, false));
List<org.exoplatform.wiki.mow.api.Attachment> attachs = wservice.getAttachmentsOfPage(page);
for (org.exoplatform.wiki.mow.api.Attachment attach : attachs) {
AttachmentReference attachmentReference = new AttachmentReference(attach.getName(), documentReference);
EntityReference entityReference = attachmentReference.getEntityReference();
entityReference.setType(org.xwiki.gwt.wysiwyg.client.wiki.EntityReference.EntityType.ATTACHMENT);
Attachment currentAttach = new Attachment();
currentAttach.setUrl(attach.getDownloadURL());
currentAttach.setReference(entityReference);
currentAttach.setMimeType(attach.getMimeType());
attachments.add(currentAttach);
}
return attachments;
} catch (Exception e) {
throw new RuntimeException("Failed to retrieve the list of attachments.", e);
}
}
/**
* {@inheritDoc}
*
* @see WikiService#getUploadURL(org.xwiki.gwt.wysiwyg.client.wiki.WikiPageReference)
*/
@Override
public String getUploadURL(WikiPageReference documentReference) {
StringBuilder sb = new StringBuilder();
sb.append("/").append(PortalContainer.getCurrentPortalContainerName()).append("/");
sb.append(PortalContainer.getCurrentRestContextName()).append("/wiki/upload/");
sb.append(documentReference.getWikiName()).append("/").append(documentReference.getSpaceName());
sb.append("/").append(documentReference.getPageName()).append("/");
return sb.toString();
}
/**
* {@inheritDoc}
*
* @see WikiService#parseLinkReference(String,
* org.xwiki.gwt.wysiwyg.client.wiki.EntityReference)
*/
public ResourceReference parseLinkReference(String linkReference, org.xwiki.gwt.wysiwyg.client.wiki.EntityReference baseReference) {
return linkService.parseLinkReference(linkReference, baseReference);
}
/**
* Helper function to prepare a list of {@link WikiPage} (with full name,
* title, etc) from a list of search results.
*
* @param results the list of the search results
* @return the list of {@link WikiPage}s corresponding to the passed names
* @throws Exception if anything goes wrong retrieving the documents
*/
private List<DocumentReference> prepareDocumentReferenceList(PageList<SearchResult> results) throws Exception {
List<DocumentReference> documentReferences = new ArrayList<DocumentReference>();
for (SearchResult result : results.getAll()) {
String nodeName = result.getPageName();
if (nodeName != null && nodeName.length() > 0 && nodeName.startsWith("/")) {
nodeName = nodeName.substring(1);
}
WikiContext wikiContext = getWikiContext();
log.info("Prepair DocumentReference : " + wikiContext.getType() + "@" + wikiContext.getOwner() + "@" + nodeName);
documentReferences.add(new DocumentReference(wikiContext.getType(), wikiContext.getOwner(), nodeName));
}
return documentReferences;
}
}