Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XContentBuilder to handle BigInteger and BigDecimal #32888

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.file.Path;
import java.time.ZonedDateTime;
import java.util.Arrays;
Expand Down Expand Up @@ -103,7 +105,8 @@ public static XContentBuilder builder(XContent xContent, Set<String> includes, S
writers.put(ZonedDateTime.class, (b, v) -> b.value(v.toString()));
writers.put(Calendar.class, XContentBuilder::timeValue);
writers.put(GregorianCalendar.class, XContentBuilder::timeValue);

writers.put(BigInteger.class, (b, v) -> b.value((BigInteger) v));
writers.put(BigDecimal.class, (b, v) -> b.value((BigDecimal) v));

Map<Class<?>, HumanReadableTransformer> humanReadableTransformer = new HashMap<>();
Map<Class<?>, Function<Object, Object>> dateTransformers = new HashMap<>();
Expand Down Expand Up @@ -546,6 +549,81 @@ public XContentBuilder value(short value) throws IOException {
return this;
}

////////////////////////////////////////////////////////////////////////////
// BigInteger
//////////////////////////////////

public XContentBuilder field(String name, BigInteger value) throws IOException {
if (value == null) {
return nullField(name);
}
ensureNameNotNull(name);
generator.writeNumberField(name, value);
return this;
}

public XContentBuilder array(String name, BigInteger[] values) throws IOException {
return field(name).values(values);
}

private XContentBuilder values(BigInteger[] values) throws IOException {
if (values == null) {
return nullValue();
}
startArray();
for (BigInteger b : values) {
value(b);
}
endArray();
return this;
}

public XContentBuilder value(BigInteger value) throws IOException {
if (value == null) {
return nullValue();
}
generator.writeNumber(value);
return this;
}


////////////////////////////////////////////////////////////////////////////
// BigDecimal
//////////////////////////////////

public XContentBuilder field(String name, BigDecimal value) throws IOException {
if (value == null) {
return nullField(name);
}
ensureNameNotNull(name);
generator.writeNumberField(name, value);
return this;
}

public XContentBuilder array(String name, BigDecimal[] values) throws IOException {
return field(name).values(values);
}

private XContentBuilder values(BigDecimal[] values) throws IOException {
if (values == null) {
return nullValue();
}
startArray();
for (BigDecimal b : values) {
value(b);
}
endArray();
return this;
}

public XContentBuilder value(BigDecimal value) throws IOException {
if (value == null) {
return nullValue();
}
generator.writeNumber(value);
return this;
}

////////////////////////////////////////////////////////////////////////////
// String
//////////////////////////////////
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import java.io.Flushable;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.BigInteger;

public interface XContentGenerator extends Closeable, Flushable {

Expand Down Expand Up @@ -70,6 +72,14 @@ public interface XContentGenerator extends Closeable, Flushable {

void writeNumber(short value) throws IOException;

void writeNumber(BigInteger value) throws IOException;

void writeNumberField(String name, BigInteger value) throws IOException;

void writeNumber(BigDecimal value) throws IOException;

void writeNumberField(String name, BigDecimal value) throws IOException;

void writeStringField(String name, String value) throws IOException;

void writeString(String value) throws IOException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Objects;
import java.util.Set;

Expand Down Expand Up @@ -226,6 +228,19 @@ public void writeNumberField(String name, int value) throws IOException {
generator.writeNumberField(name, value);
}

@Override
public void writeNumberField(String name, BigInteger value) throws IOException {
// as jackson's JsonGenerator doesn't have this method for BigInteger
// we have to implement it ourselves
generator.writeFieldName(name);
generator.writeNumber(value);
}

@Override
public void writeNumberField(String name, BigDecimal value) throws IOException {
generator.writeNumberField(name, value);
}

@Override
public void writeNumber(int value) throws IOException {
generator.writeNumber(value);
Expand All @@ -246,6 +261,16 @@ public void writeNumber(short value) throws IOException {
generator.writeNumber(value);
}

@Override
public void writeNumber(BigInteger value) throws IOException {
generator.writeNumber(value);
}

@Override
public void writeNumber(BigDecimal value) throws IOException {
generator.writeNumber(value);
}

@Override
public void writeStringField(String name, String value) throws IOException {
generator.writeStringField(name, value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,16 @@ setup:
- match: { hits.hits.0._source.bigint: 72057594037927936 }
- is_false: hits.hits.0._source.include.field2


---
"_source filtering on bigint":
- do:
search:
body:
_source: ["bigint"]
query: { match_all: {} }
- match: { hits.hits.0._source.bigint: 72057594037927936 }

---
"fields in body":
- do:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.file.Path;
import java.time.DayOfWeek;
Expand Down Expand Up @@ -266,6 +267,36 @@ public void testShorts() throws IOException {
.endObject());
}

public void testBigIntegers() throws Exception {
assertResult("{'bigint':null}", () -> builder().startObject().field("bigint", (BigInteger) null).endObject());
assertResult("{'bigint':[]}", () -> builder().startObject().array("bigint", new BigInteger[]{}).endObject());

BigInteger bigInteger = BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE);
String result = "{'bigint':" + bigInteger.toString() + "}";
assertResult(result, () -> builder().startObject().field("bigint", bigInteger).endObject());

result = "{'bigint':[" + bigInteger.toString() + "," + bigInteger.toString() + "," + bigInteger.toString() +"]}";
assertResult(result, () -> builder()
.startObject()
.array("bigint", bigInteger, bigInteger, bigInteger)
.endObject());
}

public void testBigDecimals() throws Exception {
assertResult("{'bigdecimal':null}", () -> builder().startObject().field("bigdecimal", (BigInteger) null).endObject());
assertResult("{'bigdecimal':[]}", () -> builder().startObject().array("bigdecimal", new BigInteger[]{}).endObject());

BigDecimal bigDecimal = new BigDecimal("234.43");
String result = "{'bigdecimal':" + bigDecimal.toString() + "}";
assertResult(result, () -> builder().startObject().field("bigdecimal", bigDecimal).endObject());

result = "{'bigdecimal':[" + bigDecimal.toString() + "," + bigDecimal.toString() + "," + bigDecimal.toString() +"]}";
assertResult(result, () -> builder()
.startObject()
.array("bigdecimal", bigDecimal, bigDecimal, bigDecimal)
.endObject());
}

public void testStrings() throws IOException {
assertResult("{'string':null}", () -> builder().startObject().field("string", (String) null).endObject());
assertResult("{'string':'value'}", () -> builder().startObject().field("string", "value").endObject());
Expand Down