From 93da15f67476679ff8ef67d3fa95a6b31fb76e0c Mon Sep 17 00:00:00 2001 From: Laura Trotta Date: Mon, 29 Jun 2026 18:19:13 +0200 Subject: [PATCH 1/2] supporting _source shortcut --- .../core/search/SourceConfig.java | 273 +++++++++--------- .../spec_issues/SpecIssuesTest.java | 24 ++ 2 files changed, 165 insertions(+), 132 deletions(-) diff --git a/java-client/src/main/java/co/elastic/clients/elasticsearch/core/search/SourceConfig.java b/java-client/src/main/java/co/elastic/clients/elasticsearch/core/search/SourceConfig.java index db59af2dd5..11712877ad 100644 --- a/java-client/src/main/java/co/elastic/clients/elasticsearch/core/search/SourceConfig.java +++ b/java-client/src/main/java/co/elastic/clients/elasticsearch/core/search/SourceConfig.java @@ -24,19 +24,17 @@ import co.elastic.clients.json.JsonpMapper; import co.elastic.clients.json.JsonpSerializable; import co.elastic.clients.json.JsonpUtils; -import co.elastic.clients.json.ObjectDeserializer; -import co.elastic.clients.json.UnionDeserializer; import co.elastic.clients.util.ApiTypeHelper; import co.elastic.clients.util.ObjectBuilder; import co.elastic.clients.util.ObjectBuilderBase; import co.elastic.clients.util.TaggedUnion; import co.elastic.clients.util.TaggedUnionUtils; import jakarta.json.stream.JsonGenerator; -import java.lang.Boolean; -import java.lang.Object; -import java.util.Objects; +import jakarta.json.stream.JsonParser; + +import java.util.EnumSet; +import java.util.List; import java.util.function.Function; -import javax.annotation.Nullable; //---------------------------------------------------------------- // THIS CODE IS GENERATED. MANUAL EDITS WILL BE LOST. @@ -58,135 +56,146 @@ /** * Defines how to fetch a source. Fetching can be disabled entirely, or the * source can be filtered. - * + * * @see API - * specification + * "../../doc-files/api-spec.html#_global.search._types.SourceConfig">API + * specification */ @JsonpDeserializable public class SourceConfig implements TaggedUnion, JsonpSerializable { - public enum Kind { - Filter, Fetch - - } - - private final Kind _kind; - private final Object _value; - - @Override - public final Kind _kind() { - return _kind; - } - - @Override - public final Object _get() { - return _value; - } - - private SourceConfig(Kind kind, Object value) { - this._kind = kind; - this._value = value; - } - - private SourceConfig(Builder builder) { - - this._kind = ApiTypeHelper.requireNonNull(builder._kind, builder, ""); - this._value = ApiTypeHelper.requireNonNull(builder._value, builder, ""); - - } - - public static SourceConfig of(Function> fn) { - return fn.apply(new Builder()).build(); - } - - /** - * Is this variant instance of kind {@code filter}? - */ - public boolean isFilter() { - return _kind == Kind.Filter; - } - - /** - * Get the {@code filter} variant value. - * - * @throws IllegalStateException - * if the current variant is not of the {@code filter} kind. - */ - public SourceFilter filter() { - return TaggedUnionUtils.get(this, Kind.Filter); - } - - /** - * Is this variant instance of kind {@code fetch}? - */ - public boolean isFetch() { - return _kind == Kind.Fetch; - } - - /** - * Get the {@code fetch} variant value. - * - * @throws IllegalStateException - * if the current variant is not of the {@code fetch} kind. - */ - public Boolean fetch() { - return TaggedUnionUtils.get(this, Kind.Fetch); - } - - @Override - public void serialize(JsonGenerator generator, JsonpMapper mapper) { - if (_value instanceof JsonpSerializable) { - ((JsonpSerializable) _value).serialize(generator, mapper); - } else { - switch (_kind) { - case Fetch : - generator.write(((Boolean) this._value)); - - break; - } - } - - } - - @Override - public String toString() { - return JsonpUtils.toString(this); - } - - public static class Builder extends ObjectBuilderBase implements ObjectBuilder { - private Kind _kind; - private Object _value; - - public ObjectBuilder filter(SourceFilter v) { - this._kind = Kind.Filter; - this._value = v; - return this; - } - - public ObjectBuilder filter(Function> fn) { - return this.filter(fn.apply(new SourceFilter.Builder()).build()); - } - - public ObjectBuilder fetch(Boolean v) { - this._kind = Kind.Fetch; - this._value = v; - return this; - } - - public SourceConfig build() { - _checkSingleUse(); - return new SourceConfig(this); - } - - } - - private static JsonpDeserializer buildSourceConfigDeserializer() { - return new UnionDeserializer.Builder(SourceConfig::new, false) - .addMember(Kind.Filter, SourceFilter._DESERIALIZER) - .addMember(Kind.Fetch, JsonpDeserializer.booleanDeserializer()).build(); - } - - public static final JsonpDeserializer _DESERIALIZER = JsonpDeserializer - .lazy(SourceConfig::buildSourceConfigDeserializer); + public enum Kind { + Filter, Fetch + + } + + private final Kind _kind; + private final Object _value; + + @Override + public final Kind _kind() { + return _kind; + } + + @Override + public final Object _get() { + return _value; + } + + private SourceConfig(Kind kind, Object value) { + this._kind = kind; + this._value = value; + } + + private SourceConfig(Builder builder) { + + this._kind = ApiTypeHelper.requireNonNull(builder._kind, builder, ""); + this._value = ApiTypeHelper.requireNonNull(builder._value, builder, ""); + + } + + public static SourceConfig of(Function> fn) { + return fn.apply(new Builder()).build(); + } + + /** + * Is this variant instance of kind {@code filter}? + */ + public boolean isFilter() { + return _kind == Kind.Filter; + } + + /** + * Get the {@code filter} variant value. + * + * @throws IllegalStateException if the current variant is not of the {@code filter} kind. + */ + public SourceFilter filter() { + return TaggedUnionUtils.get(this, Kind.Filter); + } + + /** + * Is this variant instance of kind {@code fetch}? + */ + public boolean isFetch() { + return _kind == Kind.Fetch; + } + + /** + * Get the {@code fetch} variant value. + * + * @throws IllegalStateException if the current variant is not of the {@code fetch} kind. + */ + public Boolean fetch() { + return TaggedUnionUtils.get(this, Kind.Fetch); + } + + @Override + public void serialize(JsonGenerator generator, JsonpMapper mapper) { + if (_value instanceof JsonpSerializable) { + ((JsonpSerializable) _value).serialize(generator, mapper); + } else { + switch (_kind) { + case Fetch: + generator.write(((Boolean) this._value)); + + break; + } + } + + } + + @Override + public String toString() { + return JsonpUtils.toString(this); + } + + public static class Builder extends ObjectBuilderBase implements ObjectBuilder { + private Kind _kind; + private Object _value; + + public ObjectBuilder filter(SourceFilter v) { + this._kind = Kind.Filter; + this._value = v; + return this; + } + + public ObjectBuilder filter(Function> fn) { + return this.filter(fn.apply(new SourceFilter.Builder()).build()); + } + + public ObjectBuilder fetch(Boolean v) { + this._kind = Kind.Fetch; + this._value = v; + return this; + } + + public SourceConfig build() { + _checkSingleUse(); + return new SourceConfig(this); + } + + } + + public static final JsonpDeserializer _DESERIALIZER = JsonpDeserializer + .lazy(() -> JsonpDeserializer.of(EnumSet.of(JsonParser.Event.START_OBJECT, + JsonParser.Event.START_ARRAY, + JsonParser.Event.VALUE_TRUE, JsonParser.Event.VALUE_FALSE), (parser, mapper, event) -> { + return switch (event) { + case VALUE_TRUE -> SourceConfig.of(b -> b.fetch(true)); + case VALUE_FALSE -> SourceConfig.of(b -> b.fetch(false)); + case START_ARRAY -> { + List includes = JsonpDeserializer + .arrayDeserializer(JsonpDeserializer.stringDeserializer()) + .deserialize(parser, mapper, event); + yield SourceConfig.of(b -> b.filter(f -> f.includes(includes))); + } + case START_OBJECT -> { + SourceFilter filter = SourceFilter._DESERIALIZER.deserialize(parser, mapper, event); + yield SourceConfig.of(b -> b.filter(filter)); + } + default -> null; + }; + })); } diff --git a/java-client/src/test/java/co/elastic/clients/elasticsearch/spec_issues/SpecIssuesTest.java b/java-client/src/test/java/co/elastic/clients/elasticsearch/spec_issues/SpecIssuesTest.java index 4feda07928..2f0d413686 100644 --- a/java-client/src/test/java/co/elastic/clients/elasticsearch/spec_issues/SpecIssuesTest.java +++ b/java-client/src/test/java/co/elastic/clients/elasticsearch/spec_issues/SpecIssuesTest.java @@ -46,6 +46,8 @@ import java.io.InputStream; import java.io.StringReader; +import java.util.Arrays; +import java.util.Collections; /** * Test issues related to the API specifications. @@ -54,6 +56,28 @@ */ public class SpecIssuesTest extends ModelTestCase { + @Test + public void i1245_sourceAsArray() { + // "_source" also accepts an array of field names as a shortcut for SourceFilter.includes + SearchRequest array = fromJson("{\"_source\":[\"date\",\"distributor\"]}", SearchRequest.class); + assertTrue(array.source().isFilter()); + assertEquals(Arrays.asList("date", "distributor"), array.source().filter().includes()); + + // The object form still works, with all SourceFilter fields set + SearchRequest object = fromJson( + "{\"_source\":{\"includes\":[\"date\",\"distributor\"],\"excludes\":[\"secret\"],\"exclude_vectors\":true}}", + SearchRequest.class); + assertTrue(object.source().isFilter()); + assertEquals(Arrays.asList("date", "distributor"), object.source().filter().includes()); + assertEquals(Collections.singletonList("secret"), object.source().filter().excludes()); + assertTrue(object.source().filter().excludeVectors()); + + // The boolean form still works + SearchRequest bool = fromJson("{\"_source\":false}", SearchRequest.class); + assertTrue(bool.source().isFetch()); + assertFalse(bool.source().fetch()); + } + @Test public void i0328_charFilter() throws Exception { // Both mappings and mappings_path are optional From 554831449a231dca1cce7f5c46e6296f06bc6d4e Mon Sep 17 00:00:00 2001 From: Laura Trotta Date: Mon, 29 Jun 2026 18:24:36 +0200 Subject: [PATCH 2/2] regen --- .../core/search/SourceConfig.java | 280 +++++++++--------- 1 file changed, 142 insertions(+), 138 deletions(-) diff --git a/java-client/src/main/java/co/elastic/clients/elasticsearch/core/search/SourceConfig.java b/java-client/src/main/java/co/elastic/clients/elasticsearch/core/search/SourceConfig.java index 11712877ad..c4053b4068 100644 --- a/java-client/src/main/java/co/elastic/clients/elasticsearch/core/search/SourceConfig.java +++ b/java-client/src/main/java/co/elastic/clients/elasticsearch/core/search/SourceConfig.java @@ -24,6 +24,7 @@ import co.elastic.clients.json.JsonpMapper; import co.elastic.clients.json.JsonpSerializable; import co.elastic.clients.json.JsonpUtils; +import co.elastic.clients.json.ObjectDeserializer; import co.elastic.clients.util.ApiTypeHelper; import co.elastic.clients.util.ObjectBuilder; import co.elastic.clients.util.ObjectBuilderBase; @@ -31,10 +32,13 @@ import co.elastic.clients.util.TaggedUnionUtils; import jakarta.json.stream.JsonGenerator; import jakarta.json.stream.JsonParser; - +import java.lang.Boolean; +import java.lang.Object; import java.util.EnumSet; import java.util.List; +import java.util.Objects; import java.util.function.Function; +import javax.annotation.Nullable; //---------------------------------------------------------------- // THIS CODE IS GENERATED. MANUAL EDITS WILL BE LOST. @@ -56,146 +60,146 @@ /** * Defines how to fetch a source. Fetching can be disabled entirely, or the * source can be filtered. - * + * * @see API - * specification + * "../../doc-files/api-spec.html#_global.search._types.SourceConfig">API + * specification */ @JsonpDeserializable public class SourceConfig implements TaggedUnion, JsonpSerializable { - public enum Kind { - Filter, Fetch - - } - - private final Kind _kind; - private final Object _value; - - @Override - public final Kind _kind() { - return _kind; - } - - @Override - public final Object _get() { - return _value; - } - - private SourceConfig(Kind kind, Object value) { - this._kind = kind; - this._value = value; - } - - private SourceConfig(Builder builder) { - - this._kind = ApiTypeHelper.requireNonNull(builder._kind, builder, ""); - this._value = ApiTypeHelper.requireNonNull(builder._value, builder, ""); - - } - - public static SourceConfig of(Function> fn) { - return fn.apply(new Builder()).build(); - } - - /** - * Is this variant instance of kind {@code filter}? - */ - public boolean isFilter() { - return _kind == Kind.Filter; - } - - /** - * Get the {@code filter} variant value. - * - * @throws IllegalStateException if the current variant is not of the {@code filter} kind. - */ - public SourceFilter filter() { - return TaggedUnionUtils.get(this, Kind.Filter); - } - - /** - * Is this variant instance of kind {@code fetch}? - */ - public boolean isFetch() { - return _kind == Kind.Fetch; - } - - /** - * Get the {@code fetch} variant value. - * - * @throws IllegalStateException if the current variant is not of the {@code fetch} kind. - */ - public Boolean fetch() { - return TaggedUnionUtils.get(this, Kind.Fetch); - } - - @Override - public void serialize(JsonGenerator generator, JsonpMapper mapper) { - if (_value instanceof JsonpSerializable) { - ((JsonpSerializable) _value).serialize(generator, mapper); - } else { - switch (_kind) { - case Fetch: - generator.write(((Boolean) this._value)); - - break; - } - } - - } - - @Override - public String toString() { - return JsonpUtils.toString(this); - } - - public static class Builder extends ObjectBuilderBase implements ObjectBuilder { - private Kind _kind; - private Object _value; - - public ObjectBuilder filter(SourceFilter v) { - this._kind = Kind.Filter; - this._value = v; - return this; - } - - public ObjectBuilder filter(Function> fn) { - return this.filter(fn.apply(new SourceFilter.Builder()).build()); - } - - public ObjectBuilder fetch(Boolean v) { - this._kind = Kind.Fetch; - this._value = v; - return this; - } - - public SourceConfig build() { - _checkSingleUse(); - return new SourceConfig(this); - } - - } - - public static final JsonpDeserializer _DESERIALIZER = JsonpDeserializer - .lazy(() -> JsonpDeserializer.of(EnumSet.of(JsonParser.Event.START_OBJECT, - JsonParser.Event.START_ARRAY, - JsonParser.Event.VALUE_TRUE, JsonParser.Event.VALUE_FALSE), (parser, mapper, event) -> { - return switch (event) { - case VALUE_TRUE -> SourceConfig.of(b -> b.fetch(true)); - case VALUE_FALSE -> SourceConfig.of(b -> b.fetch(false)); - case START_ARRAY -> { - List includes = JsonpDeserializer - .arrayDeserializer(JsonpDeserializer.stringDeserializer()) - .deserialize(parser, mapper, event); - yield SourceConfig.of(b -> b.filter(f -> f.includes(includes))); - } - case START_OBJECT -> { - SourceFilter filter = SourceFilter._DESERIALIZER.deserialize(parser, mapper, event); - yield SourceConfig.of(b -> b.filter(filter)); - } - default -> null; - }; - })); + public enum Kind { + Filter, Fetch + + } + + private final Kind _kind; + private final Object _value; + + @Override + public final Kind _kind() { + return _kind; + } + + @Override + public final Object _get() { + return _value; + } + + private SourceConfig(Kind kind, Object value) { + this._kind = kind; + this._value = value; + } + + private SourceConfig(Builder builder) { + + this._kind = ApiTypeHelper.requireNonNull(builder._kind, builder, ""); + this._value = ApiTypeHelper.requireNonNull(builder._value, builder, ""); + + } + + public static SourceConfig of(Function> fn) { + return fn.apply(new Builder()).build(); + } + + /** + * Is this variant instance of kind {@code filter}? + */ + public boolean isFilter() { + return _kind == Kind.Filter; + } + + /** + * Get the {@code filter} variant value. + * + * @throws IllegalStateException + * if the current variant is not of the {@code filter} kind. + */ + public SourceFilter filter() { + return TaggedUnionUtils.get(this, Kind.Filter); + } + + /** + * Is this variant instance of kind {@code fetch}? + */ + public boolean isFetch() { + return _kind == Kind.Fetch; + } + + /** + * Get the {@code fetch} variant value. + * + * @throws IllegalStateException + * if the current variant is not of the {@code fetch} kind. + */ + public Boolean fetch() { + return TaggedUnionUtils.get(this, Kind.Fetch); + } + + @Override + public void serialize(JsonGenerator generator, JsonpMapper mapper) { + if (_value instanceof JsonpSerializable) { + ((JsonpSerializable) _value).serialize(generator, mapper); + } else { + switch (_kind) { + case Fetch : + generator.write(((Boolean) this._value)); + + break; + } + } + + } + + @Override + public String toString() { + return JsonpUtils.toString(this); + } + + public static class Builder extends ObjectBuilderBase implements ObjectBuilder { + private Kind _kind; + private Object _value; + + public ObjectBuilder filter(SourceFilter v) { + this._kind = Kind.Filter; + this._value = v; + return this; + } + + public ObjectBuilder filter(Function> fn) { + return this.filter(fn.apply(new SourceFilter.Builder()).build()); + } + + public ObjectBuilder fetch(Boolean v) { + this._kind = Kind.Fetch; + this._value = v; + return this; + } + + public SourceConfig build() { + _checkSingleUse(); + return new SourceConfig(this); + } + + } + + public static final JsonpDeserializer _DESERIALIZER = JsonpDeserializer + .lazy(() -> JsonpDeserializer.of(EnumSet.of(JsonParser.Event.START_OBJECT, JsonParser.Event.START_ARRAY, + JsonParser.Event.VALUE_TRUE, JsonParser.Event.VALUE_FALSE), (parser, mapper, event) -> { + return switch (event) { + case VALUE_TRUE -> SourceConfig.of(b -> b.fetch(true)); + case VALUE_FALSE -> SourceConfig.of(b -> b.fetch(false)); + case START_ARRAY -> { + List includes = JsonpDeserializer + .arrayDeserializer(JsonpDeserializer.stringDeserializer()) + .deserialize(parser, mapper, event); + yield SourceConfig.of(b -> b.filter(f -> f.includes(includes))); + } + case START_OBJECT -> { + SourceFilter filter = SourceFilter._DESERIALIZER.deserialize(parser, mapper, event); + yield SourceConfig.of(b -> b.filter(filter)); + } + default -> null; + }; + })); }