blob: e65804604eab913174fe0004f1585f87c3fe241b [file] [log] [blame]
package de.ids_mannheim.korap.query;
// Based on SpanNearQuery
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermContext;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.spans.SpanQuery;
import org.apache.lucene.search.spans.Spans;
import org.apache.lucene.search.spans.SpanTermQuery;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.ToStringUtils;
import de.ids_mannheim.korap.query.spans.WithinSpans;
import de.ids_mannheim.korap.query.SpanElementQuery;
/**
* Matches spans that are within certain elements.
*/
public class SpanWithinQuery extends SpanQuery implements Cloneable {
private SpanQuery wrap;
private SpanQuery embedded;
public String field;
private byte flag;
private boolean collectPayloads;
public static final byte OVERLAP = WithinSpans.OVERLAP,
REAL_OVERLAP = WithinSpans.REAL_OVERLAP,
WITHIN = WithinSpans.WITHIN, REAL_WITHIN = WithinSpans.REAL_WITHIN,
ENDSWITH = WithinSpans.ENDSWITH,
STARTSWITH = WithinSpans.STARTSWITH, MATCH = WithinSpans.MATCH;
// may support "starting" and "ending"
// Constructor
public SpanWithinQuery (SpanQuery wrap, SpanQuery embedded, byte flag,
boolean collectPayloads) {
this.field = embedded.getField();
this.embedded = embedded;
this.wrap = wrap;
this.flag = flag;
this.collectPayloads = collectPayloads;
};
// Constructor
public SpanWithinQuery (String element, SpanQuery embedded) {
this(element, embedded, WITHIN, true);
};
// Constructor
public SpanWithinQuery (String element, SpanQuery embedded, byte flag,
boolean collectPayloads) {
this((SpanQuery) new SpanElementQuery(embedded.getField(), element),
embedded, flag, collectPayloads);
};
// Constructor
public SpanWithinQuery (String element, SpanQuery embedded, byte flag) {
this(element, embedded, flag, true);
};
// Constructor
public SpanWithinQuery (String element, SpanQuery embedded,
boolean collectPayloads) {
this(element, embedded, WITHIN, collectPayloads);
};
// Constructor
public SpanWithinQuery (SpanQuery wrap, SpanQuery embedded, byte flag) {
this(wrap, embedded, flag, true);
};
// Constructor
public SpanWithinQuery (SpanQuery wrap, SpanQuery embedded) {
this(wrap, embedded, WITHIN, true);
};
@Override
public String getField () {
return field;
};
public SpanQuery wrap () {
return wrap;
};
public SpanQuery embedded () {
return embedded;
};
public byte flag () {
return flag;
};
@Override
public void extractTerms (Set<Term> terms) {
embedded.extractTerms(terms);
};
@Override
public String toString (String field) {
StringBuilder buffer = new StringBuilder();
buffer.append("span");
buffer.append(flagToString());
buffer.append("(");
buffer.append(wrap.toString());
buffer.append(", ");
buffer.append(embedded.toString(field));
buffer.append(")");
buffer.append(ToStringUtils.boost(getBoost()));
return buffer.toString();
};
private String flagToString () {
switch (flag) {
case OVERLAP:
return "Overlap";
case REAL_OVERLAP:
return "OverlapStrict";
case WITHIN:
return "Contain";
case REAL_WITHIN:
return "ContainStrict";
case ENDSWITH:
return "EndsWith";
case STARTSWITH:
return "StartsWith";
case MATCH:
return "Match";
};
return "Contains";
};
@Override
public Spans getSpans (final LeafReaderContext context, Bits acceptDocs,
Map<Term, TermContext> termContexts) throws IOException {
return (Spans) new WithinSpans(this, context, acceptDocs, termContexts,
this.flag);
};
/*
* Rewrite query in case it includes regular expressions or wildcards
*/
@Override
public Query rewrite (IndexReader reader) throws IOException {
SpanWithinQuery clone = null;
// Does the embedded query needs a rewrite?
SpanQuery query = (SpanQuery) embedded.rewrite(reader);
if (query != embedded) {
if (clone == null)
clone = this.clone();
clone.embedded = query;
};
// Does the wrap query needs a rewrite?
query = (SpanQuery) wrap.rewrite(reader);
if (query != wrap) {
if (clone == null)
clone = this.clone();
clone.wrap = query;
};
// There is a clone and it is important
if (clone != null)
return clone;
return this;
};
@Override
public SpanWithinQuery clone () {
SpanWithinQuery spanWithinQuery = new SpanWithinQuery(
(SpanQuery) wrap.clone(), (SpanQuery) embedded.clone(),
this.flag, this.collectPayloads);
spanWithinQuery.setBoost(getBoost());
return spanWithinQuery;
};
/**
* Returns true iff <code>o</code> is equal to this.
*/
@Override
public boolean equals (Object o) {
if (this == o)
return true;
if (!(o instanceof SpanWithinQuery))
return false;
final SpanWithinQuery spanWithinQuery = (SpanWithinQuery) o;
if (collectPayloads != spanWithinQuery.collectPayloads)
return false;
if (!wrap.equals(spanWithinQuery.wrap))
return false;
if (!embedded.equals(spanWithinQuery.embedded))
return false;
return getBoost() == spanWithinQuery.getBoost();
};
// I don't know what I am doing here
@Override
public int hashCode () {
int result = flag;
result = embedded.hashCode();
result += wrap.hashCode();
result ^= (result << 4) | (result >>> 29);
result += Float.floatToRawIntBits(getBoost());
return result;
};
};