package mtas.search.spans; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Map; import java.util.Set; import mtas.codec.util.CodecInfo; import mtas.search.similarities.MtasSimScorer; import mtas.search.spans.util.MtasSpanQuery; import mtas.search.spans.util.MtasSpanWeight; import mtas.search.spans.util.MtasSpans; import org.apache.lucene.codecs.FieldsProducer; 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.similarities.Similarity.SimScorer; /** * The Class MtasSpanPositionQuery. */ public class MtasSpanPositionQuery extends MtasSpanQuery { /** The field. */ private String field; /** The start. */ private int start; /** The end. */ private int end; /** * Instantiates a new mtas span position query. * * @param field the field * @param position the position */ public MtasSpanPositionQuery(String field, int position) { this(field, position, position); } /** * Instantiates a new mtas span position query. * * @param field the field * @param start the start * @param end the end */ public MtasSpanPositionQuery(String field, int start, int end) { super(1, 1); this.field = field; this.start = start; this.end = end; } /* * (non-Javadoc) * * @see org.apache.lucene.search.spans.SpanQuery#getField() */ @Override public String getField() { return field; } /* * (non-Javadoc) * * @see * org.apache.lucene.search.spans.SpanQuery#createWeight(org.apache.lucene. * search.IndexSearcher, boolean) */ @Override public MtasSpanWeight createWeight(IndexSearcher searcher, boolean needsScores, float boost) throws IOException { return new SpanAllWeight(searcher, null, boost); } /** * The Class SpanAllWeight. */ protected class SpanAllWeight 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"; /** * Instantiates a new span all weight. * * @param searcher the searcher * @param termContexts the term contexts * @throws IOException Signals that an I/O exception has occurred. */ public SpanAllWeight(IndexSearcher searcher, Map<Term, TermContext> termContexts, float boost) throws IOException { super(MtasSpanPositionQuery.this, searcher, termContexts, boost); } /* * (non-Javadoc) * * @see * org.apache.lucene.search.spans.SpanWeight#extractTermContexts(java.util. * Map) */ @Override public void extractTermContexts(Map<Term, TermContext> contexts) { // don't do anything } /* * (non-Javadoc) * * @see * org.apache.lucene.search.spans.SpanWeight#getSpans(org.apache.lucene. * index.LeafReaderContext, * org.apache.lucene.search.spans.SpanWeight.Postings) */ @Override public MtasSpans getSpans(LeafReaderContext context, Postings requiredPostings) throws IOException { try { // get leafreader LeafReader r = context.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(MtasSpanPositionQuery.this); } else { CodecInfo mtasCodecInfo = CodecInfo.getCodecInfoFromTerms(t); return new MtasSpanPositionSpans(MtasSpanPositionQuery.this, mtasCodecInfo, field, start, end); } } catch (InvocationTargetException | IllegalAccessException | NoSuchMethodException 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) { // don't do anything } /* * (non-Javadoc) * * @see * org.apache.lucene.search.spans.SpanWeight#getSimScorer(org.apache.lucene. * index.LeafReaderContext) */ @Override public SimScorer getSimScorer(LeafReaderContext context) { return new MtasSimScorer(); } // @Override // public boolean isCacheable(LeafReaderContext arg0) { // return true; // } } /* * (non-Javadoc) * * @see * org.apache.lucene.search.spans.SpanTermQuery#toString(java.lang.String) */ @Override public String toString(String field) { StringBuilder buffer = new StringBuilder(); buffer.append(this.getClass().getSimpleName() + "([" + start + (start != end ? "," + end : "") + "])"); 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 MtasSpanPositionQuery that = (MtasSpanPositionQuery) obj; return field.equals(that.field) && start == that.start && end == that.end; } /* * (non-Javadoc) * * @see org.apache.lucene.search.Query#hashCode() */ @Override public int hashCode() { int h = this.getClass().getSimpleName().hashCode(); h = (h * 7) ^ field.hashCode(); h = (h * 13) ^ start; h = (h * 17) ^ end; return h; } @Override public boolean isMatchAllPositionsQuery() { return false; } }