|
22 | 22 | import com.google.common.collect.Lists; |
23 | 23 | import com.google.common.collect.Sets; |
24 | 24 | import org.apache.lucene.search.vectorhighlight.SimpleBoundaryScanner; |
| 25 | +import org.elasticsearch.ElasticsearchIllegalArgumentException; |
25 | 26 | import org.elasticsearch.common.collect.Tuple; |
26 | 27 | import org.elasticsearch.common.xcontent.XContentParser; |
| 28 | +import org.elasticsearch.index.query.IndexQueryParserService; |
27 | 29 | import org.elasticsearch.search.SearchParseElement; |
28 | 30 | import org.elasticsearch.search.SearchParseException; |
29 | 31 | import org.elasticsearch.search.internal.SearchContext; |
@@ -66,11 +68,19 @@ public class HighlighterParseElement implements SearchParseElement { |
66 | 68 |
|
67 | 69 | @Override |
68 | 70 | public void parse(XContentParser parser, SearchContext context) throws Exception { |
| 71 | + try { |
| 72 | + context.highlight(parse(parser, context.queryParserService())); |
| 73 | + } catch (ElasticsearchIllegalArgumentException ex) { |
| 74 | + throw new SearchParseException(context, "Error while trying to parse Highlighter element in request"); |
| 75 | + } |
| 76 | + } |
| 77 | + |
| 78 | + public SearchContextHighlight parse(XContentParser parser, IndexQueryParserService queryParserService) throws IOException { |
69 | 79 | XContentParser.Token token; |
70 | 80 | String topLevelFieldName = null; |
71 | | - List<Tuple<String, SearchContextHighlight.FieldOptions.Builder>> fieldsOptions = newArrayList(); |
| 81 | + final List<Tuple<String, SearchContextHighlight.FieldOptions.Builder>> fieldsOptions = newArrayList(); |
72 | 82 |
|
73 | | - SearchContextHighlight.FieldOptions.Builder globalOptionsBuilder = new SearchContextHighlight.FieldOptions.Builder() |
| 83 | + final SearchContextHighlight.FieldOptions.Builder globalOptionsBuilder = new SearchContextHighlight.FieldOptions.Builder() |
74 | 84 | .preTags(DEFAULT_PRE_TAGS).postTags(DEFAULT_POST_TAGS).scoreOrdered(false).highlightFilter(false) |
75 | 85 | .requireFieldMatch(false).forceSource(false).fragmentCharSize(100).numberOfFragments(5) |
76 | 86 | .encoder("default").boundaryMaxScan(SimpleBoundaryScanner.DEFAULT_MAX_SCAN) |
@@ -100,15 +110,15 @@ public void parse(XContentParser parser, SearchContext context) throws Exception |
100 | 110 | while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { |
101 | 111 | if (token == XContentParser.Token.FIELD_NAME) { |
102 | 112 | if (highlightFieldName != null) { |
103 | | - throw new SearchParseException(context, "If highlighter fields is an array it must contain objects containing a single field"); |
| 113 | + throw new ElasticsearchIllegalArgumentException("If highlighter fields is an array it must contain objects containing a single field"); |
104 | 114 | } |
105 | 115 | highlightFieldName = parser.currentName(); |
106 | 116 | } else if (token == XContentParser.Token.START_OBJECT) { |
107 | | - fieldsOptions.add(Tuple.tuple(highlightFieldName, parseFields(parser, context))); |
| 117 | + fieldsOptions.add(Tuple.tuple(highlightFieldName, parseFields(parser, queryParserService))); |
108 | 118 | } |
109 | 119 | } |
110 | 120 | } else { |
111 | | - throw new SearchParseException(context, "If highlighter fields is an array it must contain objects containing a single field"); |
| 121 | + throw new ElasticsearchIllegalArgumentException("If highlighter fields is an array it must contain objects containing a single field"); |
112 | 122 | } |
113 | 123 | } |
114 | 124 | } |
@@ -160,33 +170,32 @@ public void parse(XContentParser parser, SearchContext context) throws Exception |
160 | 170 | if (token == XContentParser.Token.FIELD_NAME) { |
161 | 171 | highlightFieldName = parser.currentName(); |
162 | 172 | } else if (token == XContentParser.Token.START_OBJECT) { |
163 | | - fieldsOptions.add(Tuple.tuple(highlightFieldName, parseFields(parser, context))); |
| 173 | + fieldsOptions.add(Tuple.tuple(highlightFieldName, parseFields(parser, queryParserService))); |
164 | 174 | } |
165 | 175 | } |
166 | 176 | } else if ("highlight_query".equals(topLevelFieldName) || "highlightQuery".equals(topLevelFieldName)) { |
167 | | - globalOptionsBuilder.highlightQuery(context.queryParserService().parse(parser).query()); |
| 177 | + globalOptionsBuilder.highlightQuery(queryParserService.parse(parser).query()); |
168 | 178 | } |
169 | 179 | } |
170 | 180 | } |
171 | 181 |
|
172 | | - SearchContextHighlight.FieldOptions globalOptions = globalOptionsBuilder.build(); |
| 182 | + final SearchContextHighlight.FieldOptions globalOptions = globalOptionsBuilder.build(); |
173 | 183 | if (globalOptions.preTags() != null && globalOptions.postTags() == null) { |
174 | | - throw new SearchParseException(context, "Highlighter global preTags are set, but global postTags are not set"); |
| 184 | + throw new ElasticsearchIllegalArgumentException("Highlighter global preTags are set, but global postTags are not set"); |
175 | 185 | } |
176 | 186 |
|
177 | | - List<SearchContextHighlight.Field> fields = Lists.newArrayList(); |
| 187 | + final List<SearchContextHighlight.Field> fields = Lists.newArrayList(); |
178 | 188 | // now, go over and fill all fieldsOptions with default values from the global state |
179 | | - for (Tuple<String, SearchContextHighlight.FieldOptions.Builder> tuple : fieldsOptions) { |
| 189 | + for (final Tuple<String, SearchContextHighlight.FieldOptions.Builder> tuple : fieldsOptions) { |
180 | 190 | fields.add(new SearchContextHighlight.Field(tuple.v1(), tuple.v2().merge(globalOptions).build())); |
181 | 191 | } |
182 | | - |
183 | | - context.highlight(new SearchContextHighlight(fields)); |
| 192 | + return new SearchContextHighlight(fields); |
184 | 193 | } |
185 | 194 |
|
186 | | - private SearchContextHighlight.FieldOptions.Builder parseFields(XContentParser parser, SearchContext context) throws IOException { |
| 195 | + protected SearchContextHighlight.FieldOptions.Builder parseFields(XContentParser parser, IndexQueryParserService queryParserService) throws IOException { |
187 | 196 | XContentParser.Token token; |
188 | 197 |
|
189 | | - SearchContextHighlight.FieldOptions.Builder fieldOptionsBuilder = new SearchContextHighlight.FieldOptions.Builder(); |
| 198 | + final SearchContextHighlight.FieldOptions.Builder fieldOptionsBuilder = new SearchContextHighlight.FieldOptions.Builder(); |
190 | 199 | String fieldName = null; |
191 | 200 | while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { |
192 | 201 | if (token == XContentParser.Token.FIELD_NAME) { |
@@ -246,7 +255,7 @@ private SearchContextHighlight.FieldOptions.Builder parseFields(XContentParser p |
246 | 255 | } |
247 | 256 | } else if (token == XContentParser.Token.START_OBJECT) { |
248 | 257 | if ("highlight_query".equals(fieldName) || "highlightQuery".equals(fieldName)) { |
249 | | - fieldOptionsBuilder.highlightQuery(context.queryParserService().parse(parser).query()); |
| 258 | + fieldOptionsBuilder.highlightQuery(queryParserService.parse(parser).query()); |
250 | 259 | } else if ("options".equals(fieldName)) { |
251 | 260 | fieldOptionsBuilder.options(parser.map()); |
252 | 261 | } |
|
0 commit comments