/* Copyright (2006-2012) Schibsted ASA * This file is part of Possom. * * Possom is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Possom 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Possom. If not, see <http://www.gnu.org/licenses/>. * * MobileSearchCommand.java * * Created on March 10, 2006, 2:22 PM * */ package no.sesat.search.mode.command; import no.fast.ds.common.FastException; import no.fast.ds.search.BaseParameter; import no.fast.ds.search.IDocumentSummary; import no.fast.ds.search.IDocumentSummaryField; import no.fast.ds.search.IQuery; import no.fast.ds.search.IQueryResult; import no.fast.ds.search.ISearchParameters; import no.fast.ds.search.Query; import no.fast.ds.search.SearchParameter; import no.fast.ds.search.SearchParameters; import no.fast.msearch.Exception.ConfigurationException; import no.fast.msearch.search.DeviceCapabilitiesFactory; import no.fast.msearch.search.IDeviceCapabilities; import no.fast.msearch.search.IMSearchEngine; import no.fast.msearch.search.IMSearchFactory; import no.fast.msearch.search.IMSearchInfo; import no.fast.msearch.search.IMSearchResult; import no.fast.msearch.search.MSearchFactory; import no.fast.msearch.search.MSearchInfoFactory; import no.fast.personalization.api.ExplicitUserGroupPersonalizationFactory; import no.fast.personalization.api.IPersonalizationSpecification; import no.sesat.search.mode.config.MobileCommandConfig; import no.sesat.search.result.BasicResultList; import no.sesat.search.result.BasicResultItem; import java.io.IOException; import java.util.List; import java.util.Map; import no.sesat.search.result.ResultItem; import no.sesat.search.result.ResultList; import org.apache.log4j.Logger; /** * A search command that uses FAST's msearch API. * * * @version $Id$ */ public final class MobileSearchCommand extends AbstractSearchCommand { private static final Logger LOG = Logger.getLogger(MobileSearchCommand.class); private static final String PERSONALIZATION_GROUP = "aspiro-sesam1"; private static final String USER_AGENT_PARAMETER="ua"; private static final String MSEARCH_CLIENT_PROPS = "msearch-client.properties"; private static final String ORIGINATION_PARAMETER = "originator"; private final MobileCommandConfig cfg; public MobileSearchCommand(final Context cxt) { super(cxt); cfg = (MobileCommandConfig) cxt.getSearchConfiguration(); } public ResultList<ResultItem> execute() { try { final IMSearchFactory factory = MSearchFactory.newInstance(); final IMSearchEngine engine = factory.createSearchEngine(); final ISearchParameters params = new SearchParameters(); final IMSearchInfo searchInfo = MSearchInfoFactory.getMSearchInfo(); if (!cfg.getSortBy().equals("")) { params.setParameter(new SearchParameter(BaseParameter.SORT_BY, cfg.getSortBy())); } params.setParameter(new SearchParameter( BaseParameter.QUERY, getTransformedQuery())); params.setParameter(new SearchParameter( "offset", getOffset())); // BaseParameter.OFFSET not in Fast4 if (getParameter("msite") != null) { String filter = "+("; String [] arr = getParameter("msite").split(";"); for (int i=0;i<arr.length;i++){ filter = filter + " domain:" + arr[i]; } filter = filter + ")"; params.setParameter(new SearchParameter( BaseParameter.FILTER, filter )); } else { if (!cfg.getFilter().equals("")) { params.setParameter(new SearchParameter( BaseParameter.FILTER, cfg.getFilter())); } } final IDeviceCapabilities cap = getDeviceCapabilities(); String personalizationGroup = cfg.getPersonalizationGroup(); if ("telenor".equals(getParameter(ORIGINATION_PARAMETER)) && !cfg.getTelenorPersonalizationGroup().equals("")){ personalizationGroup = cfg.getTelenorPersonalizationGroup(); } final IPersonalizationSpecification ps = ExplicitUserGroupPersonalizationFactory.getUserGroupSpecification(personalizationGroup); final IQuery query = new Query(params); if (LOG.isDebugEnabled()) { LOG.debug("mSearch query is " + query); } final List<IMSearchResult> results = cap != null ? engine.search(query, ps, cap) : engine.search(query, ps); IMSearchResult mResult = null; for (final IMSearchResult r : results) { if (r.getSource().equals(cfg.getSource())) { mResult = r; break; } } final IQueryResult result = mResult.getResult(); final ResultList<ResultItem> searchResult = new BasicResultList<ResultItem>(); if( null != result ){ final int cnt = getOffset(); final int maxIndex = Math.min(cnt + cfg.getResultsToReturn(), result.getDocCount()); searchResult.setHitCount(result.getDocCount()); for (int i = cnt; i < maxIndex; i++) { //catch nullpointerException because of unaccurate doccount try { final IDocumentSummary document = result.getDocument(i + 1); final ResultItem item = createResultItem(document); searchResult.addResult(item); } catch (NullPointerException e) { return searchResult; } } }else{ LOG.error("IMSearchResult.getResult() returned null"); } return searchResult; } catch (ConfigurationException ex) { LOG.error(ex.getMessage()); return new BasicResultList<ResultItem>(); } catch (IOException ex) { throw new SearchCommandException(ex); } catch (FastException ex) { throw new SearchCommandException(ex); } } private IDeviceCapabilities getDeviceCapabilities() { IDeviceCapabilities cap = null; if (null != getParameter(USER_AGENT_PARAMETER)) { final String userAgent = (getParameter(USER_AGENT_PARAMETER)); cap = DeviceCapabilitiesFactory.getDeviceCapabilities(); cap.setUserAgent(userAgent); } return cap; } private ResultItem createResultItem(final IDocumentSummary document) { ResultItem item = new BasicResultItem(); for (final Map.Entry<String,String> entry : cfg.getResultFieldMap().entrySet()) { final IDocumentSummaryField summary = document.getSummaryField(entry.getKey()); if (summary != null) { item = item.addField(entry.getValue(), summary.getSummary()); } } return item; } private StringBuilder filterBuilder = null; @Override protected String getFilter() { synchronized (this) { if (filterBuilder == null) { filterBuilder = new StringBuilder(super.getFilter()); } } return filterBuilder.toString(); } }