Decouple Text and Geopoint from XContentBuilder (#29119)

This removes the `Text` and `Geopoint` special handling from `XContentBuilder`.
Instead, these classes now implement `ToXContentFragment` and render themselves
accordingly.

This allows us to further decouple XContentBuilder from Elasticsearch-specific
classes so it can be factored into a standalone lib at a later time.

Relates to #28504
This commit is contained in:
Lee Hinman 2018-03-19 08:54:10 -06:00 committed by GitHub
parent bf05c600c4
commit 3025295f7e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 38 deletions

View File

@ -25,13 +25,17 @@ import org.apache.lucene.geo.GeoEncodingUtils;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.util.BitUtil;
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.ToXContentFragment;
import org.elasticsearch.common.xcontent.XContentBuilder;
import java.io.IOException;
import java.util.Arrays;
import static org.elasticsearch.common.geo.GeoHashUtils.mortonEncode;
import static org.elasticsearch.common.geo.GeoHashUtils.stringEncode;
public final class GeoPoint {
public final class GeoPoint implements ToXContentFragment {
private double lat;
private double lon;
@ -184,4 +188,9 @@ public final class GeoPoint {
public static GeoPoint fromGeohash(long geohashLong) {
return new GeoPoint().resetFromGeoHash(geohashLong);
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
return builder.latlon(lat, lon);
}
}

View File

@ -20,14 +20,18 @@ package org.elasticsearch.common.text;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.ToXContentFragment;
import org.elasticsearch.common.xcontent.XContentBuilder;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
/**
* Both {@link String} and {@link BytesReference} representation of the text. Starts with one of those, and if
* the other is requests, caches the other one in a local reference so no additional conversion will be needed.
*/
public final class Text implements Comparable<Text> {
public final class Text implements Comparable<Text>, ToXContentFragment {
public static final Text[] EMPTY_ARRAY = new Text[0];
@ -113,4 +117,15 @@ public final class Text implements Comparable<Text> {
public int compareTo(Text text) {
return bytes().compareTo(text.bytes());
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
if (hasString()) {
return builder.value(this.string());
} else {
// TODO: TextBytesOptimization we can use a buffer here to convert it? maybe add a
// request to jackson to support InputStream as well?
return builder.utf8Value(this.bytes().toBytesRef());
}
}
}

View File

@ -20,9 +20,7 @@
package org.elasticsearch.common.xcontent;
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.lease.Releasable;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.util.CollectionUtils;
@ -98,7 +96,6 @@ public final class XContentBuilder implements Releasable, Flushable {
writers.put(double[].class, (b, v) -> b.values((double[]) v));
writers.put(Float.class, (b, v) -> b.value((Float) v));
writers.put(float[].class, (b, v) -> b.values((float[]) v));
writers.put(GeoPoint.class, (b, v) -> b.value((GeoPoint) v));
writers.put(Integer.class, (b, v) -> b.value((Integer) v));
writers.put(int[].class, (b, v) -> b.values((int[]) v));
writers.put(Long.class, (b, v) -> b.value((Long) v));
@ -107,7 +104,6 @@ public final class XContentBuilder implements Releasable, Flushable {
writers.put(short[].class, (b, v) -> b.values((short[]) v));
writers.put(String.class, (b, v) -> b.value((String) v));
writers.put(String[].class, (b, v) -> b.values((String[]) v));
writers.put(Text.class, (b, v) -> b.value((Text) v));
WRITERS = Collections.unmodifiableMap(writers);
}
@ -630,26 +626,6 @@ public final class XContentBuilder implements Releasable, Flushable {
return this;
}
////////////////////////////////////////////////////////////////////////////
// Text
//////////////////////////////////
public XContentBuilder field(String name, Text value) throws IOException {
return field(name).value(value);
}
public XContentBuilder value(Text value) throws IOException {
if (value == null) {
return nullValue();
} else if (value.hasString()) {
return value(value.string());
} else {
// TODO: TextBytesOptimization we can use a buffer here to convert it? maybe add a
// request to jackson to support InputStream as well?
return utf8Value(value.bytes().toBytesRef());
}
}
////////////////////////////////////////////////////////////////////////////
// Date
//////////////////////////////////
@ -714,20 +690,9 @@ public final class XContentBuilder implements Releasable, Flushable {
}
////////////////////////////////////////////////////////////////////////////
// GeoPoint & LatLon
// LatLon
//////////////////////////////////
public XContentBuilder field(String name, GeoPoint value) throws IOException {
return field(name).value(value);
}
public XContentBuilder value(GeoPoint value) throws IOException {
if (value == null) {
return nullValue();
}
return latlon(value.getLat(), value.getLon());
}
public XContentBuilder latlon(String name, double lat, double lon) throws IOException {
return field(name).latlon(lat, lon);
}