Register Highlighter instances instead of classes (#18859)

This change detaches highlighter registration from Guice. It's just a
small step into the right direction.
This commit is contained in:
Simon Willnauer 2016-06-14 17:04:58 +02:00 committed by GitHub
parent d7e3f9e4eb
commit ee2ba13cce
6 changed files with 85 additions and 98 deletions

View File

@ -0,0 +1,63 @@
/*
* 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;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.search.highlight.FastVectorHighlighter;
import org.elasticsearch.search.highlight.Highlighter;
import org.elasticsearch.search.highlight.PlainHighlighter;
import org.elasticsearch.search.highlight.PostingsHighlighter;
import java.util.HashMap;
import java.util.Map;
/**
* An extensions point and registry for all the highlighters a node supports.
*/
public final class Highlighters {
private final Map<String, Highlighter> parsers = new HashMap<>();
Highlighters(Settings settings) {
registerHighlighter("fvh", new FastVectorHighlighter(settings));
registerHighlighter("plain", new PlainHighlighter());
registerHighlighter("postings", new PostingsHighlighter());
}
/**
* Returns the highlighter for the given key or <code>null</code> if there is no highlighter registered for that key.
*/
public Highlighter get(String key) {
return parsers.get(key);
}
/**
* Registers a highlighter for the given key
* @param key the key the highlighter should be referenced by in the search request
* @param highlighter the highlighter instance
*/
void registerHighlighter(String key, Highlighter highlighter) {
if (highlighter == null) {
throw new IllegalArgumentException("Can't register null highlighter for key: [" + key + "]");
}
if (parsers.putIfAbsent(key, highlighter) != null) {
throw new IllegalArgumentException("Can't register the same [highlighter] more than once for [" + key + "]");
}
}
}

View File

@ -28,7 +28,6 @@ import org.elasticsearch.common.inject.multibindings.Multibinder;
import org.elasticsearch.common.io.stream.NamedWriteable; import org.elasticsearch.common.io.stream.NamedWriteable;
import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.common.lucene.search.function.ScoreFunction;
import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.ParseFieldRegistry; import org.elasticsearch.common.xcontent.ParseFieldRegistry;
@ -250,7 +249,6 @@ import org.elasticsearch.search.fetch.source.FetchSourceSubPhase;
import org.elasticsearch.search.fetch.version.VersionFetchSubPhase; import org.elasticsearch.search.fetch.version.VersionFetchSubPhase;
import org.elasticsearch.search.highlight.HighlightPhase; import org.elasticsearch.search.highlight.HighlightPhase;
import org.elasticsearch.search.highlight.Highlighter; import org.elasticsearch.search.highlight.Highlighter;
import org.elasticsearch.search.highlight.Highlighters;
import org.elasticsearch.search.query.QueryPhase; import org.elasticsearch.search.query.QueryPhase;
import org.elasticsearch.search.rescore.QueryRescorerBuilder; import org.elasticsearch.search.rescore.QueryRescorerBuilder;
import org.elasticsearch.search.rescore.RescoreBuilder; import org.elasticsearch.search.rescore.RescoreBuilder;
@ -270,9 +268,8 @@ import java.util.Set;
*/ */
public class SearchModule extends AbstractModule { public class SearchModule extends AbstractModule {
private final Highlighters highlighters = new Highlighters(); private final Highlighters highlighters;
private final Suggesters suggesters; private final Suggesters suggesters;
private final ParseFieldRegistry<ScoreFunctionParser<?>> scoreFunctionParserRegistry = new ParseFieldRegistry<>("score_function"); private final ParseFieldRegistry<ScoreFunctionParser<?>> scoreFunctionParserRegistry = new ParseFieldRegistry<>("score_function");
private final IndicesQueriesRegistry queryParserRegistry = new IndicesQueriesRegistry(); private final IndicesQueriesRegistry queryParserRegistry = new IndicesQueriesRegistry();
private final ParseFieldRegistry<Aggregator.Parser> aggregationParserRegistry = new ParseFieldRegistry<>("aggregation"); private final ParseFieldRegistry<Aggregator.Parser> aggregationParserRegistry = new ParseFieldRegistry<>("aggregation");
@ -298,7 +295,7 @@ public class SearchModule extends AbstractModule {
this.settings = settings; this.settings = settings;
this.namedWriteableRegistry = namedWriteableRegistry; this.namedWriteableRegistry = namedWriteableRegistry;
suggesters = new Suggesters(namedWriteableRegistry); suggesters = new Suggesters(namedWriteableRegistry);
highlighters = new Highlighters(settings);
registerBuiltinScoreFunctionParsers(); registerBuiltinScoreFunctionParsers();
registerBuiltinQueryParsers(); registerBuiltinQueryParsers();
registerBuiltinRescorers(); registerBuiltinRescorers();
@ -308,8 +305,8 @@ public class SearchModule extends AbstractModule {
registerBuiltinMovingAverageModels(); registerBuiltinMovingAverageModels();
} }
public void registerHighlighter(String key, Class<? extends Highlighter> clazz) { public void registerHighlighter(String key, Highlighter highligher) {
highlighters.registerExtension(key, clazz); highlighters.registerHighlighter(key, highligher);
} }
public void registerSuggester(String key, Suggester<?> suggester) { public void registerSuggester(String key, Suggester<?> suggester) {
@ -331,13 +328,6 @@ public class SearchModule extends AbstractModule {
namedWriteableRegistry.register(ScoreFunctionBuilder.class, functionName.getPreferredName(), reader); namedWriteableRegistry.register(ScoreFunctionBuilder.class, functionName.getPreferredName(), reader);
} }
/**
* Fetch the registry of {@linkplain ScoreFunction}s. This is public so extensions can access the score functions.
*/
public ParseFieldRegistry<ScoreFunctionParser<?>> getScoreFunctionParserRegistry() {
return scoreFunctionParserRegistry;
}
/** /**
* Register a new ValueFormat. * Register a new ValueFormat.
*/ */
@ -441,10 +431,6 @@ public class SearchModule extends AbstractModule {
namedWriteableRegistry.register(PipelineAggregatorBuilder.class, aggregationName.getPreferredName(), reader); namedWriteableRegistry.register(PipelineAggregatorBuilder.class, aggregationName.getPreferredName(), reader);
} }
public AggregatorParsers getAggregatorParsers() {
return aggregatorParsers;
}
@Override @Override
protected void configure() { protected void configure() {
bind(IndicesQueriesRegistry.class).toInstance(queryParserRegistry); bind(IndicesQueriesRegistry.class).toInstance(queryParserRegistry);
@ -473,7 +459,7 @@ public class SearchModule extends AbstractModule {
} }
protected void configureHighlighters() { protected void configureHighlighters() {
highlighters.bind(binder()); binder().bind(Highlighters.class).toInstance(highlighters);
} }
protected void configureAggs() { protected void configureAggs() {

View File

@ -30,6 +30,7 @@ import org.elasticsearch.index.mapper.core.KeywordFieldMapper;
import org.elasticsearch.index.mapper.core.StringFieldMapper; import org.elasticsearch.index.mapper.core.StringFieldMapper;
import org.elasticsearch.index.mapper.core.TextFieldMapper; import org.elasticsearch.index.mapper.core.TextFieldMapper;
import org.elasticsearch.index.mapper.internal.SourceFieldMapper; import org.elasticsearch.index.mapper.internal.SourceFieldMapper;
import org.elasticsearch.search.Highlighters;
import org.elasticsearch.search.SearchParseElement; import org.elasticsearch.search.SearchParseElement;
import org.elasticsearch.search.fetch.FetchSubPhase; import org.elasticsearch.search.fetch.FetchSubPhase;
import org.elasticsearch.search.internal.InternalSearchHit; import org.elasticsearch.search.internal.InternalSearchHit;

View File

@ -1,69 +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.highlight;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.ExtensionPoint;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
/**
* An extensions point and registry for all the highlighters a node supports.
*/
public class Highlighters extends ExtensionPoint.ClassMap<Highlighter> {
private static final String FVH = "fvh";
private static final String PLAIN = "plain";
private static final String POSTINGS = "postings";
private final Map<String, Highlighter> parsers;
public Highlighters(){
this(Collections.emptyMap());
}
private Highlighters(Map<String, Highlighter> parsers) {
super("highlighter", Highlighter.class, new HashSet<>(Arrays.asList(FVH, PLAIN, POSTINGS)),
Highlighters.class);
this.parsers = Collections.unmodifiableMap(parsers);
}
@Inject
public Highlighters(Settings settings, Map<String, Highlighter> parsers) {
this(addBuiltIns(settings, parsers));
}
private static Map<String, Highlighter> addBuiltIns(Settings settings, Map<String, Highlighter> parsers) {
Map<String, Highlighter> map = new HashMap<>();
map.put(FVH, new FastVectorHighlighter(settings));
map.put(PLAIN, new PlainHighlighter());
map.put(POSTINGS, new PostingsHighlighter());
map.putAll(parsers);
return map;
}
public Highlighter get(String type) {
return parsers.get(type);
}
}

View File

@ -29,8 +29,9 @@ import org.elasticsearch.index.query.QueryParser;
import org.elasticsearch.index.query.TermQueryBuilder; import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.indices.query.IndicesQueriesRegistry; import org.elasticsearch.indices.query.IndicesQueriesRegistry;
import org.elasticsearch.search.highlight.CustomHighlighter; import org.elasticsearch.search.highlight.CustomHighlighter;
import org.elasticsearch.search.highlight.Highlighter; import org.elasticsearch.search.highlight.FastVectorHighlighter;
import org.elasticsearch.search.highlight.PlainHighlighter; import org.elasticsearch.search.highlight.PlainHighlighter;
import org.elasticsearch.search.highlight.PostingsHighlighter;
import org.elasticsearch.search.suggest.CustomSuggester; import org.elasticsearch.search.suggest.CustomSuggester;
import org.elasticsearch.search.suggest.phrase.PhraseSuggester; import org.elasticsearch.search.suggest.phrase.PhraseSuggester;
@ -48,7 +49,7 @@ public class SearchModuleTests extends ModuleTestCase {
public void testDoubleRegister() { public void testDoubleRegister() {
SearchModule module = new SearchModule(Settings.EMPTY, new NamedWriteableRegistry()); SearchModule module = new SearchModule(Settings.EMPTY, new NamedWriteableRegistry());
try { try {
module.registerHighlighter("fvh", PlainHighlighter.class); module.registerHighlighter("fvh", new PlainHighlighter());
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
assertEquals(e.getMessage(), "Can't register the same [highlighter] more than once for [fvh]"); assertEquals(e.getMessage(), "Can't register the same [highlighter] more than once for [fvh]");
} }
@ -70,13 +71,18 @@ public class SearchModuleTests extends ModuleTestCase {
public void testRegisterHighlighter() { public void testRegisterHighlighter() {
SearchModule module = new SearchModule(Settings.EMPTY, new NamedWriteableRegistry()); SearchModule module = new SearchModule(Settings.EMPTY, new NamedWriteableRegistry());
module.registerHighlighter("custom", CustomHighlighter.class); module.registerHighlighter("custom", new CustomHighlighter());
try { IllegalArgumentException exception = expectThrows(IllegalArgumentException.class,
module.registerHighlighter("custom", CustomHighlighter.class); () -> module.registerHighlighter("custom", new CustomHighlighter()));
} catch (IllegalArgumentException e) { assertEquals("Can't register the same [highlighter] more than once for [custom]", exception.getMessage());
assertEquals(e.getMessage(), "Can't register the same [highlighter] more than once for [custom]");
} exception = expectThrows(IllegalArgumentException.class,
assertMapMultiBinding(module, Highlighter.class, CustomHighlighter.class); () -> module.registerHighlighter("custom", null));
assertEquals("Can't register null highlighter for key: [custom]", exception.getMessage());
assertInstanceBinding(module, Highlighters.class, (h) -> h.get("custom").getClass() == CustomHighlighter.class
&& h.get("fvh").getClass() == FastVectorHighlighter.class
&& h.get("plain").getClass() == PlainHighlighter.class
&& h.get("postings").getClass() == PostingsHighlighter.class);
} }
public void testRegisterQueryParserDuplicate() { public void testRegisterQueryParserDuplicate() {

View File

@ -35,6 +35,6 @@ public class CustomHighlighterPlugin extends Plugin {
} }
public void onModule(SearchModule highlightModule) { public void onModule(SearchModule highlightModule) {
highlightModule.registerHighlighter("test-custom", CustomHighlighter.class); highlightModule.registerHighlighter("test-custom", new CustomHighlighter());
} }
} }