diff options
41 files changed, 202 insertions, 379 deletions
diff --git a/core/src/main/java/org/elasticsearch/plugins/SearchPlugin.java b/core/src/main/java/org/elasticsearch/plugins/SearchPlugin.java index 59cbbeafff..b68176d8f0 100644 --- a/core/src/main/java/org/elasticsearch/plugins/SearchPlugin.java +++ b/core/src/main/java/org/elasticsearch/plugins/SearchPlugin.java @@ -46,6 +46,7 @@ import org.elasticsearch.search.aggregations.pipeline.movavg.models.MovAvgModel; import org.elasticsearch.search.fetch.FetchSubPhase; import org.elasticsearch.search.fetch.subphase.highlight.Highlighter; import org.elasticsearch.search.suggest.Suggester; +import org.elasticsearch.search.suggest.SuggestionBuilder; import java.util.List; import java.util.Map; @@ -99,8 +100,8 @@ public interface SearchPlugin { /** * The new {@link Suggester}s defined by this plugin. */ - default Map<String, Suggester<?>> getSuggesters() { - return emptyMap(); + default List<SuggesterSpec<?>> getSuggesters() { + return emptyList(); } /** * The new {@link Query}s defined by this plugin. @@ -135,6 +136,38 @@ public interface SearchPlugin { } /** + * Specification for a {@link Suggester}. + */ + class SuggesterSpec<T extends SuggestionBuilder<T>> extends SearchExtensionSpec<T, NoContextParser<T>> { + /** + * Specification of custom {@link Suggester}. + * + * @param name holds the names by which this suggester might be parsed. The {@link ParseField#getPreferredName()} is special as it + * is the name by under which the reader is registered. So it is the name that the query should use as its + * {@link NamedWriteable#getWriteableName()} too. + * @param reader the reader registered for this suggester's builder. Typically a reference to a constructor that takes a + * {@link StreamInput} + * @param parser the parser the reads the query suggester from xcontent + */ + public SuggesterSpec(ParseField name, Writeable.Reader<T> reader, NoContextParser<T> parser) { + super(name, reader, parser); + } + + /** + * Specification of custom {@link Suggester}. + * + * @param name the name by which this suggester might be parsed or deserialized. Make sure that the query builder returns this name + * for {@link NamedWriteable#getWriteableName()}. + * @param reader the reader registered for this suggester's builder. Typically a reference to a constructor that takes a + * {@link StreamInput} + * @param parser the parser the reads the suggester builder from xcontent + */ + public SuggesterSpec(String name, Writeable.Reader<T> reader, NoContextParser<T> parser) { + super(name, reader, parser); + } + } + + /** * Specification of custom {@link Query}. */ class QuerySpec<T extends QueryBuilder> extends SearchExtensionSpec<T, QueryParser<T>> { diff --git a/core/src/main/java/org/elasticsearch/rest/action/search/RestMultiSearchAction.java b/core/src/main/java/org/elasticsearch/rest/action/search/RestMultiSearchAction.java index 046ee382ba..073cc6bee8 100644 --- a/core/src/main/java/org/elasticsearch/rest/action/search/RestMultiSearchAction.java +++ b/core/src/main/java/org/elasticsearch/rest/action/search/RestMultiSearchAction.java @@ -90,7 +90,7 @@ public class RestMultiSearchAction extends BaseRestHandler { parseMultiLineRequest(restRequest, multiRequest.indicesOptions(), allowExplicitIndex, (searchRequest, parser) -> { try { final QueryParseContext queryParseContext = new QueryParseContext(parser, parseFieldMatcher); - searchRequest.source(SearchSourceBuilder.fromXContent(queryParseContext, searchRequestParsers.suggesters)); + searchRequest.source(SearchSourceBuilder.fromXContent(queryParseContext)); multiRequest.add(searchRequest); } catch (IOException e) { throw new ElasticsearchParseException("Exception when parsing search request", e); diff --git a/core/src/main/java/org/elasticsearch/rest/action/search/RestSearchAction.java b/core/src/main/java/org/elasticsearch/rest/action/search/RestSearchAction.java index 23ec7ef39c..fe4fe4a4f1 100644 --- a/core/src/main/java/org/elasticsearch/rest/action/search/RestSearchAction.java +++ b/core/src/main/java/org/elasticsearch/rest/action/search/RestSearchAction.java @@ -93,7 +93,7 @@ public class RestSearchAction extends BaseRestHandler { searchRequest.indices(Strings.splitStringByCommaToArray(request.param("index"))); if (requestContentParser != null) { QueryParseContext context = new QueryParseContext(requestContentParser, parseFieldMatcher); - searchRequest.source().parseXContent(context, searchRequestParsers.suggesters); + searchRequest.source().parseXContent(context); } // do not allow 'query_and_fetch' or 'dfs_query_and_fetch' search types diff --git a/core/src/main/java/org/elasticsearch/search/SearchModule.java b/core/src/main/java/org/elasticsearch/search/SearchModule.java index 3817b6c507..951855820a 100644 --- a/core/src/main/java/org/elasticsearch/search/SearchModule.java +++ b/core/src/main/java/org/elasticsearch/search/SearchModule.java @@ -93,6 +93,7 @@ import org.elasticsearch.plugins.SearchPlugin.QuerySpec; import org.elasticsearch.plugins.SearchPlugin.ScoreFunctionSpec; import org.elasticsearch.plugins.SearchPlugin.SearchExtSpec; import org.elasticsearch.plugins.SearchPlugin.SearchExtensionSpec; +import org.elasticsearch.plugins.SearchPlugin.SuggesterSpec; import org.elasticsearch.search.aggregations.AggregationBuilder; import org.elasticsearch.search.aggregations.AggregatorFactories; import org.elasticsearch.search.aggregations.BaseAggregationBuilder; @@ -238,16 +239,14 @@ import org.elasticsearch.search.sort.GeoDistanceSortBuilder; import org.elasticsearch.search.sort.ScoreSortBuilder; import org.elasticsearch.search.sort.ScriptSortBuilder; import org.elasticsearch.search.sort.SortBuilder; -import org.elasticsearch.search.suggest.Suggester; -import org.elasticsearch.search.suggest.Suggesters; import org.elasticsearch.search.suggest.SuggestionBuilder; -import org.elasticsearch.search.suggest.completion.CompletionSuggester; +import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; import org.elasticsearch.search.suggest.phrase.Laplace; import org.elasticsearch.search.suggest.phrase.LinearInterpolation; -import org.elasticsearch.search.suggest.phrase.PhraseSuggester; +import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder; import org.elasticsearch.search.suggest.phrase.SmoothingModel; import org.elasticsearch.search.suggest.phrase.StupidBackoff; -import org.elasticsearch.search.suggest.term.TermSuggester; +import org.elasticsearch.search.suggest.term.TermSuggestionBuilder; import java.util.ArrayList; import java.util.List; @@ -267,7 +266,6 @@ public class SearchModule { private final boolean transportClient; private final Map<String, Highlighter> highlighters; - private final Map<String, Suggester<?>> suggesters; private final ParseFieldRegistry<SignificanceHeuristicParser> significanceHeuristicParserRegistry = new ParseFieldRegistry<>( "significance_heuristic"); private final ParseFieldRegistry<MovAvgModel.AbstractModelParser> movingAverageModelParserRegistry = new ParseFieldRegistry<>( @@ -283,7 +281,7 @@ public class SearchModule { public SearchModule(Settings settings, boolean transportClient, List<SearchPlugin> plugins) { this.settings = settings; this.transportClient = transportClient; - suggesters = setupSuggesters(plugins); + registerSuggesters(plugins); highlighters = setupHighlighters(settings, plugins); registerScoreFunctions(plugins); registerQueryParsers(plugins); @@ -297,7 +295,7 @@ public class SearchModule { registerFetchSubPhases(plugins); registerSearchExts(plugins); registerShapes(); - searchRequestParsers = new SearchRequestParsers(getSuggesters()); + searchRequestParsers = new SearchRequestParsers(); } public List<NamedWriteableRegistry.Entry> getNamedWriteables() { @@ -308,10 +306,6 @@ public class SearchModule { return namedXContents; } - public Suggesters getSuggesters() { - return new Suggesters(suggesters); - } - public SearchRequestParsers getSearchRequestParsers() { return searchRequestParsers; } @@ -565,23 +559,22 @@ public class SearchModule { namedWriteables.add(new NamedWriteableRegistry.Entry(SmoothingModel.class, StupidBackoff.NAME, StupidBackoff::new)); } - private Map<String, Suggester<?>> setupSuggesters(List<SearchPlugin> plugins) { + private void registerSuggesters(List<SearchPlugin> plugins) { registerSmoothingModels(namedWriteables); - // Suggester<?> is weird - it is both a Parser and a reader.... - NamedRegistry<Suggester<?>> suggesters = new NamedRegistry<Suggester<?>>("suggester") { - @Override - public void register(String name, Suggester<?> t) { - super.register(name, t); - namedWriteables.add(new NamedWriteableRegistry.Entry(SuggestionBuilder.class, name, t)); - } - }; - suggesters.register("phrase", PhraseSuggester.INSTANCE); - suggesters.register("term", TermSuggester.INSTANCE); - suggesters.register("completion", CompletionSuggester.INSTANCE); + registerSuggester(new SuggesterSpec<>("term", TermSuggestionBuilder::new, TermSuggestionBuilder::fromXContent)); + registerSuggester(new SuggesterSpec<>("phrase", PhraseSuggestionBuilder::new, PhraseSuggestionBuilder::fromXContent)); + registerSuggester(new SuggesterSpec<>("completion", CompletionSuggestionBuilder::new, CompletionSuggestionBuilder::fromXContent)); - suggesters.extractAndRegister(plugins, SearchPlugin::getSuggesters); - return unmodifiableMap(suggesters.getRegistry()); + registerFromPlugin(plugins, SearchPlugin::getSuggesters, this::registerSuggester); + } + + private void registerSuggester(SuggesterSpec<?> suggester) { + namedWriteables.add(new NamedWriteableRegistry.Entry( + SuggestionBuilder.class, suggester.getName().getPreferredName(), suggester.getReader())); + // TODO Merge NoContextParser and FromXContent + namedXContents.add(new NamedXContentRegistry.Entry(SuggestionBuilder.class, suggester.getName(), + p -> suggester.getParser().parse(p))); } private Map<String, Highlighter> setupHighlighters(Settings settings, List<SearchPlugin> plugins) { diff --git a/core/src/main/java/org/elasticsearch/search/SearchRequestParsers.java b/core/src/main/java/org/elasticsearch/search/SearchRequestParsers.java index cb3e82fe2c..8a3186ad1d 100644 --- a/core/src/main/java/org/elasticsearch/search/SearchRequestParsers.java +++ b/core/src/main/java/org/elasticsearch/search/SearchRequestParsers.java @@ -19,25 +19,11 @@ package org.elasticsearch.search; -import org.elasticsearch.search.suggest.Suggesters; - /** * A container for all parsers used to parse * {@link org.elasticsearch.action.search.SearchRequest} objects from a rest request. */ public class SearchRequestParsers { - // TODO: this class should be renamed to SearchRequestParser, and all the parse - // methods split across RestSearchAction and SearchSourceBuilder should be moved here - // TODO: make all members private once parsing functions are moved here - - // TODO: Suggesters should be removed and the underlying map moved here - /** - * Suggesters that may be used in search requests. - * @see org.elasticsearch.search.builder.SearchSourceBuilder#fromXContent(QueryParseContext, Suggesters) - */ - public final Suggesters suggesters; - - public SearchRequestParsers(Suggesters suggesters) { - this.suggesters = suggesters; + public SearchRequestParsers() { } } diff --git a/core/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java b/core/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java index e759842d54..c1d9cd115a 100644 --- a/core/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/builder/SearchSourceBuilder.java @@ -53,7 +53,6 @@ import org.elasticsearch.search.sort.SortBuilder; import org.elasticsearch.search.sort.SortBuilders; import org.elasticsearch.search.sort.SortOrder; import org.elasticsearch.search.suggest.SuggestBuilder; -import org.elasticsearch.search.suggest.Suggesters; import java.io.IOException; import java.util.ArrayList; @@ -103,9 +102,9 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ public static final ParseField SLICE = new ParseField("slice"); public static final ParseField ALL_FIELDS_FIELDS = new ParseField("all_fields"); - public static SearchSourceBuilder fromXContent(QueryParseContext context, Suggesters suggesters) throws IOException { + public static SearchSourceBuilder fromXContent(QueryParseContext context) throws IOException { SearchSourceBuilder builder = new SearchSourceBuilder(); - builder.parseXContent(context, suggesters); + builder.parseXContent(context); return builder; } @@ -910,9 +909,9 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ /** * Parse some xContent into this SearchSourceBuilder, overwriting any values specified in the xContent. Use this if you need to set up * different defaults than a regular SearchSourceBuilder would have and use - * {@link #fromXContent(QueryParseContext, Suggesters)} if you have normal defaults. + * {@link #fromXContent(QueryParseContext)} if you have normal defaults. */ - public void parseXContent(QueryParseContext context, Suggesters suggesters) throws IOException { + public void parseXContent(QueryParseContext context) throws IOException { XContentParser parser = context.parser(); XContentParser.Token token = parser.currentToken(); String currentFieldName = null; @@ -988,7 +987,7 @@ public final class SearchSourceBuilder extends ToXContentToBytes implements Writ } else if (HIGHLIGHT_FIELD.match(currentFieldName)) { highlightBuilder = HighlightBuilder.fromXContent(context); } else if (SUGGEST_FIELD.match(currentFieldName)) { - suggestBuilder = SuggestBuilder.fromXContent(context, suggesters); + suggestBuilder = SuggestBuilder.fromXContent(context.parser()); } else if (SORT_FIELD.match(currentFieldName)) { sorts = new ArrayList<>(SortBuilder.fromXContent(context)); } else if (RESCORE_FIELD.match(currentFieldName)) { diff --git a/core/src/main/java/org/elasticsearch/search/suggest/SuggestBuilder.java b/core/src/main/java/org/elasticsearch/search/suggest/SuggestBuilder.java index 1de59eb3e2..fec2b0f3bf 100644 --- a/core/src/main/java/org/elasticsearch/search/suggest/SuggestBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/suggest/SuggestBuilder.java @@ -28,7 +28,6 @@ import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.lucene.BytesRefs; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.search.suggest.SuggestionSearchContext.SuggestionContext; @@ -137,8 +136,7 @@ public class SuggestBuilder extends ToXContentToBytes implements Writeable { return builder; } - public static SuggestBuilder fromXContent(QueryParseContext parseContext, Suggesters suggesters) throws IOException { - XContentParser parser = parseContext.parser(); + public static SuggestBuilder fromXContent(XContentParser parser) throws IOException { SuggestBuilder suggestBuilder = new SuggestBuilder(); String fieldName = null; @@ -162,7 +160,7 @@ public class SuggestBuilder extends ToXContentToBytes implements Writeable { if (suggestionName == null) { throw new IllegalArgumentException("suggestion must have name"); } - suggestBuilder.addSuggestion(suggestionName, SuggestionBuilder.fromXContent(parseContext, suggesters)); + suggestBuilder.addSuggestion(suggestionName, SuggestionBuilder.fromXContent(parser)); } else { throw new ParsingException(parser.getTokenLocation(), "unexpected token [" + token + "] after [" + fieldName + "]"); } @@ -193,8 +191,7 @@ public class SuggestBuilder extends ToXContentToBytes implements Writeable { if (other == null || getClass() != other.getClass()) { return false; } - @SuppressWarnings("unchecked") - SuggestBuilder o = (SuggestBuilder)other; + SuggestBuilder o = (SuggestBuilder) other; return Objects.equals(globalText, o.globalText) && Objects.equals(suggestions, o.suggestions); } diff --git a/core/src/main/java/org/elasticsearch/search/suggest/Suggester.java b/core/src/main/java/org/elasticsearch/search/suggest/Suggester.java index 711e3d9db7..6c007bf4cb 100644 --- a/core/src/main/java/org/elasticsearch/search/suggest/Suggester.java +++ b/core/src/main/java/org/elasticsearch/search/suggest/Suggester.java @@ -21,23 +21,16 @@ package org.elasticsearch.search.suggest; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.util.CharsRefBuilder; -import org.elasticsearch.common.io.stream.Writeable; -import org.elasticsearch.index.query.QueryParseContext; import java.io.IOException; -public abstract class Suggester<T extends SuggestionSearchContext.SuggestionContext> implements Writeable.Reader<SuggestionBuilder<?>> { +public abstract class Suggester<T extends SuggestionSearchContext.SuggestionContext> { protected abstract Suggest.Suggestion<? extends Suggest.Suggestion.Entry<? extends Suggest.Suggestion.Entry.Option>> innerExecute(String name, T suggestion, IndexSearcher searcher, CharsRefBuilder spare) throws IOException; - /** - * Read the SuggestionBuilder paired with this Suggester XContent. - */ - public abstract SuggestionBuilder<?> innerFromXContent(QueryParseContext context) throws IOException; - public Suggest.Suggestion<? extends Suggest.Suggestion.Entry<? extends Suggest.Suggestion.Entry.Option>> - execute(String name, T suggestion, IndexSearcher searcher, CharsRefBuilder spare) throws IOException { + execute(String name, T suggestion, IndexSearcher searcher, CharsRefBuilder spare) throws IOException { // #3469 We want to ignore empty shards if (searcher.getIndexReader().numDocs() == 0) { diff --git a/core/src/main/java/org/elasticsearch/search/suggest/Suggesters.java b/core/src/main/java/org/elasticsearch/search/suggest/Suggesters.java deleted file mode 100644 index 3f3f805d8f..0000000000 --- a/core/src/main/java/org/elasticsearch/search/suggest/Suggesters.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.elasticsearch.search.suggest; - -import java.util.Map; - -/** - * Registry of Suggesters. This is only its own class to make Guice happy. - */ -public final class Suggesters { - private final Map<String, Suggester<?>> suggesters; - - public Suggesters(Map<String, Suggester<?>> suggesters) { - this.suggesters = suggesters; - } - - public Suggester<?> getSuggester(String suggesterName) { - Suggester<?> suggester = suggesters.get(suggesterName); - if (suggester == null) { - throw new IllegalArgumentException("suggester with name [" + suggesterName + "] not supported"); - } - return suggester; - } -} diff --git a/core/src/main/java/org/elasticsearch/search/suggest/SuggestionBuilder.java b/core/src/main/java/org/elasticsearch/search/suggest/SuggestionBuilder.java index 2062b696cf..6714778c1b 100644 --- a/core/src/main/java/org/elasticsearch/search/suggest/SuggestionBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/suggest/SuggestionBuilder.java @@ -32,7 +32,6 @@ import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.MapperService; -import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.search.suggest.SuggestionSearchContext.SuggestionContext; @@ -253,9 +252,7 @@ public abstract class SuggestionBuilder<T extends SuggestionBuilder<T>> implemen protected abstract XContentBuilder innerToXContent(XContentBuilder builder, Params params) throws IOException; - static SuggestionBuilder<?> fromXContent(QueryParseContext parseContext, Suggesters suggesters) - throws IOException { - XContentParser parser = parseContext.parser(); + static SuggestionBuilder<?> fromXContent(XContentParser parser) throws IOException { XContentParser.Token token; String currentFieldName = null; String suggestText = null; @@ -277,7 +274,7 @@ public abstract class SuggestionBuilder<T extends SuggestionBuilder<T>> implemen throw new ParsingException(parser.getTokenLocation(), "suggestion does not support [" + currentFieldName + "]"); } } else if (token == XContentParser.Token.START_OBJECT) { - suggestionBuilder = suggesters.getSuggester(currentFieldName).innerFromXContent(parseContext); + suggestionBuilder = parser.namedObject(SuggestionBuilder.class, currentFieldName, null); } } if (suggestionBuilder == null) { diff --git a/core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggester.java b/core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggester.java index 049883822d..625458f2c9 100644 --- a/core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggester.java +++ b/core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggester.java @@ -29,18 +29,14 @@ import org.apache.lucene.search.suggest.document.TopSuggestDocs; import org.apache.lucene.search.suggest.document.TopSuggestDocsCollector; import org.apache.lucene.util.CharsRefBuilder; import org.apache.lucene.util.PriorityQueue; -import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.text.Text; import org.elasticsearch.index.mapper.CompletionFieldMapper; -import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.search.suggest.Suggest; import org.elasticsearch.search.suggest.Suggester; -import org.elasticsearch.search.suggest.SuggestionBuilder; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; -import java.util.Comparator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -241,14 +237,4 @@ public class CompletionSuggester extends Suggester<CompletionSuggestionContext> } } } - - @Override - public SuggestionBuilder<?> innerFromXContent(QueryParseContext context) throws IOException { - return CompletionSuggestionBuilder.innerFromXContent(context); - } - - @Override - public SuggestionBuilder<?> read(StreamInput in) throws IOException { - return new CompletionSuggestionBuilder(in); - } } diff --git a/core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggestionBuilder.java b/core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggestionBuilder.java index 0fd3726384..7ef1a000e4 100644 --- a/core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggestionBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/suggest/completion/CompletionSuggestionBuilder.java @@ -20,7 +20,6 @@ package org.elasticsearch.search.suggest.completion; import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.common.ParseField; -import org.elasticsearch.common.ParseFieldMatcherSupplier; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; @@ -34,7 +33,6 @@ import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.mapper.CompletionFieldMapper; import org.elasticsearch.index.mapper.MappedFieldType; import org.elasticsearch.index.mapper.MapperService; -import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.search.suggest.SuggestionBuilder; import org.elasticsearch.search.suggest.SuggestionSearchContext.SuggestionContext; @@ -67,27 +65,26 @@ public class CompletionSuggestionBuilder extends SuggestionBuilder<CompletionSug * "payload" : STRING_ARRAY * } */ - private static ObjectParser<CompletionSuggestionBuilder.InnerBuilder, ParseFieldMatcherSupplier> TLP_PARSER = - new ObjectParser<>(SUGGESTION_NAME, null); + private static final ObjectParser<CompletionSuggestionBuilder.InnerBuilder, Void> PARSER = new ObjectParser<>(SUGGESTION_NAME, null); static { - TLP_PARSER.declareField((parser, completionSuggestionContext, context) -> { + PARSER.declareField((parser, completionSuggestionContext, context) -> { if (parser.currentToken() == XContentParser.Token.VALUE_BOOLEAN) { if (parser.booleanValue()) { completionSuggestionContext.fuzzyOptions = new FuzzyOptions.Builder().build(); } } else { - completionSuggestionContext.fuzzyOptions = FuzzyOptions.parse(parser, context); + completionSuggestionContext.fuzzyOptions = FuzzyOptions.parse(parser); } }, FuzzyOptions.FUZZY_OPTIONS, ObjectParser.ValueType.OBJECT_OR_BOOLEAN); - TLP_PARSER.declareField((parser, completionSuggestionContext, context) -> - completionSuggestionContext.regexOptions = RegexOptions.parse(parser, context), + PARSER.declareField((parser, completionSuggestionContext, context) -> + completionSuggestionContext.regexOptions = RegexOptions.parse(parser), RegexOptions.REGEX_OPTIONS, ObjectParser.ValueType.OBJECT); - TLP_PARSER.declareString(CompletionSuggestionBuilder.InnerBuilder::field, FIELDNAME_FIELD); - TLP_PARSER.declareString(CompletionSuggestionBuilder.InnerBuilder::analyzer, ANALYZER_FIELD); - TLP_PARSER.declareInt(CompletionSuggestionBuilder.InnerBuilder::size, SIZE_FIELD); - TLP_PARSER.declareInt(CompletionSuggestionBuilder.InnerBuilder::shardSize, SHARDSIZE_FIELD); - TLP_PARSER.declareField((p, v, c) -> { + PARSER.declareString(CompletionSuggestionBuilder.InnerBuilder::field, FIELDNAME_FIELD); + PARSER.declareString(CompletionSuggestionBuilder.InnerBuilder::analyzer, ANALYZER_FIELD); + PARSER.declareInt(CompletionSuggestionBuilder.InnerBuilder::size, SIZE_FIELD); + PARSER.declareInt(CompletionSuggestionBuilder.InnerBuilder::shardSize, SHARDSIZE_FIELD); + PARSER.declareField((p, v, c) -> { // Copy the current structure. We will parse, once the mapping is provided XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON); builder.copyCurrentStructure(p); @@ -237,9 +234,9 @@ public class CompletionSuggestionBuilder extends SuggestionBuilder<CompletionSug return builder; } - static CompletionSuggestionBuilder innerFromXContent(QueryParseContext parseContext) throws IOException { + public static CompletionSuggestionBuilder fromXContent(XContentParser parser) throws IOException { CompletionSuggestionBuilder.InnerBuilder builder = new CompletionSuggestionBuilder.InnerBuilder(); - TLP_PARSER.parse(parseContext.parser(), builder, parseContext); + PARSER.parse(parser, builder, null); String field = builder.field; // now we should have field name, check and copy fields over to the suggestion builder we return if (field == null) { diff --git a/core/src/main/java/org/elasticsearch/search/suggest/completion/FuzzyOptions.java b/core/src/main/java/org/elasticsearch/search/suggest/completion/FuzzyOptions.java index 3ae05f9ecf..8d121b24f1 100644 --- a/core/src/main/java/org/elasticsearch/search/suggest/completion/FuzzyOptions.java +++ b/core/src/main/java/org/elasticsearch/search/suggest/completion/FuzzyOptions.java @@ -22,7 +22,6 @@ package org.elasticsearch.search.suggest.completion; import org.apache.lucene.search.suggest.document.FuzzyCompletionQuery; import org.apache.lucene.util.automaton.Operations; import org.elasticsearch.common.ParseField; -import org.elasticsearch.common.ParseFieldMatcherSupplier; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Writeable; @@ -56,7 +55,7 @@ public class FuzzyOptions implements ToXContent, Writeable { * "max_determinized_states" : INT * } */ - private static ObjectParser<Builder, ParseFieldMatcherSupplier> PARSER = new ObjectParser<>(FUZZY_OPTIONS.getPreferredName(), + private static final ObjectParser<Builder, Void> PARSER = new ObjectParser<>(FUZZY_OPTIONS.getPreferredName(), Builder::new); static { PARSER.declareInt(Builder::setFuzzyMinLength, MIN_LENGTH_FIELD); @@ -67,6 +66,14 @@ public class FuzzyOptions implements ToXContent, Writeable { PARSER.declareField(Builder::setFuzziness, Fuzziness::parse, Fuzziness.FIELD, ObjectParser.ValueType.VALUE); } + static FuzzyOptions parse(XContentParser parser) throws IOException { + return PARSER.parse(parser, null).build(); + } + + public static Builder builder() { + return new Builder(); + } + private int editDistance; private boolean transpositions; private int fuzzyMinLength; @@ -106,14 +113,6 @@ public class FuzzyOptions implements ToXContent, Writeable { out.writeVInt(maxDeterminizedStates); } - static FuzzyOptions parse(XContentParser parser, ParseFieldMatcherSupplier context) throws IOException { - return PARSER.parse(parser, context).build(); - } - - public static Builder builder() { - return new Builder(); - } - /** * Returns the maximum number of edits */ diff --git a/core/src/main/java/org/elasticsearch/search/suggest/completion/RegexOptions.java b/core/src/main/java/org/elasticsearch/search/suggest/completion/RegexOptions.java index a9209044c8..f330322a9f 100644 --- a/core/src/main/java/org/elasticsearch/search/suggest/completion/RegexOptions.java +++ b/core/src/main/java/org/elasticsearch/search/suggest/completion/RegexOptions.java @@ -23,7 +23,6 @@ import org.apache.lucene.util.automaton.Operations; import org.apache.lucene.util.automaton.RegExp; import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.common.ParseField; -import org.elasticsearch.common.ParseFieldMatcherSupplier; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Writeable; @@ -49,7 +48,7 @@ public class RegexOptions implements ToXContent, Writeable { * "max_determinized_states" : INT * } */ - private static ObjectParser<Builder, ParseFieldMatcherSupplier> PARSER = new ObjectParser<>(REGEX_OPTIONS.getPreferredName(), + private static final ObjectParser<Builder, Void> PARSER = new ObjectParser<>(REGEX_OPTIONS.getPreferredName(), Builder::new); static { PARSER.declareInt(Builder::setMaxDeterminizedStates, MAX_DETERMINIZED_STATES); @@ -66,6 +65,14 @@ public class RegexOptions implements ToXContent, Writeable { PARSER.declareStringOrNull(Builder::setFlags, FLAGS_VALUE); } + public static Builder builder() { + return new Builder(); + } + + static RegexOptions parse(XContentParser parser) throws IOException { + return PARSER.parse(parser, null).build(); + } + private int flagsValue; private int maxDeterminizedStates; @@ -103,14 +110,6 @@ public class RegexOptions implements ToXContent, Writeable { return maxDeterminizedStates; } - public static Builder builder() { - return new Builder(); - } - - static RegexOptions parse(XContentParser parser, ParseFieldMatcherSupplier context) throws IOException { - return PARSER.parse(parser, context).build(); - } - @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/core/src/main/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorBuilder.java b/core/src/main/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorBuilder.java index 4132247363..d9d06783e4 100644 --- a/core/src/main/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorBuilder.java @@ -35,7 +35,6 @@ import org.elasticsearch.common.xcontent.ConstructingObjectParser; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.index.mapper.MapperService; -import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.search.suggest.SortBy; import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder.CandidateGenerator; @@ -387,7 +386,7 @@ public final class DirectCandidateGeneratorBuilder implements CandidateGenerator } } - private static ConstructingObjectParser<DirectCandidateGeneratorBuilder, QueryParseContext> PARSER = new ConstructingObjectParser<>( + public static final ConstructingObjectParser<DirectCandidateGeneratorBuilder, Void> PARSER = new ConstructingObjectParser<>( TYPE, args -> new DirectCandidateGeneratorBuilder((String) args[0])); static { @@ -407,10 +406,6 @@ public final class DirectCandidateGeneratorBuilder implements CandidateGenerator PARSER.declareInt(DirectCandidateGeneratorBuilder::prefixLength, PREFIX_LENGTH_FIELD); } - public static DirectCandidateGeneratorBuilder fromXContent(QueryParseContext parseContext) throws IOException { - return PARSER.apply(parseContext.parser(), parseContext); - } - @Override public PhraseSuggestionContext.DirectCandidateGenerator build(MapperService mapperService) throws IOException { PhraseSuggestionContext.DirectCandidateGenerator generator = new PhraseSuggestionContext.DirectCandidateGenerator(); diff --git a/core/src/main/java/org/elasticsearch/search/suggest/phrase/Laplace.java b/core/src/main/java/org/elasticsearch/search/suggest/phrase/Laplace.java index 00af02a805..222f690191 100644 --- a/core/src/main/java/org/elasticsearch/search/suggest/phrase/Laplace.java +++ b/core/src/main/java/org/elasticsearch/search/suggest/phrase/Laplace.java @@ -28,7 +28,6 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentParser.Token; -import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.search.suggest.phrase.WordScorer.WordScorerFactory; import java.io.IOException; @@ -103,8 +102,7 @@ public final class Laplace extends SmoothingModel { return Objects.hash(alpha); } - public static SmoothingModel innerFromXContent(QueryParseContext parseContext) throws IOException { - XContentParser parser = parseContext.parser(); + public static SmoothingModel fromXContent(XContentParser parser) throws IOException { XContentParser.Token token; String fieldName = null; double alpha = DEFAULT_LAPLACE_ALPHA; diff --git a/core/src/main/java/org/elasticsearch/search/suggest/phrase/LinearInterpolation.java b/core/src/main/java/org/elasticsearch/search/suggest/phrase/LinearInterpolation.java index dbd1540b32..10a170d766 100644 --- a/core/src/main/java/org/elasticsearch/search/suggest/phrase/LinearInterpolation.java +++ b/core/src/main/java/org/elasticsearch/search/suggest/phrase/LinearInterpolation.java @@ -29,7 +29,6 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentParser.Token; -import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.search.suggest.phrase.WordScorer.WordScorerFactory; import java.io.IOException; @@ -130,8 +129,7 @@ public final class LinearInterpolation extends SmoothingModel { return Objects.hash(trigramLambda, bigramLambda, unigramLambda); } - public static LinearInterpolation innerFromXContent(QueryParseContext parseContext) throws IOException { - XContentParser parser = parseContext.parser(); + public static LinearInterpolation fromXContent(XContentParser parser) throws IOException { XContentParser.Token token; String fieldName = null; double trigramLambda = 0.0; diff --git a/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggester.java b/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggester.java index 88648395e6..fc862f6363 100644 --- a/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggester.java +++ b/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggester.java @@ -29,21 +29,18 @@ import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRefBuilder; import org.apache.lucene.util.CharsRefBuilder; import org.elasticsearch.common.bytes.BytesReference; -import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.lucene.Lucene; import org.elasticsearch.common.text.Text; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.index.query.ParsedQuery; import org.elasticsearch.index.query.QueryBuilder; -import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.script.ExecutableScript; import org.elasticsearch.search.suggest.Suggest.Suggestion; import org.elasticsearch.search.suggest.Suggest.Suggestion.Entry; import org.elasticsearch.search.suggest.Suggest.Suggestion.Entry.Option; import org.elasticsearch.search.suggest.Suggester; -import org.elasticsearch.search.suggest.SuggestionBuilder; import org.elasticsearch.search.suggest.SuggestionSearchContext.SuggestionContext; import org.elasticsearch.search.suggest.phrase.NoisyChannelSpellChecker.Result; @@ -152,14 +149,4 @@ public final class PhraseSuggester extends Suggester<PhraseSuggestionContext> { spare.copyUTF8Bytes(suggestion.getText()); return new PhraseSuggestion.Entry(new Text(spare.toString()), 0, spare.length(), cutoffScore); } - - @Override - public SuggestionBuilder<?> innerFromXContent(QueryParseContext context) throws IOException { - return PhraseSuggestionBuilder.innerFromXContent(context); - } - - @Override - public SuggestionBuilder<?> read(StreamInput in) throws IOException { - return new PhraseSuggestionBuilder(in); - } } diff --git a/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggestionBuilder.java b/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggestionBuilder.java index 7611d30263..0a5596adf1 100644 --- a/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggestionBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/suggest/phrase/PhraseSuggestionBuilder.java @@ -36,7 +36,6 @@ import org.elasticsearch.index.analysis.NamedAnalyzer; import org.elasticsearch.index.analysis.ShingleTokenFilterFactory; import org.elasticsearch.index.analysis.TokenFilterFactory; import org.elasticsearch.index.mapper.MapperService; -import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.script.ExecutableScript; import org.elasticsearch.script.Script; @@ -125,7 +124,7 @@ public class PhraseSuggestionBuilder extends SuggestionBuilder<PhraseSuggestionB /** * Read from a stream. */ - PhraseSuggestionBuilder(StreamInput in) throws IOException { + public PhraseSuggestionBuilder(StreamInput in) throws IOException { super(in); maxErrors = in.readFloat(); realWordErrorLikelihood = in.readFloat(); @@ -487,8 +486,7 @@ public class PhraseSuggestionBuilder extends SuggestionBuilder<PhraseSuggestionB return builder; } - static PhraseSuggestionBuilder innerFromXContent(QueryParseContext parseContext) throws IOException { - XContentParser parser = parseContext.parser(); + public static PhraseSuggestionBuilder fromXContent(XContentParser parser) throws IOException { PhraseSuggestionBuilder tmpSuggestion = new PhraseSuggestionBuilder("_na_"); XContentParser.Token token; String currentFieldName = null; @@ -527,7 +525,7 @@ public class PhraseSuggestionBuilder extends SuggestionBuilder<PhraseSuggestionB if (DirectCandidateGeneratorBuilder.DIRECT_GENERATOR_FIELD.match(currentFieldName)) { // for now we only have a single type of generators while ((token = parser.nextToken()) == Token.START_OBJECT) { - tmpSuggestion.addCandidateGenerator(DirectCandidateGeneratorBuilder.fromXContent(parseContext)); + tmpSuggestion.addCandidateGenerator(DirectCandidateGeneratorBuilder.PARSER.apply(parser, null)); } } else { throw new ParsingException(parser.getTokenLocation(), @@ -536,7 +534,7 @@ public class PhraseSuggestionBuilder extends SuggestionBuilder<PhraseSuggestionB } else if (token == Token.START_OBJECT) { if (PhraseSuggestionBuilder.SMOOTHING_MODEL_FIELD.match(currentFieldName)) { ensureNoSmoothing(tmpSuggestion); - tmpSuggestion.smoothingModel(SmoothingModel.fromXContent(parseContext)); + tmpSuggestion.smoothingModel(SmoothingModel.fromXContent(parser)); } else if (PhraseSuggestionBuilder.HIGHLIGHT_FIELD.match(currentFieldName)) { String preTag = null; String postTag = null; diff --git a/core/src/main/java/org/elasticsearch/search/suggest/phrase/SmoothingModel.java b/core/src/main/java/org/elasticsearch/search/suggest/phrase/SmoothingModel.java index 82f106130e..6fd7d6ea53 100644 --- a/core/src/main/java/org/elasticsearch/search/suggest/phrase/SmoothingModel.java +++ b/core/src/main/java/org/elasticsearch/search/suggest/phrase/SmoothingModel.java @@ -24,7 +24,6 @@ import org.elasticsearch.common.io.stream.NamedWriteable; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.search.suggest.phrase.WordScorer.WordScorerFactory; import java.io.IOException; @@ -64,8 +63,7 @@ public abstract class SmoothingModel implements NamedWriteable, ToXContent { protected abstract int doHashCode(); - public static SmoothingModel fromXContent(QueryParseContext parseContext) throws IOException { - XContentParser parser = parseContext.parser(); + public static SmoothingModel fromXContent(XContentParser parser) throws IOException { XContentParser.Token token; String fieldName = null; SmoothingModel model = null; @@ -74,11 +72,11 @@ public abstract class SmoothingModel implements NamedWriteable, ToXContent { fieldName = parser.currentName(); } else if (token == XContentParser.Token.START_OBJECT) { if (LinearInterpolation.PARSE_FIELD.match(fieldName)) { - model = LinearInterpolation.innerFromXContent(parseContext); + model = LinearInterpolation.fromXContent(parser); } else if (Laplace.PARSE_FIELD.match(fieldName)) { - model = Laplace.innerFromXContent(parseContext); + model = Laplace.fromXContent(parser); } else if (StupidBackoff.PARSE_FIELD.match(fieldName)) { - model = StupidBackoff.innerFromXContent(parseContext); + model = StupidBackoff.fromXContent(parser); } else { throw new IllegalArgumentException("suggester[phrase] doesn't support object field [" + fieldName + "]"); } diff --git a/core/src/main/java/org/elasticsearch/search/suggest/phrase/StupidBackoff.java b/core/src/main/java/org/elasticsearch/search/suggest/phrase/StupidBackoff.java index 607ccac974..ebdd1c9ec2 100644 --- a/core/src/main/java/org/elasticsearch/search/suggest/phrase/StupidBackoff.java +++ b/core/src/main/java/org/elasticsearch/search/suggest/phrase/StupidBackoff.java @@ -28,7 +28,6 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentParser.Token; -import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.search.suggest.phrase.WordScorer.WordScorerFactory; import java.io.IOException; @@ -106,8 +105,7 @@ public final class StupidBackoff extends SmoothingModel { return Objects.hash(discount); } - public static SmoothingModel innerFromXContent(QueryParseContext parseContext) throws IOException { - XContentParser parser = parseContext.parser(); + public static SmoothingModel fromXContent(XContentParser parser) throws IOException { XContentParser.Token token; String fieldName = null; double discount = DEFAULT_BACKOFF_DISCOUNT; diff --git a/core/src/main/java/org/elasticsearch/search/suggest/term/TermSuggester.java b/core/src/main/java/org/elasticsearch/search/suggest/term/TermSuggester.java index 0d58e0f5ca..d6edf352d1 100644 --- a/core/src/main/java/org/elasticsearch/search/suggest/term/TermSuggester.java +++ b/core/src/main/java/org/elasticsearch/search/suggest/term/TermSuggester.java @@ -27,11 +27,8 @@ import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRefBuilder; import org.apache.lucene.util.CharsRefBuilder; import org.elasticsearch.common.bytes.BytesArray; -import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.text.Text; -import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.search.suggest.Suggester; -import org.elasticsearch.search.suggest.SuggestionBuilder; import org.elasticsearch.search.suggest.SuggestionSearchContext.SuggestionContext; import org.elasticsearch.search.suggest.phrase.DirectCandidateGenerator; @@ -84,16 +81,6 @@ public final class TermSuggester extends Suggester<TermSuggestionContext> { return result; } - @Override - public SuggestionBuilder<?> innerFromXContent(QueryParseContext context) throws IOException { - return TermSuggestionBuilder.innerFromXContent(context); - } - - @Override - public SuggestionBuilder<?> read(StreamInput in) throws IOException { - return new TermSuggestionBuilder(in); - } - private static class Token { public final Term term; diff --git a/core/src/main/java/org/elasticsearch/search/suggest/term/TermSuggestionBuilder.java b/core/src/main/java/org/elasticsearch/search/suggest/term/TermSuggestionBuilder.java index 9a7238dbe1..72fd41dc5b 100644 --- a/core/src/main/java/org/elasticsearch/search/suggest/term/TermSuggestionBuilder.java +++ b/core/src/main/java/org/elasticsearch/search/suggest/term/TermSuggestionBuilder.java @@ -32,7 +32,6 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.search.suggest.DirectSpellcheckerSettings; import org.elasticsearch.search.suggest.SortBy; @@ -104,7 +103,7 @@ public class TermSuggestionBuilder extends SuggestionBuilder<TermSuggestionBuild /** * Read from a stream. */ - TermSuggestionBuilder(StreamInput in) throws IOException { + public TermSuggestionBuilder(StreamInput in) throws IOException { super(in); suggestMode = SuggestMode.readFromStream(in); accuracy = in.readFloat(); @@ -387,8 +386,7 @@ public class TermSuggestionBuilder extends SuggestionBuilder<TermSuggestionBuild return builder; } - static TermSuggestionBuilder innerFromXContent(QueryParseContext parseContext) throws IOException { - XContentParser parser = parseContext.parser(); + public static TermSuggestionBuilder fromXContent(XContentParser parser) throws IOException { TermSuggestionBuilder tmpSuggestion = new TermSuggestionBuilder("_na_"); XContentParser.Token token; String currentFieldName = null; diff --git a/core/src/test/java/org/elasticsearch/action/search/MultiSearchRequestTests.java b/core/src/test/java/org/elasticsearch/action/search/MultiSearchRequestTests.java index 19c66aa8fc..a5bd3df4d6 100644 --- a/core/src/test/java/org/elasticsearch/action/search/MultiSearchRequestTests.java +++ b/core/src/test/java/org/elasticsearch/action/search/MultiSearchRequestTests.java @@ -163,7 +163,7 @@ public class MultiSearchRequestTests extends ESTestCase { private MultiSearchRequest parseMultiSearchRequest(String sample) throws IOException { byte[] data = StreamsUtils.copyToBytesFromClasspath(sample); RestRequest restRequest = new FakeRestRequest.Builder(xContentRegistry()).withContent(new BytesArray(data)).build(); - return RestMultiSearchAction.parseRequest(restRequest, true, new SearchRequestParsers(null), ParseFieldMatcher.EMPTY); + return RestMultiSearchAction.parseRequest(restRequest, true, new SearchRequestParsers(), ParseFieldMatcher.EMPTY); } @Override diff --git a/core/src/test/java/org/elasticsearch/search/SearchModuleTests.java b/core/src/test/java/org/elasticsearch/search/SearchModuleTests.java index 8a22363d5b..a56886a8bf 100644 --- a/core/src/test/java/org/elasticsearch/search/SearchModuleTests.java +++ b/core/src/test/java/org/elasticsearch/search/SearchModuleTests.java @@ -58,11 +58,9 @@ import org.elasticsearch.search.fetch.subphase.highlight.Highlighter; import org.elasticsearch.search.fetch.subphase.highlight.PlainHighlighter; import org.elasticsearch.search.fetch.subphase.highlight.PostingsHighlighter; import org.elasticsearch.search.internal.SearchContext; -import org.elasticsearch.search.suggest.CustomSuggester; -import org.elasticsearch.search.suggest.Suggester; -import org.elasticsearch.search.suggest.completion.CompletionSuggester; -import org.elasticsearch.search.suggest.phrase.PhraseSuggester; -import org.elasticsearch.search.suggest.term.TermSuggester; +import org.elasticsearch.search.suggest.CustomSuggesterSearchIT.CustomSuggestionBuilder; +import org.elasticsearch.search.suggest.SuggestionBuilder; +import org.elasticsearch.search.suggest.term.TermSuggestionBuilder; import java.io.IOException; import java.util.ArrayList; @@ -93,13 +91,12 @@ public class SearchModuleTests extends ModuleTestCase { () -> new SearchModule(Settings.EMPTY, false, singletonList(registersDupeHighlighter))); SearchPlugin registersDupeSuggester = new SearchPlugin() { - @Override - public Map<String,org.elasticsearch.search.suggest.Suggester<?>> getSuggesters() { - return singletonMap("term", TermSuggester.INSTANCE); + public List<SearchPlugin.SuggesterSpec<?>> getSuggesters() { + return singletonList(new SuggesterSpec<>("term", TermSuggestionBuilder::new, TermSuggestionBuilder::fromXContent)); } }; - expectThrows(IllegalArgumentException.class, - () -> new SearchModule(Settings.EMPTY, false, singletonList(registersDupeSuggester))); + expectThrows(IllegalArgumentException.class, () -> new NamedXContentRegistry( + new SearchModule(Settings.EMPTY, false, singletonList(registersDupeSuggester)).getNamedXContents())); SearchPlugin registersDupeScoreFunction = new SearchPlugin() { @Override @@ -172,14 +169,27 @@ public class SearchModuleTests extends ModuleTestCase { public void testRegisterSuggester() { SearchModule module = new SearchModule(Settings.EMPTY, false, singletonList(new SearchPlugin() { @Override - public Map<String, Suggester<?>> getSuggesters() { - return singletonMap("custom", CustomSuggester.INSTANCE); + public List<SuggesterSpec<?>> getSuggesters() { + return singletonList(new SuggesterSpec<>("custom", CustomSuggestionBuilder::new, CustomSuggestionBuilder::fromXContent)); } })); - assertSame(TermSuggester.INSTANCE, module.getSuggesters().getSuggester("term")); - assertSame(PhraseSuggester.INSTANCE, module.getSuggesters().getSuggester("phrase")); - assertSame(CompletionSuggester.INSTANCE, module.getSuggesters().getSuggester("completion")); - assertSame(CustomSuggester.INSTANCE, module.getSuggesters().getSuggester("custom")); + assertEquals(1, module.getNamedXContents().stream() + .filter(e -> e.categoryClass.equals(SuggestionBuilder.class) && e.name.match("term")).count()); + assertEquals(1, module.getNamedXContents().stream() + .filter(e -> e.categoryClass.equals(SuggestionBuilder.class) && e.name.match("phrase")).count()); + assertEquals(1, module.getNamedXContents().stream() + .filter(e -> e.categoryClass.equals(SuggestionBuilder.class) && e.name.match("completion")).count()); + assertEquals(1, module.getNamedXContents().stream() + .filter(e -> e.categoryClass.equals(SuggestionBuilder.class) && e.name.match("custom")).count()); + + assertEquals(1, module.getNamedWriteables().stream() + .filter(e -> e.categoryClass.equals(SuggestionBuilder.class) && e.name.equals("term")).count()); + assertEquals(1, module.getNamedWriteables().stream() + .filter(e -> e.categoryClass.equals(SuggestionBuilder.class) && e.name.equals("phrase")).count()); + assertEquals(1, module.getNamedWriteables().stream() + .filter(e -> e.categoryClass.equals(SuggestionBuilder.class) && e.name.equals("completion")).count()); + assertEquals(1, module.getNamedWriteables().stream() + .filter(e -> e.categoryClass.equals(SuggestionBuilder.class) && e.name.equals("custom")).count()); } public void testRegisterHighlighter() { diff --git a/core/src/test/java/org/elasticsearch/search/builder/SearchSourceBuilderTests.java b/core/src/test/java/org/elasticsearch/search/builder/SearchSourceBuilderTests.java index d16cb156c9..69b4d70b06 100644 --- a/core/src/test/java/org/elasticsearch/search/builder/SearchSourceBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/search/builder/SearchSourceBuilderTests.java @@ -75,7 +75,7 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase { parser.nextToken(); // sometimes we move it on the START_OBJECT to // test the embedded case } - SearchSourceBuilder newBuilder = SearchSourceBuilder.fromXContent(parseContext, searchRequestParsers.suggesters); + SearchSourceBuilder newBuilder = SearchSourceBuilder.fromXContent(parseContext); assertNull(parser.nextToken()); assertEquals(testBuilder, newBuilder); assertEquals(testBuilder.hashCode(), newBuilder.hashCode()); @@ -112,8 +112,7 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase { { String restContent = " { \"_source\": { \"includes\": \"include\", \"excludes\": \"*.field2\"}}"; try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) { - SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser), - searchRequestParsers.suggesters); + SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser)); assertArrayEquals(new String[]{"*.field2"}, searchSourceBuilder.fetchSource().excludes()); assertArrayEquals(new String[]{"include"}, searchSourceBuilder.fetchSource().includes()); } @@ -121,8 +120,7 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase { { String restContent = " { \"_source\": false}"; try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) { - SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser), - searchRequestParsers.suggesters); + SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser)); assertArrayEquals(new String[]{}, searchSourceBuilder.fetchSource().excludes()); assertArrayEquals(new String[]{}, searchSourceBuilder.fetchSource().includes()); assertFalse(searchSourceBuilder.fetchSource().fetchSource()); @@ -144,8 +142,7 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase { " }\n" + " } }"; try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) { - ParsingException e = expectThrows(ParsingException.class, () -> SearchSourceBuilder.fromXContent(createParseContext(parser), - searchRequestParsers.suggesters)); + ParsingException e = expectThrows(ParsingException.class, () -> SearchSourceBuilder.fromXContent(createParseContext(parser))); assertEquals("[multi_match] malformed query, expected [END_OBJECT] but found [FIELD_NAME]", e.getMessage()); } } @@ -154,8 +151,7 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase { { String restContent = " { \"sort\": \"foo\"}"; try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) { - SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser), - searchRequestParsers.suggesters); + SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser)); assertEquals(1, searchSourceBuilder.sorts().size()); assertEquals(new FieldSortBuilder("foo"), searchSourceBuilder.sorts().get(0)); } @@ -170,8 +166,7 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase { " \"_score\"\n" + " ]}"; try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) { - SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser), - searchRequestParsers.suggesters); + SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser)); assertEquals(5, searchSourceBuilder.sorts().size()); assertEquals(new FieldSortBuilder("post_date"), searchSourceBuilder.sorts().get(0)); assertEquals(new FieldSortBuilder("user"), searchSourceBuilder.sorts().get(1)); @@ -194,8 +189,7 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase { " }\n" + "}\n"; try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) { - SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser), - searchRequestParsers.suggesters); + SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser)); assertEquals(1, searchSourceBuilder.aggregations().count()); } } @@ -210,8 +204,7 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase { " }\n" + "}\n"; try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) { - SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser), - searchRequestParsers.suggesters); + SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser)); assertEquals(1, searchSourceBuilder.aggregations().count()); } } @@ -236,8 +229,7 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase { " }\n" + "}\n"; try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) { - SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser), - searchRequestParsers.suggesters); + SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser)); assertEquals(1, searchSourceBuilder.rescores().size()); assertEquals(new QueryRescorerBuilder(QueryBuilders.matchQuery("content", "baz")).windowSize(50), searchSourceBuilder.rescores().get(0)); @@ -259,8 +251,7 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase { " } ]\n" + "}\n"; try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) { - SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser), - searchRequestParsers.suggesters); + SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser)); assertEquals(1, searchSourceBuilder.rescores().size()); assertEquals(new QueryRescorerBuilder(QueryBuilders.matchQuery("content", "baz")).windowSize(50), searchSourceBuilder.rescores().get(0)); @@ -272,8 +263,7 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase { final String timeout = randomTimeValue(); final String query = "{ \"query\": { \"match_all\": {}}, \"timeout\": \"" + timeout + "\"}"; try (XContentParser parser = createParser(JsonXContent.jsonXContent, query)) { - final SearchSourceBuilder builder = SearchSourceBuilder.fromXContent(createParseContext(parser), - searchRequestParsers.suggesters); + final SearchSourceBuilder builder = SearchSourceBuilder.fromXContent(createParseContext(parser)); assertThat(builder.timeout(), equalTo(TimeValue.parseTimeValue(timeout, null, "timeout"))); } } @@ -283,7 +273,7 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase { final String query = "{ \"query\": { \"match_all\": {}}, \"timeout\": \"" + timeout + "\"}"; try (XContentParser parser = createParser(JsonXContent.jsonXContent, query)) { final ElasticsearchParseException e = expectThrows(ElasticsearchParseException.class, () -> SearchSourceBuilder.fromXContent( - createParseContext(parser), searchRequestParsers.suggesters)); + createParseContext(parser))); assertThat(e, hasToString(containsString("unit is missing or unrecognized"))); } } @@ -315,8 +305,7 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase { { String restContent = " { \"indices_boost\": {\"foo\": 1.0, \"bar\": 2.0}}"; try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) { - SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser), - searchRequestParsers.suggesters); + SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser)); assertEquals(2, searchSourceBuilder.indexBoosts().size()); assertEquals(new SearchSourceBuilder.IndexBoost("foo", 1.0f), searchSourceBuilder.indexBoosts().get(0)); assertEquals(new SearchSourceBuilder.IndexBoost("bar", 2.0f), searchSourceBuilder.indexBoosts().get(1)); @@ -332,8 +321,7 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase { " { \"baz\" : 3.0 }\n" + " ]}"; try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) { - SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser), - searchRequestParsers.suggesters); + SearchSourceBuilder searchSourceBuilder = SearchSourceBuilder.fromXContent(createParseContext(parser)); assertEquals(3, searchSourceBuilder.indexBoosts().size()); assertEquals(new SearchSourceBuilder.IndexBoost("foo", 1.0f), searchSourceBuilder.indexBoosts().get(0)); assertEquals(new SearchSourceBuilder.IndexBoost("bar", 2.0f), searchSourceBuilder.indexBoosts().get(1)); @@ -380,8 +368,7 @@ public class SearchSourceBuilderTests extends AbstractSearchTestCase { private void assertIndicesBoostParseErrorMessage(String restContent, String expectedErrorMessage) throws IOException { try (XContentParser parser = createParser(JsonXContent.jsonXContent, restContent)) { - ParsingException e = expectThrows(ParsingException.class, () -> SearchSourceBuilder.fromXContent(createParseContext(parser), - searchRequestParsers.suggesters)); + ParsingException e = expectThrows(ParsingException.class, () -> SearchSourceBuilder.fromXContent(createParseContext(parser))); assertEquals(expectedErrorMessage, e.getMessage()); } } diff --git a/core/src/test/java/org/elasticsearch/search/suggest/AbstractSuggestionBuilderTestCase.java b/core/src/test/java/org/elasticsearch/search/suggest/AbstractSuggestionBuilderTestCase.java index f75b73a513..530a505a69 100644 --- a/core/src/test/java/org/elasticsearch/search/suggest/AbstractSuggestionBuilderTestCase.java +++ b/core/src/test/java/org/elasticsearch/search/suggest/AbstractSuggestionBuilderTestCase.java @@ -19,16 +19,15 @@ package org.elasticsearch.search.suggest; -import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.NamedXContentRegistry; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.search.SearchModule; import org.elasticsearch.test.ESTestCase; import org.junit.AfterClass; @@ -43,8 +42,7 @@ public abstract class AbstractSuggestionBuilderTestCase<SB extends SuggestionBui private static final int NUMBER_OF_TESTBUILDERS = 20; protected static NamedWriteableRegistry namedWriteableRegistry; - protected static ParseFieldMatcher parseFieldMatcher; - protected static Suggesters suggesters; + protected static NamedXContentRegistry xContentRegistry; /** * setup for the whole base test class @@ -53,14 +51,13 @@ public abstract class AbstractSuggestionBuilderTestCase<SB extends SuggestionBui public static void init() throws IOException { SearchModule searchModule = new SearchModule(Settings.EMPTY, false, emptyList()); namedWriteableRegistry = new NamedWriteableRegistry(searchModule.getNamedWriteables()); - suggesters = searchModule.getSuggesters(); - parseFieldMatcher = ParseFieldMatcher.STRICT; + xContentRegistry = new NamedXContentRegistry(searchModule.getNamedXContents()); } @AfterClass public static void afterClass() throws Exception { namedWriteableRegistry = null; - suggesters = null; + xContentRegistry = null; } /** @@ -124,11 +121,10 @@ public abstract class AbstractSuggestionBuilderTestCase<SB extends SuggestionBui XContentBuilder shuffled = shuffleXContent(xContentBuilder, shuffleProtectedFields()); XContentParser parser = createParser(shuffled); - QueryParseContext context = new QueryParseContext(parser, parseFieldMatcher); // we need to skip the start object and the name, those will be parsed by outer SuggestBuilder parser.nextToken(); - SuggestionBuilder<?> secondSuggestionBuilder = SuggestionBuilder.fromXContent(context, suggesters); + SuggestionBuilder<?> secondSuggestionBuilder = SuggestionBuilder.fromXContent(parser); assertNotSame(suggestionBuilder, secondSuggestionBuilder); assertEquals(suggestionBuilder, secondSuggestionBuilder); assertEquals(suggestionBuilder.hashCode(), secondSuggestionBuilder.hashCode()); @@ -186,8 +182,8 @@ public abstract class AbstractSuggestionBuilderTestCase<SB extends SuggestionBui (Writeable.Reader<SB>) namedWriteableRegistry.getReader(SuggestionBuilder.class, original.getWriteableName())); } - protected static QueryParseContext newParseContext(XContentParser parser) throws IOException { - final QueryParseContext parseContext = new QueryParseContext(parser, parseFieldMatcher); - return parseContext; + @Override + protected NamedXContentRegistry xContentRegistry() { + return xContentRegistry; } } diff --git a/core/src/test/java/org/elasticsearch/search/suggest/CustomSuggester.java b/core/src/test/java/org/elasticsearch/search/suggest/CustomSuggester.java index 48b570e880..63c8aa1e66 100644 --- a/core/src/test/java/org/elasticsearch/search/suggest/CustomSuggester.java +++ b/core/src/test/java/org/elasticsearch/search/suggest/CustomSuggester.java @@ -20,11 +20,8 @@ package org.elasticsearch.search.suggest; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.util.CharsRefBuilder; -import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.text.Text; -import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.index.query.QueryShardContext; -import org.elasticsearch.search.suggest.CustomSuggesterSearchIT.CustomSuggestionBuilder; import java.io.IOException; import java.util.Locale; @@ -63,14 +60,4 @@ public class CustomSuggester extends Suggester<CustomSuggester.CustomSuggestions this.options = options; } } - - @Override - public SuggestionBuilder<?> innerFromXContent(QueryParseContext context) throws IOException { - return CustomSuggestionBuilder.innerFromXContent(context); - } - - @Override - public SuggestionBuilder<?> read(StreamInput in) throws IOException { - return new CustomSuggestionBuilder(in); - } } diff --git a/core/src/test/java/org/elasticsearch/search/suggest/CustomSuggesterPlugin.java b/core/src/test/java/org/elasticsearch/search/suggest/CustomSuggesterPlugin.java deleted file mode 100644 index 583ac365fa..0000000000 --- a/core/src/test/java/org/elasticsearch/search/suggest/CustomSuggesterPlugin.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.elasticsearch.search.suggest; - -import org.elasticsearch.plugins.Plugin; -import org.elasticsearch.plugins.SearchPlugin; - -import java.util.Map; - -import static java.util.Collections.singletonMap; - -public class CustomSuggesterPlugin extends Plugin implements SearchPlugin { - @Override - public Map<String, Suggester<?>> getSuggesters() { - return singletonMap("custom", CustomSuggester.INSTANCE); - } -} diff --git a/core/src/test/java/org/elasticsearch/search/suggest/CustomSuggesterSearchIT.java b/core/src/test/java/org/elasticsearch/search/suggest/CustomSuggesterSearchIT.java index 255cbecae5..dde5a73045 100644 --- a/core/src/test/java/org/elasticsearch/search/suggest/CustomSuggesterSearchIT.java +++ b/core/src/test/java/org/elasticsearch/search/suggest/CustomSuggesterSearchIT.java @@ -28,9 +28,9 @@ import org.elasticsearch.common.lucene.BytesRefs; import org.elasticsearch.common.util.CollectionUtils; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.index.query.QueryShardContext; import org.elasticsearch.plugins.Plugin; +import org.elasticsearch.plugins.SearchPlugin; import org.elasticsearch.search.suggest.SuggestionSearchContext.SuggestionContext; import org.elasticsearch.test.ESIntegTestCase; import org.elasticsearch.test.ESIntegTestCase.ClusterScope; @@ -45,6 +45,7 @@ import java.util.Locale; import java.util.Map; import java.util.Objects; +import static java.util.Collections.singletonList; import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.hamcrest.Matchers.hasSize; @@ -65,6 +66,14 @@ public class CustomSuggesterSearchIT extends ESIntegTestCase { return Arrays.asList(CustomSuggesterPlugin.class); } + public static class CustomSuggesterPlugin extends Plugin implements SearchPlugin { + @Override + public List<SuggesterSpec<?>> getSuggesters() { + return singletonList(new SuggesterSpec<CustomSuggestionBuilder>("custom", CustomSuggestionBuilder::new, + CustomSuggestionBuilder::fromXContent)); + } + } + public void testThatCustomSuggestersCanBeRegisteredAndWork() throws Exception { createIndex("test"); client().prepareIndex("test", "test", "1").setSource(jsonBuilder() @@ -139,8 +148,7 @@ public class CustomSuggesterSearchIT extends ESIntegTestCase { return Objects.hash(randomSuffix); } - static CustomSuggestionBuilder innerFromXContent(QueryParseContext parseContext) throws IOException { - XContentParser parser = parseContext.parser(); + public static CustomSuggestionBuilder fromXContent(XContentParser parser) throws IOException { XContentParser.Token token; String currentFieldName = null; String fieldname = null; diff --git a/core/src/test/java/org/elasticsearch/search/suggest/SuggestBuilderTests.java b/core/src/test/java/org/elasticsearch/search/suggest/SuggestBuilderTests.java index e8d0247695..9029a097ca 100644 --- a/core/src/test/java/org/elasticsearch/search/suggest/SuggestBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/search/suggest/SuggestBuilderTests.java @@ -19,15 +19,14 @@ package org.elasticsearch.search.suggest; -import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.NamedXContentRegistry; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.search.SearchModule; import org.elasticsearch.search.suggest.completion.CompletionSuggesterBuilderTests; import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilderTests; @@ -46,7 +45,7 @@ public class SuggestBuilderTests extends ESTestCase { private static final int NUMBER_OF_RUNS = 20; private static NamedWriteableRegistry namedWriteableRegistry; - private static Suggesters suggesters; + private static NamedXContentRegistry xContentRegistry; /** * Setup for the whole base test class. @@ -55,13 +54,13 @@ public class SuggestBuilderTests extends ESTestCase { public static void init() { SearchModule searchModule = new SearchModule(Settings.EMPTY, false, emptyList()); namedWriteableRegistry = new NamedWriteableRegistry(searchModule.getNamedWriteables()); - suggesters = searchModule.getSuggesters(); + xContentRegistry = new NamedXContentRegistry(searchModule.getNamedXContents()); } @AfterClass public static void afterClass() { namedWriteableRegistry = null; - suggesters = null; + xContentRegistry = null; } /** @@ -76,8 +75,7 @@ public class SuggestBuilderTests extends ESTestCase { } suggestBuilder.toXContent(xContentBuilder, ToXContent.EMPTY_PARAMS); XContentParser parser = createParser(xContentBuilder); - QueryParseContext context = new QueryParseContext(parser, ParseFieldMatcher.STRICT); - SuggestBuilder secondSuggestBuilder = SuggestBuilder.fromXContent(context, suggesters); + SuggestBuilder secondSuggestBuilder = SuggestBuilder.fromXContent(parser); assertNotSame(suggestBuilder, secondSuggestBuilder); assertEquals(suggestBuilder, secondSuggestBuilder); assertEquals(suggestBuilder.hashCode(), secondSuggestBuilder.hashCode()); @@ -159,4 +157,8 @@ public class SuggestBuilderTests extends ESTestCase { } } + @Override + protected NamedXContentRegistry xContentRegistry() { + return xContentRegistry; + } } diff --git a/core/src/test/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorTests.java b/core/src/test/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorTests.java index eab93d9fbd..6c30ccb457 100644 --- a/core/src/test/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorTests.java +++ b/core/src/test/java/org/elasticsearch/search/suggest/phrase/DirectCandidateGeneratorTests.java @@ -19,7 +19,6 @@ package org.elasticsearch.search.suggest.phrase; -import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.ParsingException; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.xcontent.ToXContent; @@ -29,7 +28,6 @@ import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.common.xcontent.json.JsonXContent; -import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.search.suggest.phrase.PhraseSuggestionContext.DirectCandidateGenerator; import org.elasticsearch.test.ESTestCase; @@ -108,9 +106,8 @@ public class DirectCandidateGeneratorTests extends ESTestCase { } generator.toXContent(builder, ToXContent.EMPTY_PARAMS); XContentParser parser = createParser(shuffleXContent(builder)); - QueryParseContext context = new QueryParseContext(parser, ParseFieldMatcher.STRICT); parser.nextToken(); - DirectCandidateGeneratorBuilder secondGenerator = DirectCandidateGeneratorBuilder.fromXContent(context); + DirectCandidateGeneratorBuilder secondGenerator = DirectCandidateGeneratorBuilder.PARSER.apply(parser, null); assertNotSame(generator, secondGenerator); assertEquals(generator, secondGenerator); assertEquals(generator.hashCode(), secondGenerator.hashCode()); @@ -172,8 +169,7 @@ public class DirectCandidateGeneratorTests extends ESTestCase { private void assertIllegalXContent(String directGenerator, Class<? extends Exception> exceptionClass, String exceptionMsg) throws IOException { XContentParser parser = createParser(JsonXContent.jsonXContent, directGenerator); - QueryParseContext context = new QueryParseContext(parser, ParseFieldMatcher.STRICT); - Exception e = expectThrows(exceptionClass, () -> DirectCandidateGeneratorBuilder.fromXContent(context)); + Exception e = expectThrows(exceptionClass, () -> DirectCandidateGeneratorBuilder.PARSER.apply(parser, null)); assertEquals(exceptionMsg, e.getMessage()); } diff --git a/core/src/test/java/org/elasticsearch/search/suggest/phrase/LaplaceModelTests.java b/core/src/test/java/org/elasticsearch/search/suggest/phrase/LaplaceModelTests.java index dae87ef057..22917c6c31 100644 --- a/core/src/test/java/org/elasticsearch/search/suggest/phrase/LaplaceModelTests.java +++ b/core/src/test/java/org/elasticsearch/search/suggest/phrase/LaplaceModelTests.java @@ -19,7 +19,7 @@ package org.elasticsearch.search.suggest.phrase; -import org.elasticsearch.index.query.QueryParseContext; +import org.elasticsearch.common.xcontent.XContentParser; import java.io.IOException; @@ -54,7 +54,7 @@ public class LaplaceModelTests extends SmoothingModelTestCase { } @Override - protected SmoothingModel fromXContent(QueryParseContext context) throws IOException { - return Laplace.innerFromXContent(context); + protected SmoothingModel fromXContent(XContentParser parser) throws IOException { + return Laplace.fromXContent(parser); } } diff --git a/core/src/test/java/org/elasticsearch/search/suggest/phrase/LinearInterpolationModelTests.java b/core/src/test/java/org/elasticsearch/search/suggest/phrase/LinearInterpolationModelTests.java index b368997784..7efbab4584 100644 --- a/core/src/test/java/org/elasticsearch/search/suggest/phrase/LinearInterpolationModelTests.java +++ b/core/src/test/java/org/elasticsearch/search/suggest/phrase/LinearInterpolationModelTests.java @@ -19,7 +19,7 @@ package org.elasticsearch.search.suggest.phrase; -import org.elasticsearch.index.query.QueryParseContext; +import org.elasticsearch.common.xcontent.XContentParser; import java.io.IOException; @@ -73,7 +73,7 @@ public class LinearInterpolationModelTests extends SmoothingModelTestCase { } @Override - protected SmoothingModel fromXContent(QueryParseContext context) throws IOException { - return LinearInterpolation.innerFromXContent(context); + protected SmoothingModel fromXContent(XContentParser parser) throws IOException { + return LinearInterpolation.fromXContent(parser); } } diff --git a/core/src/test/java/org/elasticsearch/search/suggest/phrase/SmoothingModelTestCase.java b/core/src/test/java/org/elasticsearch/search/suggest/phrase/SmoothingModelTestCase.java index b8289c7006..e75d01739c 100644 --- a/core/src/test/java/org/elasticsearch/search/suggest/phrase/SmoothingModelTestCase.java +++ b/core/src/test/java/org/elasticsearch/search/suggest/phrase/SmoothingModelTestCase.java @@ -30,7 +30,6 @@ import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.MultiFields; import org.apache.lucene.store.RAMDirectory; -import org.elasticsearch.common.ParseFieldMatcher; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.lucene.BytesRefs; import org.elasticsearch.common.xcontent.ToXContent; @@ -38,7 +37,6 @@ import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.index.query.QueryParseContext; import org.elasticsearch.search.SearchModule; import org.elasticsearch.test.ESTestCase; import org.junit.AfterClass; @@ -83,7 +81,7 @@ public abstract class SmoothingModelTestCase extends ESTestCase { */ protected abstract SmoothingModel createMutation(SmoothingModel original) throws IOException; - protected abstract SmoothingModel fromXContent(QueryParseContext context) throws IOException; + protected abstract SmoothingModel fromXContent(XContentParser parser) throws IOException; /** * Test that creates new smoothing model from a random test smoothing model and checks both for equality @@ -98,9 +96,8 @@ public abstract class SmoothingModelTestCase extends ESTestCase { testModel.innerToXContent(contentBuilder, ToXContent.EMPTY_PARAMS); contentBuilder.endObject(); XContentParser parser = createParser(shuffleXContent(contentBuilder)); - QueryParseContext context = new QueryParseContext(parser, ParseFieldMatcher.STRICT); parser.nextToken(); // go to start token, real parsing would do that in the outer element parser - SmoothingModel parsedModel = fromXContent(context); + SmoothingModel parsedModel = fromXContent(parser); assertNotSame(testModel, parsedModel); assertEquals(testModel, parsedModel); assertEquals(testModel.hashCode(), parsedModel.hashCode()); diff --git a/core/src/test/java/org/elasticsearch/search/suggest/phrase/StupidBackoffModelTests.java b/core/src/test/java/org/elasticsearch/search/suggest/phrase/StupidBackoffModelTests.java index 57f84c3754..c0e0abecb3 100644 --- a/core/src/test/java/org/elasticsearch/search/suggest/phrase/StupidBackoffModelTests.java +++ b/core/src/test/java/org/elasticsearch/search/suggest/phrase/StupidBackoffModelTests.java @@ -19,7 +19,7 @@ package org.elasticsearch.search.suggest.phrase; -import org.elasticsearch.index.query.QueryParseContext; +import org.elasticsearch.common.xcontent.XContentParser; import java.io.IOException; @@ -53,7 +53,7 @@ public class StupidBackoffModelTests extends SmoothingModelTestCase { } @Override - protected SmoothingModel fromXContent(QueryParseContext context) throws IOException { - return StupidBackoff.innerFromXContent(context); + protected SmoothingModel fromXContent(XContentParser parser) throws IOException { + return StupidBackoff.fromXContent(parser); } } diff --git a/core/src/test/java/org/elasticsearch/search/suggest/term/TermSuggestionBuilderTests.java b/core/src/test/java/org/elasticsearch/search/suggest/term/TermSuggestionBuilderTests.java index 1df99ce83a..f27d02fbe2 100644 --- a/core/src/test/java/org/elasticsearch/search/suggest/term/TermSuggestionBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/search/suggest/term/TermSuggestionBuilderTests.java @@ -24,7 +24,6 @@ import com.carrotsearch.randomizedtesting.generators.RandomStrings; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.json.JsonXContent; import org.elasticsearch.search.suggest.AbstractSuggestionBuilderTestCase; -import org.elasticsearch.search.suggest.DirectSpellcheckerSettings; import org.elasticsearch.search.suggest.SortBy; import org.elasticsearch.search.suggest.SuggestBuilder; import org.elasticsearch.search.suggest.term.TermSuggestionBuilder.StringDistanceImpl; @@ -218,31 +217,10 @@ public class TermSuggestionBuilderTests extends AbstractSuggestionBuilderTestCas " }\n" + "}"; try (XContentParser parser = createParser(JsonXContent.jsonXContent, suggest)) { - final SuggestBuilder suggestBuilder = SuggestBuilder.fromXContent(newParseContext(parser), suggesters); + final SuggestBuilder suggestBuilder = SuggestBuilder.fromXContent(parser); fail("Should not have been able to create SuggestBuilder from malformed JSON: " + suggestBuilder); } catch (Exception e) { assertThat(e.getMessage(), containsString("parsing failed")); } } - - private void assertSpellcheckerSettings(DirectSpellcheckerSettings oldSettings, DirectSpellcheckerSettings newSettings) { - final double delta = 0.0d; - // make sure the objects aren't the same - assertNotSame(oldSettings, newSettings); - // make sure the objects aren't null - assertNotNull(oldSettings); - assertNotNull(newSettings); - // and now, make sure they are equal.. - assertEquals(oldSettings.accuracy(), newSettings.accuracy(), delta); - assertEquals(oldSettings.maxEdits(), newSettings.maxEdits()); - assertEquals(oldSettings.maxInspections(), newSettings.maxInspections()); - assertEquals(oldSettings.maxTermFreq(), newSettings.maxTermFreq(), delta); - assertEquals(oldSettings.minDocFreq(), newSettings.minDocFreq(), delta); - assertEquals(oldSettings.minWordLength(), newSettings.minWordLength()); - assertEquals(oldSettings.prefixLength(), newSettings.prefixLength()); - assertEquals(oldSettings.sort(), newSettings.sort()); - assertEquals(oldSettings.stringDistance().getClass(), newSettings.stringDistance().getClass()); - assertEquals(oldSettings.suggestMode().getClass(), newSettings.suggestMode().getClass()); - } - } diff --git a/modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/TransportSearchTemplateAction.java b/modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/TransportSearchTemplateAction.java index 2fb5a98975..9d1071f62e 100644 --- a/modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/TransportSearchTemplateAction.java +++ b/modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/TransportSearchTemplateAction.java @@ -88,7 +88,7 @@ public class TransportSearchTemplateAction extends HandledTransportAction<Search try (XContentParser parser = XContentFactory.xContent(source).createParser(xContentRegistry, source)) { SearchSourceBuilder builder = SearchSourceBuilder.searchSource(); - builder.parseXContent(new QueryParseContext(parser, parseFieldMatcher), searchRequestParsers.suggesters); + builder.parseXContent(new QueryParseContext(parser, parseFieldMatcher)); builder.explain(request.isExplain()); builder.profile(request.isProfile()); searchRequest.source(builder); diff --git a/modules/percolator/src/main/java/org/elasticsearch/percolator/TransportPercolateAction.java b/modules/percolator/src/main/java/org/elasticsearch/percolator/TransportPercolateAction.java index 13ada86197..30bf1d0808 100644 --- a/modules/percolator/src/main/java/org/elasticsearch/percolator/TransportPercolateAction.java +++ b/modules/percolator/src/main/java/org/elasticsearch/percolator/TransportPercolateAction.java @@ -226,7 +226,7 @@ public class TransportPercolateAction extends HandledTransportAction<PercolateRe SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); try (XContentParser parser = XContentFactory.xContent(XContentType.JSON).createParser(xContentRegistry, source)) { QueryParseContext context = new QueryParseContext(parser, parseFieldMatcher); - searchSourceBuilder.parseXContent(context, null); + searchSourceBuilder.parseXContent(context); searchRequest.source(searchSourceBuilder); return searchRequest; } diff --git a/modules/reindex/src/main/java/org/elasticsearch/index/reindex/RestReindexAction.java b/modules/reindex/src/main/java/org/elasticsearch/index/reindex/RestReindexAction.java index 142fce0061..c631a4c7a1 100644 --- a/modules/reindex/src/main/java/org/elasticsearch/index/reindex/RestReindexAction.java +++ b/modules/reindex/src/main/java/org/elasticsearch/index/reindex/RestReindexAction.java @@ -81,8 +81,7 @@ public class RestReindexAction extends AbstractBaseReindexRestHandler<ReindexReq XContentBuilder builder = XContentFactory.contentBuilder(parser.contentType()); builder.map(source); try (XContentParser innerParser = parser.contentType().xContent().createParser(parser.getXContentRegistry(), builder.bytes())) { - request.getSearchRequest().source().parseXContent(context.queryParseContext(innerParser), - context.searchRequestParsers.suggesters); + request.getSearchRequest().source().parseXContent(context.queryParseContext(innerParser)); } }; diff --git a/modules/reindex/src/test/java/org/elasticsearch/index/reindex/RestReindexActionTests.java b/modules/reindex/src/test/java/org/elasticsearch/index/reindex/RestReindexActionTests.java index d2017f3e4e..1fa3b50b3a 100644 --- a/modules/reindex/src/test/java/org/elasticsearch/index/reindex/RestReindexActionTests.java +++ b/modules/reindex/src/test/java/org/elasticsearch/index/reindex/RestReindexActionTests.java @@ -124,7 +124,7 @@ public class RestReindexActionTests extends ESTestCase { } try (XContentParser p = createParser(JsonXContent.jsonXContent, request)) { ReindexRequest r = new ReindexRequest(new SearchRequest(), new IndexRequest()); - SearchRequestParsers searchParsers = new SearchRequestParsers(null); + SearchRequestParsers searchParsers = new SearchRequestParsers(); RestReindexAction.PARSER.parse(p, r, new ReindexParseContext(searchParsers, ParseFieldMatcher.STRICT)); assertEquals("localhost", r.getRemoteInfo().getHost()); assertArrayEquals(new String[] {"source"}, r.getSearchRequest().indices()); @@ -132,7 +132,7 @@ public class RestReindexActionTests extends ESTestCase { } public void testPipelineQueryParameterIsError() throws IOException { - SearchRequestParsers parsers = new SearchRequestParsers(null); + SearchRequestParsers parsers = new SearchRequestParsers(); RestReindexAction action = new RestReindexAction(Settings.EMPTY, mock(RestController.class), parsers, null); FakeRestRequest.Builder request = new FakeRestRequest.Builder(xContentRegistry()); |