blob: ab29d0f7db562f7045026622fca20d86a9c86cb7 [file] [log] [blame]
Nils Diewaldf399a672013-11-18 17:55:22 +00001package de.ids_mannheim.korap.query;
2
3import java.io.IOException;
margaretha50c76332015-03-19 10:10:39 +01004import java.util.ArrayList;
5import java.util.List;
Nils Diewaldf399a672013-11-18 17:55:22 +00006import java.util.Map;
7
Nils Diewaldf399a672013-11-18 17:55:22 +00008import org.apache.lucene.index.AtomicReaderContext;
Nils Diewaldf399a672013-11-18 17:55:22 +00009import org.apache.lucene.index.IndexReader;
margaretha50c76332015-03-19 10:10:39 +010010import org.apache.lucene.index.Term;
Nils Diewaldf399a672013-11-18 17:55:22 +000011import org.apache.lucene.index.TermContext;
margaretha50c76332015-03-19 10:10:39 +010012import org.apache.lucene.search.Query;
13import org.apache.lucene.search.spans.SpanQuery;
14import org.apache.lucene.search.spans.Spans;
Nils Diewaldf399a672013-11-18 17:55:22 +000015import org.apache.lucene.util.Bits;
16import org.apache.lucene.util.ToStringUtils;
17
Nils Diewaldf075df02015-03-03 20:34:00 +000018import de.ids_mannheim.korap.query.spans.FocusSpans;
Nils Diewaldf399a672013-11-18 17:55:22 +000019
20/**
Nils Diewald85f9c422015-02-06 21:09:16 +000021 * Modify the span of a match to the boundaries of a certain class.
Nils Diewaldbb33da22015-03-04 16:24:25 +000022 *
23 * In case multiple classes are found with the very same number, the
margarethaf70addb2015-04-27 13:17:18 +020024 * span is maximized to start on the first occurrence from the left
25 * and end on the last occurrence on the right.
Nils Diewaldbb33da22015-03-04 16:24:25 +000026 *
margaretha50c76332015-03-19 10:10:39 +010027 * In case the class to modify on is not found in the subquery, the
margarethaf70addb2015-04-27 13:17:18 +020028 * match is ignored.
Nils Diewaldbb33da22015-03-04 16:24:25 +000029 *
margarethaf70addb2015-04-27 13:17:18 +020030 * @author diewald, margaretha
Nils Diewaldbb33da22015-03-04 16:24:25 +000031 *
Nils Diewaldf075df02015-03-03 20:34:00 +000032 * @see FocusSpans
Nils Diewaldf399a672013-11-18 17:55:22 +000033 */
margaretha50c76332015-03-19 10:10:39 +010034public class SpanFocusQuery extends SimpleSpanQuery {
35
36 private List<Byte> classNumbers = new ArrayList<Byte>();
37 private boolean isSorted = true;
margarethaf70addb2015-04-27 13:17:18 +020038 private boolean matchTemporaryClass = false;
39 private boolean removeTemporaryClasses = false;
Nils Diewaldf399a672013-11-18 17:55:22 +000040
Akronbb5d1732015-06-22 01:22:40 +020041
Nils Diewald85f9c422015-02-06 21:09:16 +000042 /**
Nils Diewaldcec40f92015-02-19 22:20:02 +000043 * Construct a new SpanFocusQuery.
Nils Diewaldbb33da22015-03-04 16:24:25 +000044 *
margaretha50c76332015-03-19 10:10:39 +010045 * @param firstClause
Nils Diewaldbb33da22015-03-04 16:24:25 +000046 * The nested {@link SpanQuery}, that contains one or
margaretha50c76332015-03-19 10:10:39 +010047 * more
48 * classed spans.
Nils Diewaldbb33da22015-03-04 16:24:25 +000049 * @param number
50 * The class number to focus on.
Nils Diewald85f9c422015-02-06 21:09:16 +000051 */
margaretha50c76332015-03-19 10:10:39 +010052 public SpanFocusQuery (SpanQuery sq, byte classNumber) {
53 super(sq, true);
54 classNumbers.add(classNumber);
55 };
56
57
58 public SpanFocusQuery (SpanQuery sq, List<Byte> classNumbers) {
59 super(sq, true);
60 this.classNumbers = classNumbers;
Nils Diewaldf399a672013-11-18 17:55:22 +000061 };
62
Nils Diewald85f9c422015-02-06 21:09:16 +000063
64 /**
margaretha50c76332015-03-19 10:10:39 +010065 * Construct a new SpanFocusQuery. The class to focus on defaults
66 * to
67 * <tt>1</tt>.
Nils Diewaldbb33da22015-03-04 16:24:25 +000068 *
margaretha50c76332015-03-19 10:10:39 +010069 * @param firstClause
Nils Diewaldbb33da22015-03-04 16:24:25 +000070 * The nested {@link SpanQuery}, that contains one or
margaretha50c76332015-03-19 10:10:39 +010071 * more
72 * classed spans.
Nils Diewald85f9c422015-02-06 21:09:16 +000073 */
margaretha50c76332015-03-19 10:10:39 +010074 public SpanFocusQuery (SpanQuery sq) {
75 super(sq, true);
76 classNumbers.add((byte) 1);
Nils Diewaldf399a672013-11-18 17:55:22 +000077 };
78
Nils Diewald85f9c422015-02-06 21:09:16 +000079
Nils Diewaldf399a672013-11-18 17:55:22 +000080 @Override
81 public String toString (String field) {
Nils Diewald85f9c422015-02-06 21:09:16 +000082 StringBuffer buffer = new StringBuffer();
83 buffer.append("focus(");
Akronbb5d1732015-06-22 01:22:40 +020084 if (matchTemporaryClass) {
margarethaf70addb2015-04-27 13:17:18 +020085 buffer.append("#");
86 }
margaretha50c76332015-03-19 10:10:39 +010087 if (classNumbers.size() > 1) {
88 buffer.append("[");
89 for (int i = 0; i < classNumbers.size(); i++) {
90 buffer.append((short) classNumbers.get(i) & 0xFF);
91 if (i != classNumbers.size() - 1) {
92 buffer.append(",");
93 }
94 }
95 buffer.append("]");
96 }
97 else {
98 buffer.append((short) classNumbers.get(0) & 0xFF).append(": ");
99 }
100 buffer.append(this.firstClause.toString());
Nils Diewald85f9c422015-02-06 21:09:16 +0000101 buffer.append(')');
102 buffer.append(ToStringUtils.boost(getBoost()));
103 return buffer.toString();
Nils Diewaldf399a672013-11-18 17:55:22 +0000104 };
105
Nils Diewald85f9c422015-02-06 21:09:16 +0000106
Nils Diewaldf399a672013-11-18 17:55:22 +0000107 @Override
Nils Diewaldbb33da22015-03-04 16:24:25 +0000108 public Spans getSpans (final AtomicReaderContext context, Bits acceptDocs,
109 Map<Term, TermContext> termContexts) throws IOException {
margaretha50c76332015-03-19 10:10:39 +0100110 return new FocusSpans(this, context, acceptDocs, termContexts);
Nils Diewaldf399a672013-11-18 17:55:22 +0000111 };
112
Nils Diewald85f9c422015-02-06 21:09:16 +0000113
Nils Diewaldf399a672013-11-18 17:55:22 +0000114 @Override
115 public Query rewrite (IndexReader reader) throws IOException {
Nils Diewaldcec40f92015-02-19 22:20:02 +0000116 SpanFocusQuery clone = null;
margaretha50c76332015-03-19 10:10:39 +0100117 SpanQuery query = (SpanQuery) this.firstClause.rewrite(reader);
Nils Diewaldbb33da22015-03-04 16:24:25 +0000118
margaretha50c76332015-03-19 10:10:39 +0100119 if (query != this.firstClause) {
Nils Diewald85f9c422015-02-06 21:09:16 +0000120 if (clone == null)
121 clone = this.clone();
margaretha50c76332015-03-19 10:10:39 +0100122 clone.firstClause = query;
Nils Diewald85f9c422015-02-06 21:09:16 +0000123 };
Nils Diewaldf399a672013-11-18 17:55:22 +0000124
Nils Diewald85f9c422015-02-06 21:09:16 +0000125 if (clone != null)
126 return clone;
Nils Diewaldf399a672013-11-18 17:55:22 +0000127
Nils Diewald85f9c422015-02-06 21:09:16 +0000128 return this;
Nils Diewaldf399a672013-11-18 17:55:22 +0000129 };
130
Nils Diewald85f9c422015-02-06 21:09:16 +0000131
Nils Diewaldf399a672013-11-18 17:55:22 +0000132 @Override
Nils Diewaldbb33da22015-03-04 16:24:25 +0000133 public SpanFocusQuery clone () {
Nils Diewaldcec40f92015-02-19 22:20:02 +0000134 SpanFocusQuery spanFocusQuery = new SpanFocusQuery(
margaretha50c76332015-03-19 10:10:39 +0100135 (SpanQuery) this.firstClause.clone(), this.getClassNumbers());
Nils Diewaldcec40f92015-02-19 22:20:02 +0000136 spanFocusQuery.setBoost(getBoost());
margarethaf70addb2015-04-27 13:17:18 +0200137 spanFocusQuery.setMatchTemporaryClass(this.matchTemporaryClass);
138 spanFocusQuery.setSorted(this.isSorted);
139 spanFocusQuery.setRemoveTemporaryClasses(this.removeTemporaryClasses);
Nils Diewaldcec40f92015-02-19 22:20:02 +0000140 return spanFocusQuery;
Nils Diewaldf399a672013-11-18 17:55:22 +0000141 };
142
143
Nils Diewaldf399a672013-11-18 17:55:22 +0000144 @Override
Nils Diewald85f9c422015-02-06 21:09:16 +0000145 public boolean equals (Object o) {
Nils Diewaldbb33da22015-03-04 16:24:25 +0000146 if (this == o)
147 return true;
148 if (!(o instanceof SpanFocusQuery))
149 return false;
150
151 final SpanFocusQuery spanFocusQuery = (SpanFocusQuery) o;
152
margaretha50c76332015-03-19 10:10:39 +0100153 if (!this.firstClause.equals(spanFocusQuery.firstClause))
Nils Diewaldbb33da22015-03-04 16:24:25 +0000154 return false;
margaretha50c76332015-03-19 10:10:39 +0100155 if (this.getClassNumbers() != spanFocusQuery.getClassNumbers())
Nils Diewaldbb33da22015-03-04 16:24:25 +0000156 return false;
Nils Diewaldcec40f92015-02-19 22:20:02 +0000157
158 // Probably not necessary
159 return getBoost() == spanFocusQuery.getBoost();
Nils Diewaldf399a672013-11-18 17:55:22 +0000160 };
161
162
Nils Diewaldf399a672013-11-18 17:55:22 +0000163 @Override
Nils Diewald3e3cbf32015-02-06 21:30:49 +0000164 public int hashCode () {
margaretha50c76332015-03-19 10:10:39 +0100165 int result = firstClause.hashCode();
166 for (byte number : classNumbers)
167 result = 31 * result + number;
Nils Diewald85f9c422015-02-06 21:09:16 +0000168 result += Float.floatToRawIntBits(getBoost());
169 return result;
margaretha50c76332015-03-19 10:10:39 +0100170 }
171
172
173 public List<Byte> getClassNumbers () {
174 return classNumbers;
175 }
176
177
178 public void setClassNumbers (List<Byte> classNumbers) {
179 this.classNumbers = classNumbers;
180 }
181
182
183 public boolean isSorted () {
184 return isSorted;
185 }
186
187
188 public void setSorted (boolean isSorted) {
189 this.isSorted = isSorted;
190 }
191
Akronbb5d1732015-06-22 01:22:40 +0200192
193 public boolean matchTemporaryClass () {
margarethaf70addb2015-04-27 13:17:18 +0200194 return matchTemporaryClass;
195 }
196
Akronbb5d1732015-06-22 01:22:40 +0200197
198 public void setMatchTemporaryClass (boolean matchTemporaryClass) {
margarethaf70addb2015-04-27 13:17:18 +0200199 this.matchTemporaryClass = matchTemporaryClass;
200 }
201
Akronbb5d1732015-06-22 01:22:40 +0200202
203 public boolean removeTemporaryClasses () {
margarethaf70addb2015-04-27 13:17:18 +0200204 return removeTemporaryClasses;
205 }
206
Akronbb5d1732015-06-22 01:22:40 +0200207
208 public void setRemoveTemporaryClasses (boolean rem) {
margarethaf70addb2015-04-27 13:17:18 +0200209 this.removeTemporaryClasses = rem;
210 }
211
Nils Diewaldf399a672013-11-18 17:55:22 +0000212};