/*
* eXist Open Source Native XML Database
* Copyright (C) 2001-2015 The eXist Project
* http://exist-db.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package org.exist.indexing.lucene;
import org.apache.lucene.analysis.TokenFilter;
import org.apache.lucene.analysis.TokenStream;
import java.util.List;
import java.util.LinkedList;
import java.io.IOException;
import java.util.Iterator;
import org.apache.lucene.util.AttributeSource;
/**
* A caching token filter which can be reset to a position marked
* via method {@link #mark()}.
*/
public class MarkableTokenFilter extends TokenFilter {
private List<AttributeSource.State> cache = null;
private Iterator<AttributeSource.State> iterator = null;
private AttributeSource.State finalState;
//private List<Token> cache = null;
private boolean isCaching = false;
public MarkableTokenFilter(TokenStream tokenStream) {
super(tokenStream);
}
public void mark() {
isCaching = true;
cache = new LinkedList<>();
}
@Override
public void reset() throws IOException {
isCaching = false;
if(cache != null) {
iterator = cache.iterator();
}
}
@Override
public final void end() throws IOException {
if(finalState != null) {
restoreState(finalState);
}
}
/*
@Override
public Token next(Token token) throws IOException {
if (isCaching) {
Token nextToken = input.next(new Token());
cache.add(nextToken);
return nextToken;
} else if (cache == null) {
return input.next(token);
} else {
Token nextToken = cache.remove(0);
if (cache.isEmpty())
cache = null;
return nextToken;
}
}*/
@Override
public final boolean incrementToken() throws IOException {
if (isCaching) {
if(!input.incrementToken()) {
input.end();
finalState = captureState();
return false;
} else {
cache.add(captureState());
return true;
}
} else if (cache == null) {
if(!input.incrementToken()) {
input.end();
finalState = captureState();
return false;
} else {
return true;
}
} else {
if (!iterator.hasNext()) {
// the cache is exhausted, return false
cache = null;
return false;
}
// Since the TokenFilter can be reset, the tokens need to be preserved as immutable.
restoreState(iterator.next());
return true;
}
}
}