/*
* 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 java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.exoplatform.commons.utils.PageList;
import org.exoplatform.container.PortalContainer;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
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.mow.core.api.wiki.AttachmentImpl;
import org.exoplatform.wiki.mow.core.api.wiki.PageImpl;
import org.exoplatform.wiki.resolver.TitleResolver;
import org.exoplatform.wiki.service.WikiContext;
import org.exoplatform.wiki.service.search.WikiSearchData;
import org.exoplatform.wiki.service.search.SearchResult;
import org.exoplatform.wiki.utils.Utils;
import org.xwiki.component.annotation.Component;
import org.xwiki.component.annotation.Requirement;
import org.xwiki.context.Execution;
import org.xwiki.gwt.wysiwyg.client.wiki.Attachment;
import org.xwiki.gwt.wysiwyg.client.wiki.AttachmentReference;
import org.xwiki.gwt.wysiwyg.client.wiki.EntityConfig;
import org.xwiki.gwt.wysiwyg.client.wiki.EntityReference;
import org.xwiki.gwt.wysiwyg.client.wiki.ResourceReference;
import org.xwiki.gwt.wysiwyg.client.wiki.WikiPage;
import org.xwiki.gwt.wysiwyg.client.wiki.WikiPageReference;
import org.xwiki.gwt.wysiwyg.client.wiki.WikiService;
import org.xwiki.model.reference.DocumentReference;
/**
* Created by The eXo Platform SAS
* Author : viet nguyen
* viet.nguyen@exoplatform.com
* Jun 24, 2010
*/
@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. */
@Requirement
private Execution execution;
/**
* The service used to create links.
*/
@Requirement
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 wikiName) {
List<String> spaceNames = new ArrayList<String>();
Collection<Wiki> wikis = Utils.getWikisByType(WikiType.valueOf(wikiName.toUpperCase()));
for (Wiki wiki : wikis) {
spaceNames.add(wiki.getOwner());
}
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,
"",
null,
wikiContext.getType(),
wikiContext.getOwner());
PageList<SearchResult> results = wservice.search(data);
List<DocumentReference> documentReferences = prepareDocumentReferenceList(results);
List<WikiPage> wikiPages = getWikiPages(documentReferences);
List<String> pagesNames = new ArrayList<String>();
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(int, int)
*/
public List<WikiPage> getRecentlyModifiedPages(int start, int count) {
// TODO: implement wiki search service by author and sort by date to get
// recently modified pages
return new ArrayList<WikiPage>();
}
/**
* {@inheritDoc}
*
* @see WikiService#getMatchingPages(String, int, int)
*/
public List<WikiPage> getMatchingPages(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(null,
escapedKeyword,
null,
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<WikiPage>();
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();
PageImpl page = (PageImpl) wservice.getPageById(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();
WikiPageReference pageReference = attachmentReference.getWikiPageReference();
org.exoplatform.wiki.service.WikiService wservice = (org.exoplatform.wiki.service.WikiService) PortalContainer.getComponent(org.exoplatform.wiki.service.WikiService.class);
PageImpl page;
try {
cleanedFileName = TitleResolver.getId(cleanedFileName, false);
page = (PageImpl) wservice.getExsitedOrNewDraftPageById(pageReference.getWikiName(),
pageReference.getSpaceName(),
pageReference.getPageName());
if (page == null) {
return null;
}
if (page.getAttachment(cleanedFileName) == 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(page.getAttachment(cleanedFileName).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));
Collection<AttachmentImpl> attachs = ((PageImpl) page).getAttachmentsExcludeContent();
for (AttachmentImpl 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.getContentResource().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.EntityReference)
*/
@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;
}
}