package lux.search.highlight; import java.io.IOException; import java.util.ArrayList; import lux.xml.QName; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import org.apache.lucene.analysis.tokenattributes.CharTermAttributeImpl; import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute; /** * Wraps a TokenStream, modifying its CharTermAttribute so as to return * the original term, and the term prefixed by each of its enclosing element's QNames, * in turn. */ public final class StreamingElementTokens extends TokenStream { private TokenStream wrapped; private final CharTermAttribute termAtt; private final PositionIncrementAttribute posIncrAtt; private final CharTermAttribute term; private ArrayList<QName> qnames; // iterate over the qnames; qnamePos = qnames.size() -> no QName // qnamePos = -1 -> done iterating private int qnamePos = -1; /** * @return true if this token represents the token from the XML_TEXT field, * and is not prefixed by an element QName */ public boolean isPlainToken () { return termAtt.length() == term.length(); } public StreamingElementTokens (TokenStream tokens) { super (tokens); // share the same attributes wrapped = tokens; termAtt = addAttribute(CharTermAttribute.class); posIncrAtt = addAttribute(PositionIncrementAttribute.class); term = new CharTermAttributeImpl(); qnames = new ArrayList<QName>(); } public void pushElement (QName qname) { qnames.add(qname); } public void popElement () { qnames.remove(qnames.size()-1); } @Override public boolean incrementToken() throws IOException { if (qnamePos < 0) { if (!wrapped.incrementToken()) { return false; } qnamePos = qnames.size() - 1; term.setEmpty(); term.append(termAtt); return true; } QName qname = qnames.get(qnamePos--); termAtt.setEmpty(); termAtt.append (qname.getEncodedName()); termAtt.append (':'); termAtt.append (term); posIncrAtt.setPositionIncrement(0); return true; } public void reset (TokenStream tokens) throws IOException { wrapped = tokens; reset (); } @Override public void reset () throws IOException { super.reset(); wrapped.reset(); } } /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */