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.Map;
020import java.util.Optional;
021
022import org.apache.solr.client.solrj.response.QueryResponse;
023import org.apache.solr.common.SolrDocumentList;
024import org.slf4j.LoggerFactory;
025
026import org.ametys.cms.search.SearchResult;
027import org.ametys.cms.search.SearchResults;
028import org.ametys.cms.search.SearchResultsIterable;
029import org.ametys.plugins.repository.AmetysObject;
030import org.ametys.plugins.repository.AmetysObjectIterable;
031import org.ametys.plugins.repository.AmetysObjectIterator;
032import org.ametys.plugins.repository.AmetysObjectResolver;
033
034/**
035 * Solr implementation of a {@link SearchResults}.
036 * @param <A> the actual type of {@link AmetysObject}s. 
037 */
038public class SolrSearchResults<A extends AmetysObject> implements SearchResults<A>
039{
040    
041    /** The solr query response */
042    protected QueryResponse _response;
043    
044    /** The Solr documents of the search response */
045    protected SolrDocumentList _docList;
046    
047    /** The AmetysObject resolver. */
048    protected AmetysObjectResolver _resolver;
049    
050    /** The facet results. */
051    protected Map<String, Map<String, Integer>> _facetResults;
052    
053    /**
054     * Build a SolrSearchResults object.
055     * @param response the solr search response.
056     * @param resolver The Ametys object resolver.
057     * @param facetResults The facet results.
058     */
059    public SolrSearchResults(QueryResponse response, AmetysObjectResolver resolver, Map<String, Map<String, Integer>> facetResults)
060    {
061        _response = response;
062        _docList = response.getResults();
063        _resolver = resolver;
064        _facetResults = facetResults;
065    }
066    
067    @Override
068    public SearchResultsIterable<SearchResult<A>> getResults()
069    {
070        return new SolrResponseIterable<>(_docList, _resolver);
071    }
072    
073    @Override
074    public AmetysObjectIterable<A> getObjects()
075    {
076        return new AmetysObjectIterable<>()
077        {
078            @Override
079            public long getSize()
080            {
081                return _docList.size();
082            }
083
084            @Override
085            public AmetysObjectIterator<A> iterator()
086            {
087                return new SolrResponseAmetysObjectIterator<>(_docList.iterator(), _docList.size(), _resolver, LoggerFactory.getLogger(SolrResponseAmetysObjectIterator.class));
088            }
089
090            @Override
091            public void close()
092            {
093                // Nothing to do.
094            }
095        };
096    }
097    
098    @Override
099    public Iterable<String> getObjectIds()
100    {
101        return new SolrResponseIdIterable(_docList);
102    }
103    
104    @Override
105    public Map<String, Map<String, Integer>> getFacetResults()
106    {
107        return Collections.unmodifiableMap(_facetResults);
108    }
109    
110    @Override
111    public long getTotalCount()
112    {
113        return _docList.getNumFound();
114    }
115    
116    @Override
117    public float getMaxScore()
118    {
119        return _docList.getMaxScore();
120    }
121    
122    @Override
123    public Optional<Map<String, Object>> getDebugMap()
124    {
125        return Optional.ofNullable(_response)
126                .map(QueryResponse::getDebugMap);
127    }
128}