package org.apache.lucene.search.spans;
/**
* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.IOException;
import java.util.Collection;
import java.util.ArrayList;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermPositions;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.Searcher;
import org.apache.lucene.search.Similarity;
/** Matches spans containing a term. */
public class SpanTermQuery extends SpanQuery
{
private Term term;
private int termLength;
/** Construct a SpanTermQuery matching the named term's spans. */
public SpanTermQuery(Term term) {
this.term = term;
this.termLength = 1;
}
/** Construct a SpanTermQuery matching the named term's spans, using
* the specified stop-word set. */
public SpanTermQuery(Term term, int termLength) {
this.term = term;
this.termLength = termLength;
}
/** Return the term whose spans are matched. */
public Term getTerm() {
return term;
}
/** Return the length of the term in positions (typically 1) */
public int getTermLength() {
return termLength;
}
public String getField() {
return term.field();
}
public Collection getTerms() {
Collection terms = new ArrayList();
terms.add(term);
return terms;
}
public String toString(String field)
{
StringBuffer buffer = new StringBuffer();
if (!term.field().equals(field)) {
buffer.append(term.field());
buffer.append(":");
}
buffer.append(term.text());
if (getBoost() != 1.0f) {
buffer.append("^");
buffer.append(Float.toString(getBoost()));
}
return buffer.toString();
}
public Spans getSpans(final IndexReader reader, final Searcher searcher)
throws IOException
{
// Calculate a score value for this term, including the boost.
final float idf = getSimilarity(searcher).idf(term, searcher); // compute idf
final float value = idf * getBoost(); // compute query weight
final byte[] fieldNorms = reader.norms(term.field());
return new Spans()
{
private TermPositions positions = reader.termPositions(term);
private int doc = -1;
private int freq;
private int count;
private int position;
public boolean next()
throws IOException
{
if (count == freq)
{
if (!positions.next()) {
doc = Integer.MAX_VALUE;
return false;
}
doc = positions.doc();
freq = positions.freq();
count = 0;
}
position = positions.nextPosition();
count++;
return true;
}
public boolean skipTo(int target)
throws IOException
{
if (!positions.skipTo(target)) {
doc = Integer.MAX_VALUE;
return false;
}
doc = positions.doc();
freq = positions.freq();
count = 0;
position = positions.nextPosition();
count++;
return true;
}
public int doc() {
return doc;
}
public int start() {
return position;
}
public int end() {
return position + termLength;
}
public float score() {
return value * Similarity.decodeNorm(fieldNorms[doc]);
}
public String toString() {
return "spans(" + SpanTermQuery.this.toString() + ")@" +
(doc == -1 ? "START"
: (doc == Integer.MAX_VALUE) ? "END" : doc + ":" + position);
}
public Explanation explain()
throws IOException
{
Explanation result = new Explanation();
result.setDescription("weight(" + toString() + "), product of:");
// Explain idf
Explanation idfExpl = new Explanation(idf,
"idf(docFreq=" +
searcher.docFreq(term) + ")");
result.addDetail(idfExpl);
// Explain boost
Explanation boostExpl = new Explanation(getBoost(), "boost");
if (getBoost() != 1.0f)
result.addDetail(boostExpl);
// Explain norm
Explanation fieldNormExpl = new Explanation();
float fieldNorm = fieldNorms != null
? Similarity.decodeNorm(fieldNorms[doc]) : 0.0f;
fieldNormExpl.setValue(fieldNorm);
fieldNormExpl.setDescription(
"fieldNorm(field=" + getField() + ", doc=" + doc + ")");
result.addDetail(fieldNormExpl);
result.setValue(
boostExpl.getValue() * idfExpl.getValue() * fieldNormExpl.getValue());
return result;
}
};
}
}