001 002package org.opencms.search.solr; 003 004import org.opencms.search.CmsSearchResource; 005 006import java.util.ArrayList; 007import java.util.Collections; 008import java.util.HashMap; 009import java.util.List; 010import java.util.Map; 011 012import org.apache.solr.client.solrj.SolrQuery; 013import org.apache.solr.client.solrj.response.FacetField; 014import org.apache.solr.client.solrj.response.QueryResponse; 015import org.apache.solr.client.solrj.response.RangeFacet; 016import org.apache.solr.client.solrj.response.SpellCheckResponse; 017import org.apache.solr.common.SolrDocumentList; 018 019/** 020 * Encapsulates a list of 'OpenCms resource documents' ({@link CmsSearchResource}).<p> 021 * 022 * This list can be accessed exactly like an {@link ArrayList} which entries are 023 * {@link CmsSearchResource} that extend {@link org.opencms.file.CmsResource} and 024 * holds the Solr implementation of {@link org.opencms.search.I_CmsSearchDocument} 025 * as member. <b>This enables you to deal with the resulting list as you do with 026 * well known {@link List} and work on it's entries like you do on 027 * {@link org.opencms.file.CmsResource}.</b><p> 028 * 029 * @since 8.5.0 030 */ 031public class CmsSolrResultList extends ArrayList<CmsSearchResource> { 032 033 /** The serial version UID. */ 034 private static final long serialVersionUID = 707475894827620542L; 035 036 /** The end index of documents to display (start + rows). */ 037 private int m_end; 038 039 /** The time in ms when the highlighting is finished. */ 040 private long m_highlightEndTime; 041 042 /** A map of highlighting. */ 043 private Map<String, Map<String, List<String>>> m_highlighting; 044 045 /** The current page (start / rows), used to build a pagination. */ 046 private int m_page; 047 048 /** The original Solr query. */ 049 private SolrQuery m_query; 050 051 /** The original query response. */ 052 private QueryResponse m_queryResponse; 053 054 /** The original list of Solr documents. */ 055 private SolrDocumentList m_resultDocuments; 056 057 /** The row count. */ 058 private Integer m_rows; 059 060 /** The start time, when the search query was executed. */ 061 private long m_startTime; 062 063 /** The count of visible documents. */ 064 private long m_visibleHitCount; 065 066 /** 067 * The public constructor.<p> 068 * 069 * @param query original Solr query 070 * @param queryResponse original query response 071 * @param resultDocuments original list of Solr documents 072 * @param resourceDocumentList the list of resource documents 073 * @param start the start (offset) 074 * @param rows the rows (hits per page) 075 * @param end the end (start + rows) 076 * @param page the current page (start / rows) 077 * @param visibleHitCount the visible hit count 078 * @param maxScore the max score of the best matching doc 079 * @param startTime the start time when the query has been executed 080 * @param highlightEndTime the time in ms when the highlighting is finished 081 */ 082 public CmsSolrResultList( 083 SolrQuery query, 084 QueryResponse queryResponse, 085 SolrDocumentList resultDocuments, 086 List<CmsSearchResource> resourceDocumentList, 087 int start, 088 Integer rows, 089 int end, 090 int page, 091 long visibleHitCount, 092 Float maxScore, 093 long startTime, 094 long highlightEndTime) { 095 096 super(resourceDocumentList); 097 098 m_query = query; 099 m_startTime = startTime; 100 m_highlightEndTime = highlightEndTime; 101 m_rows = rows; 102 m_end = end; 103 m_page = page; 104 m_visibleHitCount = visibleHitCount; 105 106 m_resultDocuments = resultDocuments; 107 m_queryResponse = queryResponse; 108 109 m_highlighting = transformHighlighting(); 110 } 111 112 /** 113 * Returns the last index of documents to display.<p> 114 * 115 * @return the last index of documents to display 116 */ 117 public int getEnd() { 118 119 return m_end; 120 } 121 122 /** 123 * Delegator.<p> 124 * 125 * @param name the name 126 * 127 * @return the facet field 128 */ 129 public FacetField getFacetDate(String name) { 130 131 return m_queryResponse.getFacetDate(name); 132 } 133 134 /** 135 * Delegator.<p> 136 * 137 * @return the list of faceted date fields 138 */ 139 public List<FacetField> getFacetDates() { 140 141 return m_queryResponse.getFacetDates(); 142 } 143 144 /** 145 * Delegator.<p> 146 * 147 * @param name the name 148 * 149 * @return the facet field 150 */ 151 public FacetField getFacetField(String name) { 152 153 return m_queryResponse.getFacetField(name); 154 } 155 156 /** 157 * Delegator.<p> 158 * 159 * @return the list of faceted fields 160 */ 161 public List<FacetField> getFacetFields() { 162 163 return m_queryResponse.getFacetFields(); 164 } 165 166 /** 167 * Delegator.<p> 168 * 169 * @return the facet query 170 */ 171 public Map<String, Integer> getFacetQuery() { 172 173 return m_queryResponse.getFacetQuery(); 174 } 175 176 /** 177 * Delegator.<p> 178 * 179 * @return the list of facet ranges 180 */ 181 @SuppressWarnings("rawtypes") 182 public List<RangeFacet> getFacetRanges() { 183 184 return m_queryResponse.getFacetRanges(); 185 } 186 187 /** 188 * Returns the time in ms when the highlighting is finished.<p> 189 * 190 * @return the time in ms when the highlighting is finished 191 */ 192 public long getHighlightEndTime() { 193 194 return m_highlightEndTime; 195 } 196 197 /** 198 * Returns the highlighting information.<p> 199 * 200 * @return the highlighting information 201 */ 202 public Map<String, Map<String, List<String>>> getHighLighting() { 203 204 return m_highlighting; 205 } 206 207 /** 208 * Delegator.<p> 209 * 210 * @return the limiting facets 211 */ 212 public List<FacetField> getLimitingFacets() { 213 214 return m_queryResponse.getLimitingFacets(); 215 } 216 217 /** 218 * Returns the score of the best matching document.<p> 219 * 220 * @return the score of the best matching document 221 */ 222 public Float getMaxScore() { 223 224 return m_resultDocuments.getMaxScore(); 225 } 226 227 /** 228 * Returns the count of docs that have been found.<p> 229 * 230 * @return the count of docs that have been found 231 */ 232 public long getNumFound() { 233 234 return m_resultDocuments.getNumFound(); 235 } 236 237 /** 238 * Returns the current page.<p> 239 * 240 * @return the current page 241 */ 242 public int getPage() { 243 244 return m_page; 245 } 246 247 /** 248 * The original Solr query.<p> 249 * 250 * @return the query 251 */ 252 public SolrQuery getQuery() { 253 254 return m_query; 255 } 256 257 /** 258 * Returns the requested row count.<p> 259 * 260 * @return the rows 261 */ 262 public Integer getRows() { 263 264 return m_rows; 265 } 266 267 /** 268 * Delegator.<p> 269 * 270 * @return the spellcheck response 271 */ 272 public SpellCheckResponse getSpellCheckResponse() { 273 274 return m_queryResponse.getSpellCheckResponse(); 275 } 276 277 /** 278 * Returns the start index (offset).<p> 279 * 280 * @return the start 281 */ 282 public Long getStart() { 283 284 return Long.valueOf(m_resultDocuments.getStart()); 285 } 286 287 /** 288 * Returns the start time.<p> 289 * 290 * @return the start time 291 */ 292 public long getStartTime() { 293 294 return m_startTime; 295 } 296 297 /** 298 * Returns the visible hit count.<p> 299 * 300 * @return the visible count of documents 301 */ 302 public long getVisibleHitCount() { 303 304 return m_visibleHitCount; 305 } 306 307 /** 308 * Transforms / corrects the highlighting.<p> 309 * 310 * @return the highlighting 311 */ 312 private Map<String, Map<String, List<String>>> transformHighlighting() { 313 314 Map<String, Map<String, List<String>>> result = new HashMap<String, Map<String, List<String>>>(); 315 if (m_queryResponse.getHighlighting() != null) { 316 for (String key : m_queryResponse.getHighlighting().keySet()) { 317 Map<String, ?> value = m_queryResponse.getHighlighting().get(key); 318 Map<String, List<String>> innerResult = new HashMap<String, List<String>>(); 319 for (String innerKey : value.keySet()) { 320 Object entry = value.get(innerKey); 321 List<String> innerList = new ArrayList<String>(); 322 if (entry instanceof String) { 323 innerResult.put(innerKey, Collections.singletonList((String)entry)); 324 } else if (entry instanceof String[]) { 325 String[] li = (String[])entry; 326 for (Object lo : li) { 327 String s = (String)lo; 328 innerList.add(s); 329 } 330 innerResult.put(innerKey, innerList); 331 } else if (entry instanceof List<?>) { 332 List<?> li = (List<?>)entry; 333 for (Object lo : li) { 334 String s = (String)lo; 335 innerList.add(s); 336 } 337 innerResult.put(innerKey, innerList); 338 } 339 } 340 result.put(key, innerResult); 341 } 342 } 343 return result; 344 } 345}