/* This file is part of Cyclos (www.cyclos.org). A project of the Social Trade Organisation (www.socialtrade.org). Cyclos is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Cyclos is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Cyclos; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package nl.strohalm.cyclos.utils.lucene; import java.io.Closeable; import java.io.IOException; import java.util.Iterator; import java.util.NoSuchElementException; import nl.strohalm.cyclos.entities.Entity; import nl.strohalm.cyclos.entities.Indexable; import nl.strohalm.cyclos.entities.Relationship; import org.apache.lucene.index.IndexReader; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.TopDocs; /** * An iterator for returned documents in a full text search * @author luis */ public class DocsIterator<E extends Entity & Indexable> implements Closeable, Iterator<E> { private final LuceneQueryHandler luceneQueryHandler; private final Class<E> entityType; private final IndexReader reader; private final TopDocs topDocs; private final Relationship[] fetch; private int index; private E entity; public DocsIterator(final LuceneQueryHandler luceneQueryHandler, final Class<E> entityType, final IndexReader reader, final TopDocs topDocs, final int firstResult, final Relationship[] fetch) { this.luceneQueryHandler = luceneQueryHandler; this.entityType = entityType; this.reader = reader; this.topDocs = topDocs; this.fetch = fetch; index = firstResult; entity = getNextEntity(); } @Override public void close() throws IOException { reader.close(); } @Override public boolean hasNext() { return entity != null; } @Override public E next() { if (entity == null) { throw new NoSuchElementException(); } E result = entity; entity = getNextEntity(); return result; } @Override public void remove() { throw new UnsupportedOperationException(); } private E getNextEntity() { E entity = null; try { ScoreDoc scoreDoc = topDocs.scoreDocs[index++]; entity = luceneQueryHandler.toEntity(reader, scoreDoc.doc, entityType, fetch); if (entity == null) { // There could be an entity which was removed. In that case, we just skip it and get the next one entity = getNextEntity(); } } catch (ArrayIndexOutOfBoundsException e) { entity = null; } return entity; } }