MtasMaximumExpandSpanQuery.java

  1. package mtas.search.spans.util;

  2. import java.io.IOException;
  3. import java.lang.reflect.Method;
  4. import java.util.Map;
  5. import java.util.Set;

  6. import org.apache.lucene.codecs.FieldsProducer;
  7. import org.apache.lucene.index.IndexReader;
  8. import org.apache.lucene.index.LeafReader;
  9. import org.apache.lucene.index.LeafReaderContext;
  10. import org.apache.lucene.index.Term;
  11. import org.apache.lucene.index.TermContext;
  12. import org.apache.lucene.index.Terms;
  13. import org.apache.lucene.search.IndexSearcher;
  14. import org.apache.lucene.search.spans.SpanWeight;
  15. import org.apache.lucene.search.spans.Spans;

  16. import mtas.codec.util.CodecInfo;
  17. import mtas.search.spans.MtasSpanMatchNoneSpans;

  18. /**
  19.  * The Class MtasMaximumExpandSpanQuery.
  20.  */
  21. public class MtasMaximumExpandSpanQuery extends MtasSpanQuery {

  22.   /** The query. */
  23.   MtasSpanQuery query;

  24.   /** The minimum left. */
  25.   int minimumLeft;

  26.   /** The maximum left. */
  27.   int maximumLeft;

  28.   /** The minimum right. */
  29.   int minimumRight;

  30.   /** The maximum right. */
  31.   int maximumRight;

  32.   /**
  33.    * Instantiates a new mtas maximum expand span query.
  34.    *
  35.    * @param query the query
  36.    * @param minimumLeft the minimum left
  37.    * @param maximumLeft the maximum left
  38.    * @param minimumRight the minimum right
  39.    * @param maximumRight the maximum right
  40.    */
  41.   public MtasMaximumExpandSpanQuery(MtasSpanQuery query, int minimumLeft,
  42.       int maximumLeft, int minimumRight, int maximumRight) {
  43.     super(null, null);
  44.     this.query = query;
  45.     if (minimumLeft > maximumLeft || minimumRight > maximumRight
  46.         || minimumLeft < 0 || minimumRight < 0) {
  47.       throw new IllegalArgumentException();
  48.     }
  49.     this.minimumLeft = minimumLeft;
  50.     this.maximumLeft = maximumLeft;
  51.     this.minimumRight = minimumRight;
  52.     this.maximumRight = maximumRight;
  53.     Integer minimum = query.getMinimumWidth();
  54.     Integer maximum = query.getMaximumWidth();
  55.     if (minimum != null) {
  56.       minimum += minimumLeft + minimumRight;
  57.     }
  58.     if (maximum != null) {
  59.       maximum += maximumLeft + maximumRight;
  60.     }
  61.     setWidth(minimum, maximum);
  62.   }

  63.   /*
  64.    * (non-Javadoc)
  65.    *
  66.    * @see
  67.    * mtas.search.spans.util.MtasSpanQuery#createWeight(org.apache.lucene.search.
  68.    * IndexSearcher, boolean)
  69.    */
  70.   @Override
  71.   public SpanWeight createWeight(IndexSearcher searcher, boolean needsScores, float boost)
  72.       throws IOException {
  73.     SpanWeight subWeight = query.createWeight(searcher, needsScores, boost);
  74.     if (maximumLeft == 0 && maximumRight == 0) {
  75.       return subWeight;
  76.     } else {
  77.       return new MtasMaximumExpandWeight(subWeight, searcher, needsScores, boost);
  78.     }
  79.   }

  80.   /*
  81.    * (non-Javadoc)
  82.    *
  83.    * @see org.apache.lucene.search.spans.SpanQuery#getField()
  84.    */
  85.   @Override
  86.   public String getField() {
  87.     return query.getField();
  88.   }

  89.   /*
  90.    * (non-Javadoc)
  91.    *
  92.    * @see org.apache.lucene.search.Query#toString(java.lang.String)
  93.    */
  94.   @Override
  95.   public String toString(String field) {
  96.     StringBuilder buffer = new StringBuilder();
  97.     buffer.append(this.getClass().getSimpleName() + "([");
  98.     buffer.append(query.toString(field) + "][" + minimumLeft + "," + maximumLeft
  99.         + "][" + minimumRight + "," + maximumRight + "])");
  100.     return buffer.toString();
  101.   }

  102.   /*
  103.    * (non-Javadoc)
  104.    *
  105.    * @see org.apache.lucene.search.Query#equals(java.lang.Object)
  106.    */
  107.   @Override
  108.   public boolean equals(Object obj) {
  109.     if (this == obj)
  110.       return true;
  111.     if (obj == null)
  112.       return false;
  113.     if (getClass() != obj.getClass())
  114.       return false;
  115.     final MtasMaximumExpandSpanQuery that = (MtasMaximumExpandSpanQuery) obj;
  116.     boolean isEqual;
  117.     isEqual = query.equals(that.query);
  118.     isEqual &= minimumLeft == that.minimumLeft;
  119.     isEqual &= maximumLeft == that.maximumLeft;
  120.     isEqual &= minimumRight == that.minimumRight;
  121.     isEqual &= maximumRight == that.maximumRight;
  122.     return isEqual;
  123.   }

  124.   /*
  125.    * (non-Javadoc)
  126.    *
  127.    * @see org.apache.lucene.search.Query#hashCode()
  128.    */
  129.   @Override
  130.   public int hashCode() {
  131.     int h = Integer.rotateLeft(classHash(), 1);
  132.     h ^= query.hashCode();
  133.     h = Integer.rotateLeft(h, minimumLeft) + minimumLeft;
  134.     h ^= 2;
  135.     h = Integer.rotateLeft(h, maximumLeft) + maximumLeft;
  136.     h ^= 3;
  137.     h = Integer.rotateLeft(h, minimumRight) + minimumRight;
  138.     h ^= 5;
  139.     h = Integer.rotateLeft(h, maximumRight) + maximumRight;
  140.     return h;
  141.   }

  142.   /*
  143.    * (non-Javadoc)
  144.    *
  145.    * @see mtas.search.spans.util.MtasSpanQuery#rewrite(org.apache.lucene.index.
  146.    * IndexReader)
  147.    */
  148.   @Override
  149.   public MtasSpanQuery rewrite(IndexReader reader) throws IOException {
  150.     MtasSpanQuery newQuery = query.rewrite(reader);
  151.     if (maximumLeft == 0 && maximumRight == 0) {
  152.       return newQuery;
  153.     } else if (!query.equals(newQuery)) {
  154.       return new MtasMaximumExpandSpanQuery(newQuery, minimumLeft, maximumLeft,
  155.           minimumRight, maximumRight);
  156.     } else {
  157.       return super.rewrite(reader);
  158.     }
  159.   }

  160.   /*
  161.    * (non-Javadoc)
  162.    *
  163.    * @see mtas.search.spans.util.MtasSpanQuery#disableTwoPhaseIterator()
  164.    */
  165.   @Override
  166.   public void disableTwoPhaseIterator() {
  167.     super.disableTwoPhaseIterator();
  168.     query.disableTwoPhaseIterator();
  169.   }
  170.  
  171.   @Override
  172.   public boolean isMatchAllPositionsQuery() {
  173.     return false;
  174.   }

  175.   /**
  176.    * The Class MtasMaximumExpandWeight.
  177.    */
  178.   private class MtasMaximumExpandWeight extends MtasSpanWeight {

  179.     /** The Constant METHOD_GET_DELEGATE. */
  180.     private static final String METHOD_GET_DELEGATE = "getDelegate";

  181.     /** The Constant METHOD_GET_POSTINGS_READER. */
  182.     private static final String METHOD_GET_POSTINGS_READER = "getPostingsReader";

  183.     /** The sub weight. */
  184.     SpanWeight subWeight;

  185.     /**
  186.      * Instantiates a new mtas maximum expand weight.
  187.      *
  188.      * @param subWeight the sub weight
  189.      * @param searcher the searcher
  190.      * @param needsScores the needs scores
  191.      * @throws IOException Signals that an I/O exception has occurred.
  192.      */
  193.     public MtasMaximumExpandWeight(SpanWeight subWeight, IndexSearcher searcher,
  194.         boolean needsScores, float boost) throws IOException {
  195.       super(MtasMaximumExpandSpanQuery.this, searcher,
  196.           needsScores ? getTermContexts(subWeight) : null, boost);
  197.       this.subWeight = subWeight;
  198.     }

  199.     /*
  200.      * (non-Javadoc)
  201.      *
  202.      * @see
  203.      * org.apache.lucene.search.spans.SpanWeight#extractTermContexts(java.util.
  204.      * Map)
  205.      */
  206.     @Override
  207.     public void extractTermContexts(Map<Term, TermContext> contexts) {
  208.       subWeight.extractTermContexts(contexts);
  209.     }

  210.     /*
  211.      * (non-Javadoc)
  212.      *
  213.      * @see
  214.      * org.apache.lucene.search.spans.SpanWeight#getSpans(org.apache.lucene.
  215.      * index.LeafReaderContext,
  216.      * org.apache.lucene.search.spans.SpanWeight.Postings)
  217.      */
  218.     @Override
  219.     public Spans getSpans(LeafReaderContext ctx, Postings requiredPostings)
  220.         throws IOException {
  221.       Spans spans = subWeight.getSpans(ctx, requiredPostings);
  222.       if ((maximumLeft == 0 && maximumRight == 0) || spans == null) {
  223.         return spans;
  224.       } else {
  225.         try {
  226.           // get leafreader
  227.           LeafReader r = ctx.reader();
  228.           // get delegate
  229.           Boolean hasMethod = true;
  230.           while (hasMethod) {
  231.             hasMethod = false;
  232.             Method[] methods = r.getClass().getMethods();
  233.             for (Method m : methods) {
  234.               if (m.getName().equals(METHOD_GET_DELEGATE)) {
  235.                 hasMethod = true;
  236.                 r = (LeafReader) m.invoke(r, (Object[]) null);
  237.                 break;
  238.               }
  239.             }
  240.           } // get fieldsproducer
  241.           Method fpm = r.getClass().getMethod(METHOD_GET_POSTINGS_READER,
  242.               (Class<?>[]) null);
  243.           FieldsProducer fp = (FieldsProducer) fpm.invoke(r, (Object[]) null);
  244.           // get MtasFieldsProducer using terms
  245.           Terms t = fp.terms(field);
  246.           if (t == null) {
  247.             return new MtasSpanMatchNoneSpans(MtasMaximumExpandSpanQuery.this);
  248.           } else {
  249.             CodecInfo mtasCodecInfo = CodecInfo.getCodecInfoFromTerms(t);
  250.             return new MtasMaximumExpandSpans(MtasMaximumExpandSpanQuery.this,
  251.                 mtasCodecInfo, query.getField(), spans);
  252.           }
  253.         } catch (Exception e) {
  254.           throw new IOException("Can't get reader", e);
  255.         }

  256.       }
  257.     }

  258.     /*
  259.      * (non-Javadoc)
  260.      *
  261.      * @see org.apache.lucene.search.Weight#extractTerms(java.util.Set)
  262.      */
  263.     @Override
  264.     public void extractTerms(Set<Term> terms) {
  265.       subWeight.extractTerms(terms);
  266.     }
  267.    
  268. //    @Override
  269. //    public boolean isCacheable(LeafReaderContext arg0) {
  270. //      return subWeight.isCacheable(arg0);
  271. //    }

  272.   }

  273. }