/* * Copyright 2012 - 2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.data.solr.core.query.result; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.data.solr.core.query.Field; import org.springframework.data.solr.core.query.Function; import org.springframework.data.solr.core.query.PivotField; import org.springframework.data.solr.core.query.Query; import org.springframework.data.solr.core.query.SimpleField; import org.springframework.data.solr.core.query.SimplePivotField; import org.springframework.data.solr.core.query.result.HighlightEntry.Highlight; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; /** * Base implementation of page holding solr response entities. * * @author Christoph Strobl * @author Francisco Spaeth * @author David Webb * @author Petar Tahchiev */ public class SolrResultPage<T> extends PageImpl<T> implements FacetPage<T>, HighlightPage<T>, FacetAndHighlightPage<T>, ScoredPage<T>, GroupPage<T>, StatsPage<T>, SpellcheckedPage<T> { private static final long serialVersionUID = -4199560685036530258L; private Map<PageKey, Page<FacetFieldEntry>> facetResultPages = new LinkedHashMap<>(1); private Map<PageKey, List<FacetPivotFieldEntry>> facetPivotResultPages = new LinkedHashMap<>(); private Map<PageKey, Page<FacetFieldEntry>> facetRangeResultPages = new LinkedHashMap<>(1); private Page<FacetQueryEntry> facetQueryResult; private List<HighlightEntry<T>> highlighted; private Float maxScore; private Map<Object, GroupResult<T>> groupResults = Collections.emptyMap(); private Map<String, FieldStatsResult> fieldStatsResults; private Map<String, List<Alternative>> suggestions = new LinkedHashMap<>(); public SolrResultPage(List<T> content) { super(content); } public SolrResultPage(List<T> content, Pageable pageable, long total, Float maxScore) { super(content, pageable, total); this.maxScore = maxScore; } private Page<FacetFieldEntry> getResultPage(String fieldname, Map<PageKey, Page<FacetFieldEntry>> resultPages) { Page<FacetFieldEntry> page = resultPages.get(new StringPageKey(fieldname)); return page != null ? page : new PageImpl<>(Collections.<FacetFieldEntry> emptyList()); } @Override public final Page<FacetFieldEntry> getFacetResultPage(String fieldname) { return getResultPage(fieldname, this.facetResultPages); } /* * (non-Javadoc) * @see org.springframework.data.solr.core.query.result.FacetPage#getRangeFacetResultPage(java.lang.String) */ @Override public final Page<FacetFieldEntry> getRangeFacetResultPage(String fieldname) { return getResultPage(fieldname, this.facetRangeResultPages); } @Override public final Page<FacetFieldEntry> getFacetResultPage(Field field) { return this.getFacetResultPage(field.getName()); } /* * (non-Javadoc) * @see org.springframework.data.solr.core.query.result.FacetPage#getRangeFacetResultPage(org.springframework.data.solr.core.query.Field) */ @Override public final Page<FacetFieldEntry> getRangeFacetResultPage(Field field) { return getRangeFacetResultPage(field.getName()); } @Override public List<FacetPivotFieldEntry> getPivot(String fieldName) { return facetPivotResultPages.get(new StringPageKey(fieldName)); } @Override public List<FacetPivotFieldEntry> getPivot(PivotField field) { return facetPivotResultPages.get(new StringPageKey(field.getName())); } public final void addFacetResultPage(Page<FacetFieldEntry> page, Field field) { this.facetResultPages.put(new StringPageKey(field.getName()), page); } /** * @param page * @param field * @since 1.5 */ public final void addRangeFacetResultPage(Page<FacetFieldEntry> page, Field field) { this.facetRangeResultPages.put(new StringPageKey(field.getName()), page); } public final void addFacetPivotResultPage(List<FacetPivotFieldEntry> result, PivotField field) { this.facetPivotResultPages.put(new StringPageKey(field.getName()), result); } public void addAllFacetFieldResultPages(Map<Field, Page<FacetFieldEntry>> pageMap) { for (Map.Entry<Field, Page<FacetFieldEntry>> entry : pageMap.entrySet()) { addFacetResultPage(entry.getValue(), entry.getKey()); } } /** * @param pageMap * @since 1.5 */ public void addAllRangeFacetFieldResultPages(Map<Field, Page<FacetFieldEntry>> pageMap) { for (Map.Entry<Field, Page<FacetFieldEntry>> entry : pageMap.entrySet()) { addRangeFacetResultPage(entry.getValue(), entry.getKey()); } } public void addAllFacetPivotFieldResult(Map<PivotField, List<FacetPivotFieldEntry>> resultMap) { for (Map.Entry<PivotField, List<FacetPivotFieldEntry>> entry : resultMap.entrySet()) { addFacetPivotResultPage(entry.getValue(), entry.getKey()); } } @Override public Collection<Page<FacetFieldEntry>> getFacetResultPages() { return Collections.unmodifiableCollection(this.facetResultPages.values()); } public final void setFacetQueryResultPage(List<FacetQueryEntry> facetQueryResult) { this.facetQueryResult = new PageImpl<>(facetQueryResult); } @Override public Page<FacetQueryEntry> getFacetQueryResult() { return this.facetQueryResult != null ? this.facetQueryResult : new PageImpl<>(Collections.<FacetQueryEntry> emptyList()); } @Override public Collection<Field> getFacetFields() { if (this.facetResultPages.isEmpty()) { return Collections.emptyList(); } List<Field> fields = new ArrayList<>(this.facetResultPages.size()); for (PageKey pageKey : this.facetResultPages.keySet()) { fields.add(new SimpleField(pageKey.getKey().toString())); } return fields; } @Override public Collection<PivotField> getFacetPivotFields() { if (this.facetPivotResultPages.isEmpty()) { return Collections.emptyList(); } List<PivotField> fields = new ArrayList<>(this.facetPivotResultPages.size()); for (PageKey pageKey : this.facetPivotResultPages.keySet()) { fields.add(new SimplePivotField(pageKey.getKey().toString())); } return fields; } @Override public Collection<Page<? extends FacetEntry>> getAllFacets() { List<Page<? extends FacetEntry>> entries = new ArrayList<>(this.facetResultPages.size() + 1); entries.addAll(this.facetResultPages.values()); entries.add(this.facetQueryResult); return entries; } @Override public List<HighlightEntry<T>> getHighlighted() { return this.highlighted != null ? this.highlighted : Collections.<HighlightEntry<T>> emptyList(); } public void setHighlighted(List<HighlightEntry<T>> highlighted) { this.highlighted = highlighted; } @Override public List<Highlight> getHighlights(T entity) { if (entity != null && this.highlighted != null) { for (HighlightEntry<T> highlightEntry : this.highlighted) { if (highlightEntry != null && ObjectUtils.nullSafeEquals(highlightEntry.getEntity(), entity)) { return highlightEntry.getHighlights(); } } } return Collections.emptyList(); } /** * @param groupResults * @since 1.4 */ public void setGroupResults(Map<Object, GroupResult<T>> groupResults) { this.groupResults = groupResults; } /* * (non-Javadoc) * @see org.springframework.data.solr.core.query.result.ScoredPage#getMaxScore() */ @Override public Float getMaxScore() { return maxScore; } @Override public GroupResult<T> getGroupResult(Field field) { Assert.notNull(field, "group result field must not be null"); return groupResults.get(field.getName()); } @Override public GroupResult<T> getGroupResult(Function function) { Assert.notNull(function, "group result function must not be null"); return groupResults.get(function); } @Override public GroupResult<T> getGroupResult(Query query) { Assert.notNull(query, "group result query must not be null"); return groupResults.get(query); } @Override public GroupResult<T> getGroupResult(String name) { Assert.notNull(name, "group result name must not be null"); return groupResults.get(name); } /** * @since 1.4 */ public void setFieldStatsResults(Map<String, FieldStatsResult> fieldStatsResults) { this.fieldStatsResults = fieldStatsResults; } @Override public FieldStatsResult getFieldStatsResult(Field field) { return getFieldStatsResult(field.getName()); } @Override public FieldStatsResult getFieldStatsResult(String fieldName) { return this.fieldStatsResults.get(fieldName); } @Override public Map<String, FieldStatsResult> getFieldStatsResults() { return this.fieldStatsResults; } /* * (non-Javadoc) * @see org.springframework.data.solr.core.query.result.SpellcheckQueryResult#getSuggestions(java.lang.String) */ @Override public Collection<String> getSuggestions(String term) { List<String> suggestions = new ArrayList<>(); for (Alternative alternative : getAlternatives(term)) { suggestions.add(alternative.getSuggestion()); } return suggestions; } /* * (non-Javadoc) * @see org.springframework.data.solr.core.query.result.SpellcheckQueryResult#getSuggestions() */ @Override public Collection<String> getSuggestions() { List<String> suggestions = new ArrayList<>(); for (Alternative alternative : getAlternatives()) { suggestions.add(alternative.getSuggestion()); } return suggestions; } /* * (non-Javadoc) * @see org.springframework.data.solr.core.query.result.SpellcheckQueryResult#addSuggestions(java.lang.String, java.util.List) */ @Override public void addSuggestions(String term, List<Alternative> suggestions) { this.suggestions.put(term, suggestions); } /* * (non-Javadoc) * @see org.springframework.data.solr.core.query.result.SpellcheckQueryResult#getAlternatives() */ @Override public Collection<Alternative> getAlternatives() { List<Alternative> allSuggestions = new ArrayList<>(); for (List<Alternative> suggestions : this.suggestions.values()) { allSuggestions.addAll(suggestions); } return allSuggestions; } /* * (non-Javadoc) * @see org.springframework.data.solr.core.query.result.SpellcheckQueryResult#getAlternatives(java.lang.String) */ @Override public Collection<Alternative> getAlternatives(String term) { return suggestions.containsKey(term) ? Collections.<Alternative> unmodifiableList(this.suggestions.get(term)) : Collections.<Alternative> emptyList(); } }