/* * 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; } }