blob: ae2e8d565ee6cb381b6c86dab39d68e7febcd191 [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
Akron700c1eb2015-09-25 16:57:30 +02008import org.apache.lucene.index.LeafReaderContext;
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;
Eliza Margarethadc98dc12016-11-16 14:33:42 +010040 private int windowSize = 10; // default
Akronbb5d1732015-06-22 01:22:40 +020041
Akronc12567c2016-06-03 00:40:52 +020042
Nils Diewald85f9c422015-02-06 21:09:16 +000043 /**
Nils Diewaldcec40f92015-02-19 22:20:02 +000044 * Construct a new SpanFocusQuery.
Nils Diewaldbb33da22015-03-04 16:24:25 +000045 *
margaretha50c76332015-03-19 10:10:39 +010046 * @param firstClause
Nils Diewaldbb33da22015-03-04 16:24:25 +000047 * The nested {@link SpanQuery}, that contains one or
margaretha50c76332015-03-19 10:10:39 +010048 * more
49 * classed spans.
Nils Diewaldbb33da22015-03-04 16:24:25 +000050 * @param number
51 * The class number to focus on.
Nils Diewald85f9c422015-02-06 21:09:16 +000052 */
margaretha50c76332015-03-19 10:10:39 +010053 public SpanFocusQuery (SpanQuery sq, byte classNumber) {
54 super(sq, true);
55 classNumbers.add(classNumber);
56 };
57
58
59 public SpanFocusQuery (SpanQuery sq, List<Byte> classNumbers) {
60 super(sq, true);
61 this.classNumbers = classNumbers;
Nils Diewaldf399a672013-11-18 17:55:22 +000062 };
63
Akronc12567c2016-06-03 00:40:52 +020064
Nils Diewald85f9c422015-02-06 21:09:16 +000065 /**
margaretha50c76332015-03-19 10:10:39 +010066 * Construct a new SpanFocusQuery. The class to focus on defaults
67 * to
68 * <tt>1</tt>.
Nils Diewaldbb33da22015-03-04 16:24:25 +000069 *
margaretha50c76332015-03-19 10:10:39 +010070 * @param firstClause
Nils Diewaldbb33da22015-03-04 16:24:25 +000071 * The nested {@link SpanQuery}, that contains one or
margaretha50c76332015-03-19 10:10:39 +010072 * more
73 * classed spans.
Nils Diewald85f9c422015-02-06 21:09:16 +000074 */
margaretha50c76332015-03-19 10:10:39 +010075 public SpanFocusQuery (SpanQuery sq) {
76 super(sq, true);
77 classNumbers.add((byte) 1);
Nils Diewaldf399a672013-11-18 17:55:22 +000078 };
79
Nils Diewald85f9c422015-02-06 21:09:16 +000080
Nils Diewaldf399a672013-11-18 17:55:22 +000081 @Override
82 public String toString (String field) {
Nils Diewald85f9c422015-02-06 21:09:16 +000083 StringBuffer buffer = new StringBuffer();
84 buffer.append("focus(");
Akronbb5d1732015-06-22 01:22:40 +020085 if (matchTemporaryClass) {
margarethaf70addb2015-04-27 13:17:18 +020086 buffer.append("#");
87 }
margaretha50c76332015-03-19 10:10:39 +010088 if (classNumbers.size() > 1) {
89 buffer.append("[");
90 for (int i = 0; i < classNumbers.size(); i++) {
91 buffer.append((short) classNumbers.get(i) & 0xFF);
92 if (i != classNumbers.size() - 1) {
93 buffer.append(",");
94 }
95 }
96 buffer.append("]");
97 }
98 else {
99 buffer.append((short) classNumbers.get(0) & 0xFF).append(": ");
100 }
101 buffer.append(this.firstClause.toString());
Akrona26184e2018-12-05 15:37:34 +0100102 if (!this.isSorted()) {
103 buffer.append(",sorting");
104 }
Nils Diewald85f9c422015-02-06 21:09:16 +0000105 buffer.append(')');
106 buffer.append(ToStringUtils.boost(getBoost()));
107 return buffer.toString();
Nils Diewaldf399a672013-11-18 17:55:22 +0000108 };
109
Nils Diewald85f9c422015-02-06 21:09:16 +0000110
Nils Diewaldf399a672013-11-18 17:55:22 +0000111 @Override
Akron700c1eb2015-09-25 16:57:30 +0200112 public Spans getSpans (final LeafReaderContext context, Bits acceptDocs,
Nils Diewaldbb33da22015-03-04 16:24:25 +0000113 Map<Term, TermContext> termContexts) throws IOException {
margaretha50c76332015-03-19 10:10:39 +0100114 return new FocusSpans(this, context, acceptDocs, termContexts);
Nils Diewaldf399a672013-11-18 17:55:22 +0000115 };
116
Nils Diewald85f9c422015-02-06 21:09:16 +0000117
Nils Diewaldf399a672013-11-18 17:55:22 +0000118 @Override
119 public Query rewrite (IndexReader reader) throws IOException {
Nils Diewaldcec40f92015-02-19 22:20:02 +0000120 SpanFocusQuery clone = null;
margaretha50c76332015-03-19 10:10:39 +0100121 SpanQuery query = (SpanQuery) this.firstClause.rewrite(reader);
Nils Diewaldbb33da22015-03-04 16:24:25 +0000122
margaretha50c76332015-03-19 10:10:39 +0100123 if (query != this.firstClause) {
Nils Diewald85f9c422015-02-06 21:09:16 +0000124 if (clone == null)
125 clone = this.clone();
margaretha50c76332015-03-19 10:10:39 +0100126 clone.firstClause = query;
Nils Diewald85f9c422015-02-06 21:09:16 +0000127 };
Nils Diewaldf399a672013-11-18 17:55:22 +0000128
Nils Diewald85f9c422015-02-06 21:09:16 +0000129 if (clone != null)
130 return clone;
Nils Diewaldf399a672013-11-18 17:55:22 +0000131
Nils Diewald85f9c422015-02-06 21:09:16 +0000132 return this;
Nils Diewaldf399a672013-11-18 17:55:22 +0000133 };
134
Nils Diewald85f9c422015-02-06 21:09:16 +0000135
Nils Diewaldf399a672013-11-18 17:55:22 +0000136 @Override
Nils Diewaldbb33da22015-03-04 16:24:25 +0000137 public SpanFocusQuery clone () {
Nils Diewaldcec40f92015-02-19 22:20:02 +0000138 SpanFocusQuery spanFocusQuery = new SpanFocusQuery(
margaretha50c76332015-03-19 10:10:39 +0100139 (SpanQuery) this.firstClause.clone(), this.getClassNumbers());
Nils Diewaldcec40f92015-02-19 22:20:02 +0000140 spanFocusQuery.setBoost(getBoost());
margarethaf70addb2015-04-27 13:17:18 +0200141 spanFocusQuery.setMatchTemporaryClass(this.matchTemporaryClass);
142 spanFocusQuery.setSorted(this.isSorted);
143 spanFocusQuery.setRemoveTemporaryClasses(this.removeTemporaryClasses);
Nils Diewaldcec40f92015-02-19 22:20:02 +0000144 return spanFocusQuery;
Nils Diewaldf399a672013-11-18 17:55:22 +0000145 };
146
147
Nils Diewaldf399a672013-11-18 17:55:22 +0000148 @Override
Nils Diewald85f9c422015-02-06 21:09:16 +0000149 public boolean equals (Object o) {
Nils Diewaldbb33da22015-03-04 16:24:25 +0000150 if (this == o)
151 return true;
152 if (!(o instanceof SpanFocusQuery))
153 return false;
154
155 final SpanFocusQuery spanFocusQuery = (SpanFocusQuery) o;
156
margaretha50c76332015-03-19 10:10:39 +0100157 if (!this.firstClause.equals(spanFocusQuery.firstClause))
Nils Diewaldbb33da22015-03-04 16:24:25 +0000158 return false;
margaretha50c76332015-03-19 10:10:39 +0100159 if (this.getClassNumbers() != spanFocusQuery.getClassNumbers())
Nils Diewaldbb33da22015-03-04 16:24:25 +0000160 return false;
Nils Diewaldcec40f92015-02-19 22:20:02 +0000161
162 // Probably not necessary
163 return getBoost() == spanFocusQuery.getBoost();
Nils Diewaldf399a672013-11-18 17:55:22 +0000164 };
165
166
Nils Diewaldf399a672013-11-18 17:55:22 +0000167 @Override
Nils Diewald3e3cbf32015-02-06 21:30:49 +0000168 public int hashCode () {
margaretha50c76332015-03-19 10:10:39 +0100169 int result = firstClause.hashCode();
170 for (byte number : classNumbers)
171 result = 31 * result + number;
Nils Diewald85f9c422015-02-06 21:09:16 +0000172 result += Float.floatToRawIntBits(getBoost());
173 return result;
margaretha50c76332015-03-19 10:10:39 +0100174 }
175
176
177 public List<Byte> getClassNumbers () {
178 return classNumbers;
179 }
180
181
182 public void setClassNumbers (List<Byte> classNumbers) {
183 this.classNumbers = classNumbers;
184 }
185
186
187 public boolean isSorted () {
188 return isSorted;
189 }
190
191
192 public void setSorted (boolean isSorted) {
193 this.isSorted = isSorted;
194 }
195
Akronbb5d1732015-06-22 01:22:40 +0200196
197 public boolean matchTemporaryClass () {
margarethaf70addb2015-04-27 13:17:18 +0200198 return matchTemporaryClass;
199 }
200
Akronbb5d1732015-06-22 01:22:40 +0200201
202 public void setMatchTemporaryClass (boolean matchTemporaryClass) {
margarethaf70addb2015-04-27 13:17:18 +0200203 this.matchTemporaryClass = matchTemporaryClass;
204 }
205
Akronbb5d1732015-06-22 01:22:40 +0200206
207 public boolean removeTemporaryClasses () {
margarethaf70addb2015-04-27 13:17:18 +0200208 return removeTemporaryClasses;
209 }
210
Akronbb5d1732015-06-22 01:22:40 +0200211
212 public void setRemoveTemporaryClasses (boolean rem) {
margarethaf70addb2015-04-27 13:17:18 +0200213 this.removeTemporaryClasses = rem;
214 }
215
margaretha3865e522016-05-02 13:24:51 +0200216
Akronc12567c2016-06-03 00:40:52 +0200217 public int getWindowSize () {
margaretha3865e522016-05-02 13:24:51 +0200218 return windowSize;
219 }
220
221
Akronc12567c2016-06-03 00:40:52 +0200222 public void setWindowSize (int windowSize) {
margaretha3865e522016-05-02 13:24:51 +0200223 this.windowSize = windowSize;
224 }
225
Nils Diewaldf399a672013-11-18 17:55:22 +0000226};