001/*
002 *  Copyright 2014 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.cms.search.solr;
017
018import java.util.Collections;
019import java.util.List;
020import java.util.Map;
021import java.util.Optional;
022
023import org.apache.solr.client.solrj.response.QueryResponse;
024import org.apache.solr.common.SolrDocumentList;
025import org.slf4j.LoggerFactory;
026
027import org.ametys.cms.search.SearchResult;
028import org.ametys.cms.search.SearchResults;
029import org.ametys.cms.search.SearchResultsIterable;
030import org.ametys.plugins.repository.AmetysObject;
031import org.ametys.plugins.repository.AmetysObjectIterable;
032import org.ametys.plugins.repository.AmetysObjectIterator;
033import org.ametys.plugins.repository.AmetysObjectResolver;
034
035/**
036 * Solr implementation of a {@link SearchResults}.
037 * @param <A> the actual type of {@link AmetysObject}s.
038 */
039public class SolrSearchResults<A extends AmetysObject> implements SearchResults<A>
040{
041    
042    /** The solr query response */
043    protected QueryResponse _response;
044    
045    /** The Solr documents of the search response */
046    protected SolrDocumentList _docList;
047    
048    /** The AmetysObject resolver. */
049    protected AmetysObjectResolver _resolver;
050    
051    /** The facet results. */
052    protected Map<String, Map<String, Integer>> _facetResults;
053    
054    /**
055     * Build a SolrSearchResults object.
056     * @param response the solr search response.
057     * @param resolver The Ametys object resolver.
058     * @param facetResults The facet results.
059     */
060    public SolrSearchResults(QueryResponse response, AmetysObjectResolver resolver, Map<String, Map<String, Integer>> facetResults)
061    {
062        _response = response;
063        _docList = response.getResults();
064        _resolver = resolver;
065        _facetResults = facetResults;
066    }
067    
068    @Override
069    public SearchResultsIterable<SearchResult<A>> getResults()
070    {
071        return new SolrResponseIterable<>(_docList, _resolver);
072    }
073    
074    @Override
075    public AmetysObjectIterable<A> getObjects()
076    {
077        return new AmetysObjectIterable<>()
078        {
079            @Override
080            public long getSize()
081            {
082                return _docList.size();
083            }
084
085            @Override
086            public AmetysObjectIterator<A> iterator()
087            {
088                return new SolrResponseAmetysObjectIterator<>(_docList.iterator(), _docList.size(), _resolver, LoggerFactory.getLogger(SolrResponseAmetysObjectIterator.class));
089            }
090
091            @Override
092            public void close()
093            {
094                // Nothing to do.
095            }
096        };
097    }
098    
099    @Override
100    public Iterable<String> getObjectIds()
101    {
102        return new SolrResponseIdIterable(_docList);
103    }
104    
105    @Override
106    public Map<String, Map<String, Integer>> getFacetResults()
107    {
108        return Collections.unmodifiableMap(_facetResults);
109    }
110    
111    @Override
112    public long getTotalCount()
113    {
114        return _docList.getNumFound();
115    }
116    
117    @Override
118    public float getMaxScore()
119    {
120        return _docList.getMaxScore();
121    }
122    
123    @Override
124    public Optional<Map<String, Object>> getDebugMap()
125    {
126        return Optional.ofNullable(_response)
127                .map(QueryResponse::getDebugMap);
128    }
129    
130    public Map<String, Map<String, List<String>>> getHighlighting()
131    {
132        return _response.getHighlighting();
133    }
134}