WikiSearchServiceConnector.java
package org.exoplatform.wiki.service.impl;
import org.apache.commons.lang.StringUtils;
import org.exoplatform.commons.api.search.SearchServiceConnector;
import org.exoplatform.commons.api.search.data.SearchContext;
import org.exoplatform.commons.api.search.data.SearchResult;
import org.exoplatform.commons.utils.PageList;
import org.exoplatform.container.ExoContainerContext;
import org.exoplatform.container.xml.InitParams;
import org.exoplatform.portal.config.model.PortalConfig;
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.service.WikiService;
import org.exoplatform.wiki.service.search.WikiSearchData;
import org.exoplatform.wiki.utils.Utils;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* Provides a connector service for the unified search.
* It implements a direct search in the JCR based on several criteria.
*
* @LevelAPI Experimental
*/
public class WikiSearchServiceConnector extends SearchServiceConnector {
private static final Log LOG = ExoLogger.getLogger("org.exoplatform.wiki.service.impl.WikiSearchServiceConnector");
/**
* URL pointing to the icon representing the wiki pages in the unified search results.
*/
public static final String WIKI_PAGE_ICON = "/eXoSkin/skin/images/system/unified-search/PageIcon.png";
/**
* Date and time format used in the unified search.
*/
public static String DATE_TIME_FORMAT = "EEEEE, MMMMMMMM d, yyyy K:mm a";
private WikiService wikiService;
/**
* Initializes the Wiki search service.
*
* @param initParams The params object which is used for initializing the Wiki search service.
*/
public WikiSearchServiceConnector(InitParams initParams) {
super(initParams);
wikiService = ExoContainerContext.getCurrentContainer().getComponentInstanceOfType(WikiService.class);
}
/**
* Implements the search method by given criteria.
*
* @param context The search context.
* @param query The query statement.
* @param sites Specified sites where the search is performed (for example Acme, or Intranet).
* @param offset The start point from which the search results are returned.
* @param limit The limitation number of search results.
* @param sort The sorting criteria (title, relevancy and date).
* @param order The sorting order (ascending and descending).
* @return Search results.
*/
@Override
public Collection<SearchResult> search(SearchContext context, String query, Collection<String> sites, int offset, int limit, String sort, String order) {
// When limit is 0 then return all search result
if (limit == 0) {
limit = Integer.MAX_VALUE;
}
// Prepare search data
WikiSearchData searchData = new WikiSearchData(query, query, null, null);
searchData.setOffset(offset);
searchData.setLimit(limit);
// Execute the search
List<SearchResult> searchResults = new ArrayList<SearchResult>();
try {
PageList<org.exoplatform.wiki.service.search.SearchResult> wikiSearchPageList = wikiService.search(searchData);
if (wikiSearchPageList != null) {
List<org.exoplatform.wiki.service.search.SearchResult> wikiSearchResults = wikiSearchPageList.getAll();
for (org.exoplatform.wiki.service.search.SearchResult wikiSearchResult : wikiSearchResults) {
SearchResult searchResult = buildResult(context, wikiSearchResult);
if (searchResult != null) {
searchResults.add(searchResult);
}
}
}
} catch (Exception e) {
LOG.info("Could not execute unified seach on wiki" , e) ;
}
// Sort search result
sortSearchResult(searchResults, sort, order);
// Return the result
return searchResults;
}
/**
* Sorts search results by order and sorting criteria.
*
* @param searchResults The list of search results.
* @param sort The sorting criteria, including title, relevancy and date.
* @param order The sorting order, including ascending and descending.
*/
private void sortSearchResult(List<SearchResult> searchResults, String sort, String order) {
if (StringUtils.isEmpty(sort)) {
return;
}
if (StringUtils.isEmpty(order)) {
order = "ASC";
}
final String orderValue = order;
if ("title".equalsIgnoreCase(sort)) {
Collections.sort(searchResults, new Comparator<SearchResult>() {
@Override
public int compare(SearchResult o1, SearchResult o2) {
if ("ASC".equalsIgnoreCase(orderValue)) {
return o1.getTitle().compareTo(o2.getTitle());
}
return o2.getTitle().compareTo(o1.getTitle());
}
});
} else if ("relevancy".equalsIgnoreCase(sort)) {
Collections.sort(searchResults, new Comparator<SearchResult>() {
@Override
public int compare(SearchResult o1, SearchResult o2) {
if ("ASC".equalsIgnoreCase(orderValue)) {
return Long.valueOf(o1.getRelevancy()).compareTo(Long.valueOf(o2.getRelevancy()));
}
return Long.valueOf(o2.getRelevancy()).compareTo(Long.valueOf(o1.getRelevancy()));
}
});
} else if ("date".equalsIgnoreCase(sort)) {
Collections.sort(searchResults, new Comparator<SearchResult>() {
@Override
public int compare(SearchResult o1, SearchResult o2) {
if ("ASC".equalsIgnoreCase(orderValue)) {
return Long.valueOf(o1.getDate()).compareTo(Long.valueOf(o2.getDate()));
}
return Long.valueOf(o2.getDate()).compareTo(Long.valueOf(o1.getDate()));
}
});
}
}
/**
* Gets an URL to the icon representing the wiki pages.
*
* @param wikiSearchResult The search result of Wiki.
* @return The icon URL.
* @return URL of the icon.
*/
private String getResultIcon(org.exoplatform.wiki.service.search.SearchResult wikiSearchResult) {
return WIKI_PAGE_ICON;
}
/**
* Gets a wiki page by a given search result.
*
* @param result The search result of Wiki.
* @return The wiki page.
* @throws Exception
*/
private Page getPage(org.exoplatform.wiki.service.search.SearchResult result) throws Exception {
return wikiService.getPageOfWikiByName(result.getWikiType(), result.getWikiOwner(), result.getPageName());
}
/**
* Gets a string which represents the wiki page containing the search result.
*
* The string format is: <b>PageOwner - UpdateDate</b>.
*
* @param wikiSearchResult The search result of Wiki.
* @return The string.
*/
private String getPageDetail(org.exoplatform.wiki.service.search.SearchResult wikiSearchResult) {
StringBuffer pageDetail = new StringBuffer();
try {
// Get space name
Page page = getPage(wikiSearchResult);
String spaceName;
Wiki wiki = wikiService.getWikiByTypeAndOwner(page.getWikiType(), page.getWikiOwner());
if (wiki.getType().equals(PortalConfig.GROUP_TYPE)) {
String wikiOwner = wiki.getOwner();
if (wikiOwner.indexOf('/') == -1) {
spaceName = wikiService.getSpaceNameByGroupId("/spaces/" + wiki.getOwner());
} else {
spaceName = wikiService.getSpaceNameByGroupId(wiki.getOwner());
}
} else {
spaceName = wiki.getOwner();
}
// Get update date
Calendar updateDate = wikiSearchResult.getUpdatedDate();
SimpleDateFormat format = new SimpleDateFormat(DATE_TIME_FORMAT);
// Build page detail
pageDetail.append(spaceName);
pageDetail.append(" - ");
pageDetail.append(format.format(updateDate.getTime()));
} catch (Exception e) {
LOG.info("Can not get page detail ", e);
}
return pageDetail.toString();
}
/**
* Gets a permalink of the wiki page by a given search result.
*
* @param context The search context.
* @param wikiSearchResult The search result of Wiki.
* @return The wiki page permalink.
*/
private String getPagePermalink(SearchContext context, org.exoplatform.wiki.service.search.SearchResult wikiSearchResult) {
StringBuffer permalink = new StringBuffer();
try {
Page page = getPage(wikiSearchResult);
Wiki wiki = wikiService.getWikiByTypeAndOwner(page.getWikiType(), page.getWikiOwner());
if (wiki.getType().equalsIgnoreCase(WikiType.GROUP.toString())) {
String portalContainerName = Utils.getPortalName();
String portalOwner = context.getSiteName();
String wikiWebappUri = wikiService.getWikiWebappUri();
String spaceGroupId = wiki.getOwner();
permalink.append("/");
permalink.append(portalContainerName);
permalink.append("/");
permalink.append(portalOwner);
permalink.append("/");
permalink.append(wikiWebappUri);
permalink.append("/");
permalink.append(PortalConfig.GROUP_TYPE);
permalink.append(spaceGroupId);
permalink.append("/");
permalink.append(page.getName());
} else {
String portalContainerName = Utils.getPortalName();
String url = page.getUrl();
if (url != null) {
url = url.substring(url.indexOf("/" + portalContainerName + "/"));
permalink.append(url);
}
}
} catch (Exception ex) {
LOG.info("Can not build the permalink for wiki page ", ex);
}
return permalink.toString();
}
/**
* Formats a search result which is used for the unified search.
*
* @param context The context URL.
* @param wikiSearchResult The search result of Wiki.
* @return The formated search result.
*/
private SearchResult buildResult(SearchContext context, org.exoplatform.wiki.service.search.SearchResult wikiSearchResult) {
try {
String title = wikiSearchResult.getTitle();
String url = getPagePermalink(context, wikiSearchResult);
String excerpt = wikiSearchResult.getExcerpt();
String detail = getPageDetail(wikiSearchResult);
long relevancy = wikiSearchResult.getScore();
long date = wikiSearchResult.getUpdatedDate().getTime().getTime();
String imageUrl = getResultIcon(wikiSearchResult);
return new SearchResult(url, title, excerpt, detail, imageUrl, date, relevancy);
} catch (Exception e) {
LOG.info("Error when getting property from node ", e);
return null;
}
}
}