| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 1 | package de.ids_mannheim.korap.query; |
| 2 | |
| 3 | // Based on SpanNearQuery |
| 4 | import java.io.IOException; |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 5 | import java.util.Map; |
| 6 | import java.util.Set; |
| 7 | |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 8 | import org.apache.lucene.index.IndexReader; |
| Eliza Margaretha | dc98dc1 | 2016-11-16 14:33:42 +0100 | [diff] [blame] | 9 | import org.apache.lucene.index.LeafReaderContext; |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 10 | import org.apache.lucene.index.Term; |
| 11 | import org.apache.lucene.index.TermContext; |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 12 | import org.apache.lucene.search.Query; |
| 13 | import org.apache.lucene.search.spans.SpanQuery; |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 14 | import org.apache.lucene.search.spans.Spans; |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 15 | import org.apache.lucene.util.Bits; |
| 16 | import org.apache.lucene.util.ToStringUtils; |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 17 | |
| 18 | import de.ids_mannheim.korap.query.spans.WithinSpans; |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 19 | |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 20 | |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 21 | /** |
| 22 | * Matches spans that are within certain elements. |
| 23 | */ |
| 24 | public class SpanWithinQuery extends SpanQuery implements Cloneable { |
| 25 | private SpanQuery wrap; |
| 26 | private SpanQuery embedded; |
| 27 | public String field; |
| Nils Diewald | 6802acd | 2014-03-18 18:29:30 +0000 | [diff] [blame] | 28 | private byte flag; |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 29 | private boolean collectPayloads; |
| 30 | |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 31 | public static final byte OVERLAP = WithinSpans.OVERLAP, |
| 32 | REAL_OVERLAP = WithinSpans.REAL_OVERLAP, |
| 33 | WITHIN = WithinSpans.WITHIN, REAL_WITHIN = WithinSpans.REAL_WITHIN, |
| 34 | ENDSWITH = WithinSpans.ENDSWITH, |
| 35 | STARTSWITH = WithinSpans.STARTSWITH, MATCH = WithinSpans.MATCH; |
| 36 | |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 37 | |
| 38 | // may support "starting" and "ending" |
| 39 | |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 40 | |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 41 | // Constructor |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 42 | public SpanWithinQuery (SpanQuery wrap, SpanQuery embedded, byte flag, |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 43 | boolean collectPayloads) { |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 44 | |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 45 | this.field = embedded.getField(); |
| 46 | this.embedded = embedded; |
| 47 | this.wrap = wrap; |
| 48 | this.flag = flag; |
| 49 | this.collectPayloads = collectPayloads; |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 50 | }; |
| 51 | |
| 52 | |
| 53 | // Constructor |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 54 | public SpanWithinQuery (String element, SpanQuery embedded) { |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 55 | this(element, embedded, WITHIN, true); |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 56 | }; |
| 57 | |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 58 | |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 59 | // Constructor |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 60 | public SpanWithinQuery (String element, SpanQuery embedded, byte flag, |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 61 | boolean collectPayloads) { |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 62 | this((SpanQuery) new SpanElementQuery(embedded.getField(), element), |
| 63 | embedded, flag, collectPayloads); |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 64 | }; |
| 65 | |
| 66 | |
| 67 | // Constructor |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 68 | public SpanWithinQuery (String element, SpanQuery embedded, byte flag) { |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 69 | this(element, embedded, flag, true); |
| 70 | }; |
| 71 | |
| 72 | |
| 73 | // Constructor |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 74 | public SpanWithinQuery (String element, SpanQuery embedded, |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 75 | boolean collectPayloads) { |
| 76 | this(element, embedded, WITHIN, collectPayloads); |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 77 | }; |
| 78 | |
| 79 | |
| 80 | // Constructor |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 81 | public SpanWithinQuery (SpanQuery wrap, SpanQuery embedded, byte flag) { |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 82 | this(wrap, embedded, flag, true); |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 83 | }; |
| 84 | |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 85 | |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 86 | // Constructor |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 87 | public SpanWithinQuery (SpanQuery wrap, SpanQuery embedded) { |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 88 | this(wrap, embedded, WITHIN, true); |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 89 | }; |
| 90 | |
| 91 | |
| 92 | @Override |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 93 | public String getField () { |
| 94 | return field; |
| 95 | }; |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 96 | |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 97 | |
| 98 | public SpanQuery wrap () { |
| 99 | return wrap; |
| 100 | }; |
| 101 | |
| 102 | |
| 103 | public SpanQuery embedded () { |
| 104 | return embedded; |
| 105 | }; |
| 106 | |
| 107 | |
| 108 | public byte flag () { |
| 109 | return flag; |
| 110 | }; |
| 111 | |
| 112 | |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 113 | @Override |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 114 | public void extractTerms (Set<Term> terms) { |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 115 | embedded.extractTerms(terms); |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 116 | }; |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 117 | |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 118 | |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 119 | @Override |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 120 | public String toString (String field) { |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 121 | StringBuilder buffer = new StringBuilder(); |
| 122 | buffer.append("span"); |
| 123 | buffer.append(flagToString()); |
| 124 | buffer.append("("); |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 125 | buffer.append(wrap.toString()); |
| 126 | buffer.append(", "); |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 127 | buffer.append(embedded.toString(field)); |
| 128 | buffer.append(")"); |
| 129 | buffer.append(ToStringUtils.boost(getBoost())); |
| 130 | return buffer.toString(); |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 131 | }; |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 132 | |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 133 | |
| Nils Diewald | 6802acd | 2014-03-18 18:29:30 +0000 | [diff] [blame] | 134 | private String flagToString () { |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 135 | switch (flag) { |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 136 | case OVERLAP: |
| 137 | return "Overlap"; |
| 138 | case REAL_OVERLAP: |
| 139 | return "OverlapStrict"; |
| 140 | case WITHIN: |
| 141 | return "Contain"; |
| 142 | case REAL_WITHIN: |
| 143 | return "ContainStrict"; |
| 144 | case ENDSWITH: |
| 145 | return "EndsWith"; |
| 146 | case STARTSWITH: |
| 147 | return "StartsWith"; |
| 148 | case MATCH: |
| 149 | return "Match"; |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 150 | }; |
| 151 | return "Contains"; |
| Nils Diewald | 6802acd | 2014-03-18 18:29:30 +0000 | [diff] [blame] | 152 | }; |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 153 | |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 154 | |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 155 | @Override |
| Akron | 700c1eb | 2015-09-25 16:57:30 +0200 | [diff] [blame] | 156 | public Spans getSpans (final LeafReaderContext context, Bits acceptDocs, |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 157 | Map<Term, TermContext> termContexts) throws IOException { |
| 158 | return (Spans) new WithinSpans(this, context, acceptDocs, termContexts, |
| 159 | this.flag); |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 160 | }; |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 161 | |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 162 | |
| Nils Diewald | ea12520 | 2014-09-19 15:12:06 +0000 | [diff] [blame] | 163 | /* |
| 164 | * Rewrite query in case it includes regular expressions or wildcards |
| 165 | */ |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 166 | @Override |
| 167 | public Query rewrite (IndexReader reader) throws IOException { |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 168 | SpanWithinQuery clone = null; |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 169 | |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 170 | // Does the embedded query needs a rewrite? |
| 171 | SpanQuery query = (SpanQuery) embedded.rewrite(reader); |
| 172 | if (query != embedded) { |
| 173 | if (clone == null) |
| 174 | clone = this.clone(); |
| 175 | clone.embedded = query; |
| 176 | }; |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 177 | |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 178 | // Does the wrap query needs a rewrite? |
| 179 | query = (SpanQuery) wrap.rewrite(reader); |
| 180 | if (query != wrap) { |
| 181 | if (clone == null) |
| 182 | clone = this.clone(); |
| 183 | clone.wrap = query; |
| 184 | }; |
| Nils Diewald | ea12520 | 2014-09-19 15:12:06 +0000 | [diff] [blame] | 185 | |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 186 | // There is a clone and it is important |
| 187 | if (clone != null) |
| 188 | return clone; |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 189 | |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 190 | return this; |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 191 | }; |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 192 | |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 193 | |
| 194 | @Override |
| 195 | public SpanWithinQuery clone () { |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 196 | SpanWithinQuery spanWithinQuery = new SpanWithinQuery( |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 197 | (SpanQuery) wrap.clone(), (SpanQuery) embedded.clone(), |
| 198 | this.flag, this.collectPayloads); |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 199 | spanWithinQuery.setBoost(getBoost()); |
| 200 | return spanWithinQuery; |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 201 | }; |
| 202 | |
| 203 | |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 204 | /** |
| 205 | * Returns true iff <code>o</code> is equal to this. |
| 206 | */ |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 207 | @Override |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 208 | public boolean equals (Object o) { |
| 209 | if (this == o) |
| 210 | return true; |
| 211 | if (!(o instanceof SpanWithinQuery)) |
| 212 | return false; |
| 213 | |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 214 | final SpanWithinQuery spanWithinQuery = (SpanWithinQuery) o; |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 215 | |
| 216 | if (collectPayloads != spanWithinQuery.collectPayloads) |
| 217 | return false; |
| 218 | if (!wrap.equals(spanWithinQuery.wrap)) |
| 219 | return false; |
| 220 | if (!embedded.equals(spanWithinQuery.embedded)) |
| 221 | return false; |
| 222 | |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 223 | return getBoost() == spanWithinQuery.getBoost(); |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 224 | }; |
| 225 | |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 226 | |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 227 | // I don't know what I am doing here |
| 228 | @Override |
| Nils Diewald | bb33da2 | 2015-03-04 16:24:25 +0000 | [diff] [blame] | 229 | public int hashCode () { |
| Nils Diewald | 93d6d1b | 2015-02-02 21:47:43 +0000 | [diff] [blame] | 230 | int result = flag; |
| 231 | result = embedded.hashCode(); |
| 232 | result += wrap.hashCode(); |
| 233 | result ^= (result << 4) | (result >>> 29); |
| 234 | result += Float.floatToRawIntBits(getBoost()); |
| 235 | return result; |
| Nils Diewald | f399a67 | 2013-11-18 17:55:22 +0000 | [diff] [blame] | 236 | }; |
| 237 | }; |