001/* 002 * Copyright 2016 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.Iterator; 019import java.util.NoSuchElementException; 020 021import org.apache.solr.common.SolrDocument; 022import org.slf4j.Logger; 023 024import org.ametys.cms.content.indexing.solr.SolrFieldNames; 025import org.ametys.cms.search.SearchResultsIterator; 026import org.ametys.plugins.repository.AmetysObjectResolver; 027 028/** 029 * This abstract iterator is here for providing common code to an iterator over 030 * SearchResult and to an AmetysObjectIterator 031 * @param <O> the type of elements returned by this iterator 032 */ 033abstract class AbstractResponseIterator<O> implements SearchResultsIterator<O> 034{ 035 protected AmetysObjectResolver _ametysObjectResolver; 036 private Iterator<SolrDocument> _it; 037 private O _nextObject; 038 private int _position; 039 private long _size; 040 private long _errors; 041 private Logger _logger; 042 043 public AbstractResponseIterator(Iterator<SolrDocument> it, long size, AmetysObjectResolver resolver, Logger logger) 044 { 045 _it = it; 046 _size = size; 047 _errors = 0; 048 _ametysObjectResolver = resolver; 049 _logger = logger; 050 } 051 052 @Override 053 public boolean hasNext() 054 { 055 // Prefetch the next object 056 if (_nextObject == null) 057 { 058 while (_it.hasNext()) 059 { 060 SolrDocument document = _it.next(); 061 String id = (String) document.getFieldValue(SolrFieldNames.ID); 062 063 if (_ametysObjectResolver.hasAmetysObjectForId(id)) 064 { 065 _nextObject = _setNextObject(document, id); 066 return true; 067 } 068 else 069 { 070 // Go to next element 071 _errors++; 072 _logger.warn("The Solr indexed Ametys object with id '{}' does not exist. Either autoCommit did not execute yet or a full reindexation is required.", id); 073 } 074 } 075 return false; 076 } 077 return true; 078 } 079 080 protected abstract O _setNextObject(SolrDocument document, String id); 081 082 @Override 083 public O next() 084 { 085 if (!hasNext()) 086 { 087 throw new NoSuchElementException(); 088 } 089 090 try 091 { 092 _position++; 093 return _nextObject; 094 } 095 finally 096 { 097 _nextObject = null; 098 } 099 } 100 101 public long getPosition() 102 { 103 return _position; 104 } 105 106 public long getSize() 107 { 108 return _size - _errors; 109 } 110 111 @Override 112 public void skip(long skipNum) 113 { 114 if (skipNum <= 0) 115 { 116 return; 117 } 118 119 long size = getSize(); 120 if (size != -1 && skipNum > size - getPosition()) 121 { 122 throw new NoSuchElementException(); 123 } 124 125 for (long i = skipNum; i > 0; i--) 126 { 127 next(); 128 } 129 } 130}