Merge some equivalent interfaces (#22816)

Remove `FromXContent` and use `CheckedFunction` instead.
Remove `FromXContentWithContext` and use `ContentParser` instead.
This commit is contained in:
Nik Everett 2017-01-26 13:15:29 -05:00 committed by GitHub
parent 2abe948cd7
commit f8c28711be
13 changed files with 51 additions and 68 deletions

View File

@ -26,6 +26,7 @@ import org.elasticsearch.cluster.routing.allocation.command.AllocateStalePrimary
import org.elasticsearch.cluster.routing.allocation.command.AllocationCommand;
import org.elasticsearch.cluster.routing.allocation.command.CancelAllocationCommand;
import org.elasticsearch.cluster.routing.allocation.command.MoveAllocationCommand;
import org.elasticsearch.common.CheckedFunction;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
import org.elasticsearch.common.io.stream.Writeable;
@ -34,7 +35,7 @@ import org.elasticsearch.common.settings.Setting.Property;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.BigArrays;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.common.xcontent.NamedXContentRegistry.FromXContent;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.http.HttpServerTransport;
import org.elasticsearch.indices.breaker.CircuitBreakerService;
import org.elasticsearch.plugins.NetworkPlugin;
@ -46,6 +47,7 @@ import org.elasticsearch.transport.TransportInterceptor;
import org.elasticsearch.transport.TransportRequest;
import org.elasticsearch.transport.TransportRequestHandler;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@ -166,7 +168,7 @@ public final class NetworkModule {
* it is the name under which the command's reader is registered.
*/
private static <T extends AllocationCommand> void registerAllocationCommand(Writeable.Reader<T> reader,
FromXContent<T> parser, ParseField commandName) {
CheckedFunction<XContentParser, T, IOException> parser, ParseField commandName) {
namedXContents.add(new NamedXContentRegistry.Entry(AllocationCommand.class, commandName, parser));
namedWriteables.add(new NamedWriteableRegistry.Entry(AllocationCommand.class, commandName.getPreferredName(), reader));
}

View File

@ -19,6 +19,7 @@
package org.elasticsearch.common.xcontent;
import org.elasticsearch.common.CheckedFunction;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.xcontent.ObjectParser.ValueType;
@ -36,14 +37,6 @@ import java.util.function.BiFunction;
public abstract class AbstractObjectParser<Value, Context>
implements BiFunction<XContentParser, Context, Value>, ContextParser<Context, Value> {
/**
* Reads an object right from the parser without any context.
*/
@FunctionalInterface
public interface NoContextParser<T> {
T parse(XContentParser p) throws IOException;
}
/**
* Declare some field. Usually it is easier to use {@link #declareString(BiConsumer, ParseField)} or
* {@link #declareObject(BiConsumer, ContextParser, ParseField)} rather than call this directly.
@ -51,11 +44,12 @@ public abstract class AbstractObjectParser<Value, Context>
public abstract <T> void declareField(BiConsumer<Value, T> consumer, ContextParser<Context, T> parser, ParseField parseField,
ValueType type);
public <T> void declareField(BiConsumer<Value, T> consumer, NoContextParser<T> parser, ParseField parseField, ValueType type) {
public <T> void declareField(BiConsumer<Value, T> consumer, CheckedFunction<XContentParser, T, IOException> parser,
ParseField parseField, ValueType type) {
if (parser == null) {
throw new IllegalArgumentException("[parser] is required");
}
declareField(consumer, (p, c) -> parser.parse(p), parseField, type);
declareField(consumer, (p, c) -> parser.apply(p), parseField, type);
}
public <T> void declareObject(BiConsumer<Value, T> consumer, ContextParser<Context, T> objectParser, ParseField field) {
@ -121,7 +115,7 @@ public abstract class AbstractObjectParser<Value, Context>
}
public void declareRawObject(BiConsumer<Value, BytesReference> consumer, ParseField field) {
NoContextParser<BytesReference> bytesParser = p -> {
CheckedFunction<XContentParser, BytesReference, IOException> bytesParser = p -> {
try (XContentBuilder builder = JsonXContent.contentBuilder()) {
builder.prettyPrint();
builder.copyCurrentStructure(p);

View File

@ -20,6 +20,7 @@
package org.elasticsearch.common.xcontent;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.common.CheckedFunction;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.io.stream.StreamInput;
@ -47,25 +48,6 @@ public class NamedXContentRegistry {
*/
public static final NamedXContentRegistry EMPTY = new NamedXContentRegistry(emptyList());
/**
* Parses an object with the type T from parser.
*/
public interface FromXContent<T> {
/**
* Parses an object with the type T from parser.
*/
T fromXContent(XContentParser parser) throws IOException;
}
/**
* Parses an object with the type T from parser.
* @deprecated prefer {@link FromXContent} if possible
*/
@Deprecated
public interface FromXContentWithContext<T> {
T fromXContent(XContentParser parser, Object context) throws IOException;
}
/**
* An entry in the {@linkplain NamedXContentRegistry} containing the name of the object and the parser that can parse it.
*/
@ -77,20 +59,20 @@ public class NamedXContentRegistry {
public final ParseField name;
/** A parser capability of parser the entry's class. */
private final FromXContentWithContext<?> parser;
private final ContextParser<Object, ?> parser;
/** Creates a new entry which can be stored by the registry. */
public <T> Entry(Class<T> categoryClass, ParseField name, FromXContent<? extends T> parser) {
public <T> Entry(Class<T> categoryClass, ParseField name, CheckedFunction<XContentParser, ? extends T, IOException> parser) {
this.categoryClass = Objects.requireNonNull(categoryClass);
this.name = Objects.requireNonNull(name);
this.parser = Objects.requireNonNull((p, c) -> parser.fromXContent(p));
this.parser = Objects.requireNonNull((p, c) -> parser.apply(p));
}
/**
* Creates a new entry which can be stored by the registry.
* @deprecated prefer {@link Entry#Entry(Class, ParseField, FromXContent)}. Contexts will be removed when possible
* @deprecated prefer {@link Entry#Entry(Class, ParseField, CheckedFunction)}. Contexts will be removed when possible
*/
@Deprecated
public <T> Entry(Class<T> categoryClass, ParseField name, FromXContentWithContext<? extends T> parser) {
public <T> Entry(Class<T> categoryClass, ParseField name, ContextParser<Object, ? extends T> parser) {
this.categoryClass = Objects.requireNonNull(categoryClass);
this.name = Objects.requireNonNull(name);
this.parser = Objects.requireNonNull(parser);
@ -159,7 +141,7 @@ public class NamedXContentRegistry {
throw new ParsingException(parser.getTokenLocation(),
"Unknown " + categoryClass.getSimpleName() + " [" + name + "]: Parser didn't match");
}
return categoryClass.cast(entry.parser.fromXContent(parser, context));
return categoryClass.cast(entry.parser.parse(parser, context));
}
/**

View File

@ -22,13 +22,14 @@ package org.elasticsearch.plugins;
import org.apache.lucene.search.Query;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.CheckedFunction;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.io.stream.NamedWriteable;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.common.lucene.search.function.ScoreFunction;
import org.elasticsearch.common.xcontent.AbstractObjectParser.NoContextParser;
import org.elasticsearch.common.xcontent.XContent;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryParser;
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilder;
@ -50,6 +51,7 @@ import org.elasticsearch.search.fetch.subphase.highlight.Highlighter;
import org.elasticsearch.search.suggest.Suggester;
import org.elasticsearch.search.suggest.SuggestionBuilder;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
@ -150,7 +152,7 @@ public interface SearchPlugin {
/**
* Specification for a {@link Suggester}.
*/
class SuggesterSpec<T extends SuggestionBuilder<T>> extends SearchExtensionSpec<T, NoContextParser<T>> {
class SuggesterSpec<T extends SuggestionBuilder<T>> extends SearchExtensionSpec<T, CheckedFunction<XContentParser, T, IOException>> {
/**
* Specification of custom {@link Suggester}.
*
@ -161,7 +163,7 @@ public interface SearchPlugin {
* {@link StreamInput}
* @param parser the parser the reads the query suggester from xcontent
*/
public SuggesterSpec(ParseField name, Writeable.Reader<T> reader, NoContextParser<T> parser) {
public SuggesterSpec(ParseField name, Writeable.Reader<T> reader, CheckedFunction<XContentParser, T, IOException> parser) {
super(name, reader, parser);
}
@ -174,7 +176,7 @@ public interface SearchPlugin {
* {@link StreamInput}
* @param parser the parser the reads the suggester builder from xcontent
*/
public SuggesterSpec(String name, Writeable.Reader<T> reader, NoContextParser<T> parser) {
public SuggesterSpec(String name, Writeable.Reader<T> reader, CheckedFunction<XContentParser, T, IOException> parser) {
super(name, reader, parser);
}
}
@ -347,12 +349,13 @@ public interface SearchPlugin {
* Specification for a {@link SearchExtBuilder} which represents an additional section that can be
* parsed in a search request (within the ext element).
*/
class SearchExtSpec<T extends SearchExtBuilder> extends SearchExtensionSpec<T, NoContextParser<T>> {
public SearchExtSpec(ParseField name, Writeable.Reader<? extends T> reader, NoContextParser<T> parser) {
class SearchExtSpec<T extends SearchExtBuilder> extends SearchExtensionSpec<T, CheckedFunction<XContentParser, T, IOException>> {
public SearchExtSpec(ParseField name, Writeable.Reader<? extends T> reader,
CheckedFunction<XContentParser, T, IOException> parser) {
super(name, reader, parser);
}
public SearchExtSpec(String name, Writeable.Reader<? extends T> reader, NoContextParser<T> parser) {
public SearchExtSpec(String name, Writeable.Reader<? extends T> reader, CheckedFunction<XContentParser, T, IOException> parser) {
super(name, reader, parser);
}
}

View File

@ -19,10 +19,10 @@
package org.elasticsearch.repositories.blobstore;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.common.CheckedFunction;
import org.elasticsearch.common.blobstore.BlobContainer;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.common.xcontent.NamedXContentRegistry.FromXContent;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentParser;
@ -40,7 +40,7 @@ public abstract class BlobStoreFormat<T extends ToXContent> {
protected final String blobNameFormat;
protected final FromXContent<T> reader;
protected final CheckedFunction<XContentParser, T, IOException> reader;
protected final NamedXContentRegistry namedXContentRegistry;
@ -61,7 +61,8 @@ public abstract class BlobStoreFormat<T extends ToXContent> {
* @param blobNameFormat format of the blobname in {@link String#format(Locale, String, Object...)} format
* @param reader the prototype object that can deserialize objects with type T
*/
protected BlobStoreFormat(String blobNameFormat, FromXContent<T> reader, NamedXContentRegistry namedXContentRegistry) {
protected BlobStoreFormat(String blobNameFormat, CheckedFunction<XContentParser, T, IOException> reader,
NamedXContentRegistry namedXContentRegistry) {
this.reader = reader;
this.blobNameFormat = blobNameFormat;
this.namedXContentRegistry = namedXContentRegistry;
@ -109,7 +110,7 @@ public abstract class BlobStoreFormat<T extends ToXContent> {
protected T read(BytesReference bytes) throws IOException {
try (XContentParser parser = XContentHelper.createParser(namedXContentRegistry, bytes)) {
T obj = reader.fromXContent(parser);
T obj = reader.apply(parser);
return obj;
}
}

View File

@ -23,6 +23,7 @@ import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexFormatTooNewException;
import org.apache.lucene.index.IndexFormatTooOldException;
import org.apache.lucene.store.OutputStreamIndexOutput;
import org.elasticsearch.common.CheckedFunction;
import org.elasticsearch.common.blobstore.BlobContainer;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.bytes.BytesReference;
@ -33,10 +34,10 @@ import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.lucene.store.ByteArrayIndexInput;
import org.elasticsearch.common.lucene.store.IndexOutputOutputStream;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.common.xcontent.NamedXContentRegistry.FromXContent;
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.gateway.CorruptStateException;
@ -73,7 +74,7 @@ public class ChecksumBlobStoreFormat<T extends ToXContent> extends BlobStoreForm
* @param compress true if the content should be compressed
* @param xContentType content type that should be used for write operations
*/
public ChecksumBlobStoreFormat(String codec, String blobNameFormat, FromXContent<T> reader,
public ChecksumBlobStoreFormat(String codec, String blobNameFormat, CheckedFunction<XContentParser, T, IOException> reader,
NamedXContentRegistry namedXContentRegistry, boolean compress, XContentType xContentType) {
super(blobNameFormat, reader, namedXContentRegistry);
this.xContentType = xContentType;
@ -87,7 +88,7 @@ public class ChecksumBlobStoreFormat<T extends ToXContent> extends BlobStoreForm
* @param reader prototype object that can deserialize T from XContent
* @param compress true if the content should be compressed
*/
public ChecksumBlobStoreFormat(String codec, String blobNameFormat, FromXContent<T> reader,
public ChecksumBlobStoreFormat(String codec, String blobNameFormat, CheckedFunction<XContentParser, T, IOException> reader,
NamedXContentRegistry namedXContentRegistry, boolean compress) {
this(codec, blobNameFormat, reader, namedXContentRegistry, compress, DEFAULT_X_CONTENT_TYPE);
}

View File

@ -19,12 +19,12 @@
package org.elasticsearch.search;
import org.elasticsearch.common.CheckedFunction;
import org.elasticsearch.common.io.stream.NamedWriteable;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.AbstractObjectParser.NoContextParser;
import org.elasticsearch.plugins.SearchPlugin;
import org.elasticsearch.plugins.SearchPlugin.SearchExtSpec;
@ -35,7 +35,7 @@ import org.elasticsearch.plugins.SearchPlugin.SearchExtSpec;
* read from the incoming stream, usually done adding a constructor that takes {@link StreamInput} as
* an argument.
*
* Registration happens through {@link SearchPlugin#getSearchExts()}, which also needs a {@link NoContextParser} that's able to parse
* Registration happens through {@link SearchPlugin#getSearchExts()}, which also needs a {@link CheckedFunction} that's able to parse
* the incoming request from the REST layer into the proper {@link SearchExtBuilder} subclass.
*
* {@link #getWriteableName()} must return the same name as the one used for the registration

View File

@ -590,9 +590,8 @@ public class SearchModule {
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)));
suggester.getParser()));
}
private Map<String, Highlighter> setupHighlighters(Settings settings, List<SearchPlugin> plugins) {
@ -711,8 +710,7 @@ public class SearchModule {
}
private void registerSearchExt(SearchExtSpec<?> spec) {
// TODO merge NoContextParser and ToXContent
namedXContents.add(new NamedXContentRegistry.Entry(SearchExtBuilder.class, spec.getName(), p -> spec.getParser().parse(p)));
namedXContents.add(new NamedXContentRegistry.Entry(SearchExtBuilder.class, spec.getName(), spec.getParser()));
namedWriteables.add(new NamedWriteableRegistry.Entry(SearchExtBuilder.class, spec.getName().getPreferredName(), spec.getReader()));
}

View File

@ -19,16 +19,17 @@
package org.elasticsearch.search.aggregations.bucket.histogram;
import org.elasticsearch.common.CheckedFunction;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.common.rounding.Rounding;
import org.elasticsearch.common.xcontent.AbstractObjectParser.NoContextParser;
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
import org.elasticsearch.common.xcontent.ObjectParser.ValueType;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentParser.Token;
import org.elasticsearch.search.DocValueFormat;
import org.elasticsearch.search.SearchParseException;
@ -72,7 +73,7 @@ public class ExtendedBounds implements ToXContent, Writeable {
return new ExtendedBounds(min, max, minAsStr, maxAsStr);
});
static {
NoContextParser<Object> longOrString = p -> {
CheckedFunction<XContentParser, Object, IOException> longOrString = p -> {
if (p.currentToken() == Token.VALUE_NUMBER) {
return p.longValue(false);
}

View File

@ -19,11 +19,11 @@
package org.elasticsearch.common.xcontent;
import org.elasticsearch.common.CheckedFunction;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.xcontent.AbstractObjectParser.NoContextParser;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.test.ESTestCase;
import org.hamcrest.Matcher;
@ -51,7 +51,7 @@ public class ConstructingObjectParserTests extends ESTestCase {
new ParseField("test"), ObjectParser.ValueType.STRING));
assertEquals("[parser] is required", e.getMessage());
e = expectThrows(IllegalArgumentException.class, () -> objectParser.declareField(
(o, v) -> {}, (NoContextParser<Object>) null,
(o, v) -> {}, (CheckedFunction<XContentParser, Object, IOException>) null,
new ParseField("test"), ObjectParser.ValueType.STRING));
assertEquals("[parser] is required", e.getMessage());
e = expectThrows(IllegalArgumentException.class, () -> objectParser.declareField(

View File

@ -18,9 +18,9 @@
*/
package org.elasticsearch.common.xcontent;
import org.elasticsearch.common.CheckedFunction;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.xcontent.AbstractObjectParser.NoContextParser;
import org.elasticsearch.common.xcontent.ObjectParser.NamedObjectParser;
import org.elasticsearch.common.xcontent.ObjectParser.ValueType;
import org.elasticsearch.common.xcontent.json.JsonXContent;
@ -82,7 +82,7 @@ public class ObjectParserTests extends ESTestCase {
new ParseField("test"), ObjectParser.ValueType.STRING));
assertEquals("[parser] is required", e.getMessage());
e = expectThrows(IllegalArgumentException.class, () -> objectParser.declareField(
(o, v) -> {}, (NoContextParser<Object>) null,
(o, v) -> {}, (CheckedFunction<XContentParser, Object, IOException>) null,
new ParseField("test"), ObjectParser.ValueType.STRING));
assertEquals("[parser] is required", e.getMessage());
e = expectThrows(IllegalArgumentException.class, () -> objectParser.declareField(

View File

@ -20,12 +20,12 @@
package org.elasticsearch.search;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.common.CheckedFunction;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.AbstractObjectParser.NoContextParser;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
@ -143,7 +143,7 @@ public abstract class AbstractSearchTestCase extends ESTestCase {
}
}
private static class TestSearchExtParser<T extends SearchExtBuilder> implements NoContextParser<T> {
private static class TestSearchExtParser<T extends SearchExtBuilder> implements CheckedFunction<XContentParser, T, IOException> {
private final Function<String, T> searchExtBuilderFunction;
TestSearchExtParser(Function<String, T> searchExtBuilderFunction) {
@ -151,7 +151,7 @@ public abstract class AbstractSearchTestCase extends ESTestCase {
}
@Override
public T parse(XContentParser parser) throws IOException {
public T apply(XContentParser parser) throws IOException {
return searchExtBuilderFunction.apply(parseField(parser));
}

View File

@ -41,6 +41,7 @@ import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.cluster.metadata.MetaDataIndexStateService;
import org.elasticsearch.cluster.routing.allocation.decider.EnableAllocationDecider;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.CheckedFunction;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.Priority;
@ -111,7 +112,7 @@ public class DedicatedClusterSnapshotRestoreIT extends AbstractSnapshotIntegTest
private <T extends MetaData.Custom> void registerMetaDataCustom(String name, Writeable.Reader<T> reader,
Writeable.Reader<NamedDiff> diffReader,
NamedXContentRegistry.FromXContent<T> parser) {
CheckedFunction<XContentParser, T, IOException> parser) {
namedWritables.add(new NamedWriteableRegistry.Entry(MetaData.Custom.class, name, reader));
namedWritables.add(new NamedWriteableRegistry.Entry(NamedDiff.class, name, diffReader));
namedXContents.add(new NamedXContentRegistry.Entry(MetaData.Custom.class, new ParseField(name), parser));