MtasExpandSpanQuery.java
package mtas.search.spans.util;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;
import org.apache.lucene.codecs.FieldsProducer;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.LeafReader;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermContext;
import org.apache.lucene.index.Terms;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.spans.SpanWeight;
import org.apache.lucene.search.spans.Spans;
import mtas.codec.util.CodecInfo;
import mtas.search.spans.MtasSpanMatchNoneSpans;
/**
* The Class MtasExpandSpanQuery.
*/
public class MtasExpandSpanQuery extends MtasSpanQuery {
/** The query. */
MtasSpanQuery query;
/** The minimum left. */
int minimumLeft;
/** The maximum left. */
int maximumLeft;
/** The minimum right. */
int minimumRight;
/** The maximum right. */
int maximumRight;
/**
* Instantiates a new mtas expand span query.
*
* @param query the query
* @param minimumLeft the minimum left
* @param maximumLeft the maximum left
* @param minimumRight the minimum right
* @param maximumRight the maximum right
*/
public MtasExpandSpanQuery(MtasSpanQuery query, int minimumLeft,
int maximumLeft, int minimumRight, int maximumRight) {
super(null, null);
this.query = query;
if (minimumLeft > maximumLeft || minimumRight > maximumRight
|| minimumLeft < 0 || minimumRight < 0) {
throw new IllegalArgumentException();
}
this.minimumLeft = minimumLeft;
this.maximumLeft = maximumLeft;
this.minimumRight = minimumRight;
this.maximumRight = maximumRight;
Integer minimum = query.getMinimumWidth();
Integer maximum = query.getMaximumWidth();
if (minimum != null) {
minimum += minimumLeft + minimumRight;
}
if (maximum != null) {
maximum += maximumLeft + maximumRight;
}
setWidth(minimum, maximum);
}
/*
* (non-Javadoc)
*
* @see
* mtas.search.spans.util.MtasSpanQuery#createWeight(org.apache.lucene.search.
* IndexSearcher, boolean)
*/
@Override
public SpanWeight createWeight(IndexSearcher searcher, boolean needsScores, float boost)
throws IOException {
SpanWeight subWeight = query.createWeight(searcher, needsScores, boost);
if (maximumLeft == 0 && maximumRight == 0) {
return subWeight;
} else {
return new MtasExpandWeight(subWeight, searcher, needsScores, boost);
}
}
/*
* (non-Javadoc)
*
* @see org.apache.lucene.search.spans.SpanQuery#getField()
*/
@Override
public String getField() {
return query.getField();
}
/*
* (non-Javadoc)
*
* @see org.apache.lucene.search.Query#toString(java.lang.String)
*/
@Override
public String toString(String field) {
StringBuilder buffer = new StringBuilder();
buffer.append(this.getClass().getSimpleName() + "([");
buffer.append(query.toString(field) + "][" + minimumLeft + "," + maximumLeft
+ "][" + minimumRight + "," + maximumRight + "])");
return buffer.toString();
}
/*
* (non-Javadoc)
*
* @see org.apache.lucene.search.Query#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final MtasExpandSpanQuery that = (MtasExpandSpanQuery) obj;
boolean isEqual;
isEqual = query.equals(that.query);
isEqual &= minimumLeft == that.minimumLeft;
isEqual &= maximumLeft == that.maximumLeft;
isEqual &= minimumRight == that.minimumRight;
isEqual &= maximumRight == that.maximumRight;
return isEqual;
}
/*
* (non-Javadoc)
*
* @see org.apache.lucene.search.Query#hashCode()
*/
@Override
public int hashCode() {
int h = Integer.rotateLeft(classHash(), 1);
h ^= query.hashCode();
h = Integer.rotateLeft(h, minimumLeft) + minimumLeft;
h ^= 2;
h = Integer.rotateLeft(h, maximumLeft) + maximumLeft;
h ^= 3;
h = Integer.rotateLeft(h, minimumRight) + minimumRight;
h ^= 5;
h = Integer.rotateLeft(h, maximumRight) + maximumRight;
return h;
}
/*
* (non-Javadoc)
*
* @see mtas.search.spans.util.MtasSpanQuery#rewrite(org.apache.lucene.index.
* IndexReader)
*/
@Override
public MtasSpanQuery rewrite(IndexReader reader) throws IOException {
MtasSpanQuery newQuery = query.rewrite(reader);
if (maximumLeft == 0 && maximumRight == 0) {
return newQuery;
} else if (((maximumLeft == 0) || (maximumLeft == minimumLeft))
&& ((maximumRight == 0) || (maximumRight == minimumRight))) {
MtasSpanQuery maximumExpandedQuery = new MtasMaximumExpandSpanQuery(
newQuery, minimumLeft, maximumLeft, minimumRight, maximumRight);
return maximumExpandedQuery.rewrite(reader);
} else if (!query.equals(newQuery)) {
return new MtasExpandSpanQuery(newQuery, minimumLeft, maximumLeft,
minimumRight, maximumRight);
} else {
return super.rewrite(reader);
}
}
/*
* (non-Javadoc)
*
* @see mtas.search.spans.util.MtasSpanQuery#disableTwoPhaseIterator()
*/
@Override
public void disableTwoPhaseIterator() {
super.disableTwoPhaseIterator();
query.disableTwoPhaseIterator();
}
@Override
public boolean isMatchAllPositionsQuery() {
return false;
}
/**
* The Class MtasExpandWeight.
*/
private class MtasExpandWeight extends MtasSpanWeight {
/** The Constant METHOD_GET_DELEGATE. */
private static final String METHOD_GET_DELEGATE = "getDelegate";
/** The Constant METHOD_GET_POSTINGS_READER. */
private static final String METHOD_GET_POSTINGS_READER = "getPostingsReader";
/** The sub weight. */
SpanWeight subWeight;
/**
* Instantiates a new mtas expand weight.
*
* @param subWeight the sub weight
* @param searcher the searcher
* @param needsScores the needs scores
* @throws IOException Signals that an I/O exception has occurred.
*/
public MtasExpandWeight(SpanWeight subWeight, IndexSearcher searcher,
boolean needsScores, float boost) throws IOException {
super(MtasExpandSpanQuery.this, searcher,
needsScores ? getTermContexts(subWeight) : null, boost);
this.subWeight = subWeight;
}
/*
* (non-Javadoc)
*
* @see
* org.apache.lucene.search.spans.SpanWeight#extractTermContexts(java.util.
* Map)
*/
@Override
public void extractTermContexts(Map<Term, TermContext> contexts) {
subWeight.extractTermContexts(contexts);
}
/*
* (non-Javadoc)
*
* @see
* org.apache.lucene.search.spans.SpanWeight#getSpans(org.apache.lucene.
* index.LeafReaderContext,
* org.apache.lucene.search.spans.SpanWeight.Postings)
*/
@Override
public Spans getSpans(LeafReaderContext ctx, Postings requiredPostings)
throws IOException {
Spans spans = subWeight.getSpans(ctx, requiredPostings);
if ((maximumLeft == 0 && maximumRight == 0) || spans == null) {
return spans;
} else {
try {
// get leafreader
LeafReader r = ctx.reader();
// get delegate
Boolean hasMethod = true;
while (hasMethod) {
hasMethod = false;
Method[] methods = r.getClass().getMethods();
for (Method m : methods) {
if (m.getName().equals(METHOD_GET_DELEGATE)) {
hasMethod = true;
r = (LeafReader) m.invoke(r, (Object[]) null);
break;
}
}
} // get fieldsproducer
Method fpm = r.getClass().getMethod(METHOD_GET_POSTINGS_READER,
(Class<?>[]) null);
FieldsProducer fp = (FieldsProducer) fpm.invoke(r, (Object[]) null);
// get MtasFieldsProducer using terms
Terms t = fp.terms(field);
if (t == null) {
return new MtasSpanMatchNoneSpans(MtasExpandSpanQuery.this);
} else {
CodecInfo mtasCodecInfo = CodecInfo.getCodecInfoFromTerms(t);
return new MtasExpandSpans(MtasExpandSpanQuery.this, mtasCodecInfo,
query.getField(), spans);
}
} catch (Exception e) {
throw new IOException("Can't get reader", e);
}
}
}
/*
* (non-Javadoc)
*
* @see org.apache.lucene.search.Weight#extractTerms(java.util.Set)
*/
@Override
public void extractTerms(Set<Term> terms) {
subWeight.extractTerms(terms);
}
// @Override
// public boolean isCacheable(LeafReaderContext arg0) {
// return subWeight.isCacheable(arg0);
// }
}
}