(Java) Using primitive arrays instead of Object with map/builder
also simplify and consolidate the builder generic value write handling fixes #3279
This commit is contained in:
parent
2314b8665b
commit
3a0ce0bde8
|
@ -28,7 +28,6 @@ import org.elasticsearch.common.bytes.BytesReference;
|
|||
import org.elasticsearch.common.io.BytesStream;
|
||||
import org.elasticsearch.common.io.FastByteArrayOutputStream;
|
||||
import org.elasticsearch.common.text.Text;
|
||||
import org.elasticsearch.common.xcontent.support.XContentMapConverter;
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.joda.time.ReadableInstant;
|
||||
import org.joda.time.format.DateTimeFormatter;
|
||||
|
@ -647,7 +646,7 @@ public final class XContentBuilder implements BytesStream {
|
|||
endArray();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public XContentBuilder field(XContentBuilderString name, int offset, int length, int... value) throws IOException {
|
||||
assert ((offset >= 0) && (value.length > length));
|
||||
startArray(name);
|
||||
|
@ -722,163 +721,22 @@ public final class XContentBuilder implements BytesStream {
|
|||
}
|
||||
|
||||
public XContentBuilder field(String name, Object value) throws IOException {
|
||||
if (value == null) {
|
||||
nullField(name);
|
||||
return this;
|
||||
}
|
||||
Class type = value.getClass();
|
||||
if (type == String.class) {
|
||||
field(name, (String) value);
|
||||
} else if (type == Float.class) {
|
||||
field(name, ((Float) value).floatValue());
|
||||
} else if (type == Double.class) {
|
||||
field(name, ((Double) value).doubleValue());
|
||||
} else if (type == Integer.class) {
|
||||
field(name, ((Integer) value).intValue());
|
||||
} else if (type == Long.class) {
|
||||
field(name, ((Long) value).longValue());
|
||||
} else if (type == Short.class) {
|
||||
field(name, ((Short) value).shortValue());
|
||||
} else if (type == Byte.class) {
|
||||
field(name, ((Byte) value).byteValue());
|
||||
} else if (type == Boolean.class) {
|
||||
field(name, ((Boolean) value).booleanValue());
|
||||
} else if (value instanceof Date) {
|
||||
field(name, (Date) value);
|
||||
} else if (value instanceof Calendar) {
|
||||
field(name, convertCalendar((Calendar) value));
|
||||
} else if (type == byte[].class) {
|
||||
field(name, (byte[]) value);
|
||||
} else if (value instanceof ReadableInstant) {
|
||||
field(name, (ReadableInstant) value);
|
||||
} else if (value instanceof Map) {
|
||||
//noinspection unchecked
|
||||
field(name, (Map<String, Object>) value);
|
||||
} else if (value instanceof Iterable) {
|
||||
field(name, (Iterable) value);
|
||||
} else if (value instanceof Object[]) {
|
||||
field(name, (Object[]) value);
|
||||
} else if (value instanceof int[]) {
|
||||
field(name, (int[]) value);
|
||||
} else if (value instanceof long[]) {
|
||||
field(name, (long[]) value);
|
||||
} else if (value instanceof float[]) {
|
||||
field(name, (float[]) value);
|
||||
} else if (value instanceof double[]) {
|
||||
field(name, (double[]) value);
|
||||
} else if (value instanceof BytesReference) {
|
||||
field(name, (BytesReference) value);
|
||||
} else if (value instanceof Text) {
|
||||
field(name, (Text) value);
|
||||
} else if (value instanceof ToXContent) {
|
||||
field(name, (ToXContent) value);
|
||||
} else {
|
||||
field(name, value.toString());
|
||||
}
|
||||
field(name);
|
||||
writeValue(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public XContentBuilder field(XContentBuilderString name, Object value) throws IOException {
|
||||
if (value == null) {
|
||||
nullField(name);
|
||||
return this;
|
||||
}
|
||||
Class type = value.getClass();
|
||||
if (type == String.class) {
|
||||
field(name, (String) value);
|
||||
} else if (type == Float.class) {
|
||||
field(name, ((Float) value).floatValue());
|
||||
} else if (type == Double.class) {
|
||||
field(name, ((Double) value).doubleValue());
|
||||
} else if (type == Integer.class) {
|
||||
field(name, ((Integer) value).intValue());
|
||||
} else if (type == Long.class) {
|
||||
field(name, ((Long) value).longValue());
|
||||
} else if (type == Short.class) {
|
||||
field(name, ((Short) value).shortValue());
|
||||
} else if (type == Byte.class) {
|
||||
field(name, ((Byte) value).byteValue());
|
||||
} else if (type == Boolean.class) {
|
||||
field(name, ((Boolean) value).booleanValue());
|
||||
} else if (value instanceof Date) {
|
||||
field(name, (Date) value);
|
||||
} else if (type == byte[].class) {
|
||||
field(name, (byte[]) value);
|
||||
} else if (value instanceof ReadableInstant) {
|
||||
field(name, (ReadableInstant) value);
|
||||
} else if (value instanceof Map) {
|
||||
//noinspection unchecked
|
||||
field(name, (Map<String, Object>) value);
|
||||
} else if (value instanceof Iterable) {
|
||||
field(name, (Iterable) value);
|
||||
} else if (value instanceof Object[]) {
|
||||
field(name, (Object[]) value);
|
||||
} else if (value instanceof int[]) {
|
||||
field(name, (int[]) value);
|
||||
} else if (value instanceof long[]) {
|
||||
field(name, (long[]) value);
|
||||
} else if (value instanceof float[]) {
|
||||
field(name, (float[]) value);
|
||||
} else if (value instanceof double[]) {
|
||||
field(name, (double[]) value);
|
||||
} else if (value instanceof BytesReference) {
|
||||
field(name, (BytesReference) value);
|
||||
} else if (value instanceof Text) {
|
||||
field(name, (Text) value);
|
||||
} else {
|
||||
field(name, value.toString());
|
||||
}
|
||||
field(name);
|
||||
writeValue(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public XContentBuilder value(Object value) throws IOException {
|
||||
if (value == null) {
|
||||
return nullValue();
|
||||
}
|
||||
Class type = value.getClass();
|
||||
if (type == String.class) {
|
||||
value((String) value);
|
||||
} else if (type == Float.class) {
|
||||
value(((Float) value).floatValue());
|
||||
} else if (type == Double.class) {
|
||||
value(((Double) value).doubleValue());
|
||||
} else if (type == Integer.class) {
|
||||
value(((Integer) value).intValue());
|
||||
} else if (type == Long.class) {
|
||||
value(((Long) value).longValue());
|
||||
} else if (type == Short.class) {
|
||||
value(((Short) value).shortValue());
|
||||
} else if (type == Byte.class) {
|
||||
value(((Byte) value).byteValue());
|
||||
} else if (type == Boolean.class) {
|
||||
value((Boolean) value);
|
||||
} else if (type == byte[].class) {
|
||||
value((byte[]) value);
|
||||
} else if (value instanceof Date) {
|
||||
value((Date) value);
|
||||
} else if (value instanceof Calendar) {
|
||||
value(convertCalendar((Calendar) value));
|
||||
} else if (value instanceof ReadableInstant) {
|
||||
value((ReadableInstant) value);
|
||||
} else if (value instanceof BytesReference) {
|
||||
value((BytesReference) value);
|
||||
} else if (value instanceof Text) {
|
||||
value((Text) value);
|
||||
} else if (value instanceof Map) {
|
||||
//noinspection unchecked
|
||||
value((Map<String, Object>) value);
|
||||
} else if (value instanceof Iterable) {
|
||||
value((Iterable) value);
|
||||
} else {
|
||||
throw new IOException("Type not allowed [" + type + "]");
|
||||
}
|
||||
writeValue(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
private Date convertCalendar(Calendar value) {
|
||||
return value.getTime();
|
||||
}
|
||||
|
||||
public XContentBuilder field(String name, boolean value) throws IOException {
|
||||
field(name);
|
||||
generator.writeBoolean(value);
|
||||
|
@ -1120,7 +978,7 @@ public final class XContentBuilder implements BytesStream {
|
|||
if (map == null) {
|
||||
return nullValue();
|
||||
}
|
||||
XContentMapConverter.writeMap(generator, map);
|
||||
writeMap(map);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -1128,7 +986,7 @@ public final class XContentBuilder implements BytesStream {
|
|||
if (map == null) {
|
||||
return nullValue();
|
||||
}
|
||||
XContentMapConverter.writeMap(generator, map);
|
||||
writeMap(map);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -1162,6 +1020,10 @@ public final class XContentBuilder implements BytesStream {
|
|||
}
|
||||
}
|
||||
|
||||
public XContentGenerator generator() {
|
||||
return this.generator;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Object payload() {
|
||||
return this.payload;
|
||||
|
@ -1195,4 +1057,116 @@ public final class XContentBuilder implements BytesStream {
|
|||
BytesArray bytesArray = bytes().toBytesArray();
|
||||
return new String(bytesArray.array(), bytesArray.arrayOffset(), bytesArray.length(), Charsets.UTF_8);
|
||||
}
|
||||
|
||||
|
||||
private void writeMap(Map<String, Object> map) throws IOException {
|
||||
generator.writeStartObject();
|
||||
|
||||
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
||||
field(entry.getKey());
|
||||
Object value = entry.getValue();
|
||||
if (value == null) {
|
||||
generator.writeNull();
|
||||
} else {
|
||||
writeValue(value);
|
||||
}
|
||||
}
|
||||
generator.writeEndObject();
|
||||
}
|
||||
|
||||
private void writeValue(Object value) throws IOException {
|
||||
if (value == null) {
|
||||
generator.writeNull();
|
||||
return;
|
||||
}
|
||||
Class type = value.getClass();
|
||||
if (type == String.class) {
|
||||
generator.writeString((String) value);
|
||||
} else if (type == Integer.class) {
|
||||
generator.writeNumber(((Integer) value).intValue());
|
||||
} else if (type == Long.class) {
|
||||
generator.writeNumber(((Long) value).longValue());
|
||||
} else if (type == Float.class) {
|
||||
generator.writeNumber(((Float) value).floatValue());
|
||||
} else if (type == Double.class) {
|
||||
generator.writeNumber(((Double) value).doubleValue());
|
||||
} else if (type == Short.class) {
|
||||
generator.writeNumber(((Short) value).shortValue());
|
||||
} else if (type == Boolean.class) {
|
||||
generator.writeBoolean(((Boolean) value).booleanValue());
|
||||
} else if (value instanceof Map) {
|
||||
writeMap((Map) value);
|
||||
} else if (value instanceof Iterable) {
|
||||
generator.writeStartArray();
|
||||
for (Object v : (Iterable) value) {
|
||||
writeValue(v);
|
||||
}
|
||||
generator.writeEndArray();
|
||||
} else if (value instanceof Object[]) {
|
||||
generator.writeStartArray();
|
||||
for (Object v : (Object[]) value) {
|
||||
writeValue(v);
|
||||
}
|
||||
generator.writeEndArray();
|
||||
} else if (type == byte[].class) {
|
||||
generator.writeBinary((byte[]) value);
|
||||
} else if (value instanceof Date) {
|
||||
generator.writeString(XContentBuilder.defaultDatePrinter.print(((Date) value).getTime()));
|
||||
} else if (value instanceof Calendar) {
|
||||
generator.writeString(XContentBuilder.defaultDatePrinter.print((((Calendar) value)).getTimeInMillis()));
|
||||
} else if (value instanceof BytesReference) {
|
||||
BytesReference bytes = (BytesReference) value;
|
||||
if (!bytes.hasArray()) {
|
||||
bytes = bytes.toBytesArray();
|
||||
}
|
||||
generator.writeBinary(bytes.array(), bytes.arrayOffset(), bytes.length());
|
||||
} else if (value instanceof Text) {
|
||||
Text text = (Text) value;
|
||||
if (text.hasBytes() && text.bytes().hasArray()) {
|
||||
generator.writeUTF8String(text.bytes().array(), text.bytes().arrayOffset(), text.bytes().length());
|
||||
} else if (text.hasString()) {
|
||||
generator.writeString(text.string());
|
||||
} else {
|
||||
BytesArray bytesArray = text.bytes().toBytesArray();
|
||||
generator.writeUTF8String(bytesArray.array(), bytesArray.arrayOffset(), bytesArray.length());
|
||||
}
|
||||
} else if (value instanceof ToXContent) {
|
||||
((ToXContent) value).toXContent(this, ToXContent.EMPTY_PARAMS);
|
||||
} else if (value instanceof double[]) {
|
||||
generator.writeStartArray();
|
||||
for (double v : (double[]) value) {
|
||||
generator.writeNumber(v);
|
||||
}
|
||||
generator.writeEndArray();
|
||||
} else if (value instanceof long[]) {
|
||||
generator.writeStartArray();
|
||||
for (long v : (long[]) value) {
|
||||
generator.writeNumber(v);
|
||||
}
|
||||
generator.writeEndArray();
|
||||
} else if (value instanceof int[]) {
|
||||
generator.writeStartArray();
|
||||
for (int v : (int[]) value) {
|
||||
generator.writeNumber(v);
|
||||
}
|
||||
generator.writeEndArray();
|
||||
} else if (value instanceof float[]) {
|
||||
generator.writeStartArray();
|
||||
for (float v : (float[]) value) {
|
||||
generator.writeNumber(v);
|
||||
}
|
||||
generator.writeEndArray();
|
||||
} else if (value instanceof short[]) {
|
||||
generator.writeStartArray();
|
||||
for (float v : (short[]) value) {
|
||||
generator.writeNumber(v);
|
||||
}
|
||||
generator.writeEndArray();
|
||||
} else {
|
||||
// if this is a "value" object, like enum, DistanceUnit, ..., just toString it
|
||||
// yea, it can be misleading when toString a Java class, but really, jackson should be used in that case
|
||||
generator.writeString(value.toString());
|
||||
//throw new ElasticSearchIllegalArgumentException("type not supported for generic value conversion: " + type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ import org.elasticsearch.common.Booleans;
|
|||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -118,12 +118,12 @@ public abstract class AbstractXContentParser implements XContentParser {
|
|||
|
||||
@Override
|
||||
public Map<String, Object> map() throws IOException {
|
||||
return XContentMapConverter.readMap(this);
|
||||
return readMap(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> mapOrdered() throws IOException {
|
||||
return XContentMapConverter.readOrderedMap(this);
|
||||
return readOrderedMap(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -143,4 +143,87 @@ public abstract class AbstractXContentParser implements XContentParser {
|
|||
close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static interface MapFactory {
|
||||
Map<String, Object> newMap();
|
||||
}
|
||||
|
||||
static final MapFactory SIMPLE_MAP_FACTORY = new MapFactory() {
|
||||
@Override
|
||||
public Map<String, Object> newMap() {
|
||||
return new HashMap<String, Object>();
|
||||
}
|
||||
};
|
||||
|
||||
static final MapFactory ORDERED_MAP_FACTORY = new MapFactory() {
|
||||
@Override
|
||||
public Map<String, Object> newMap() {
|
||||
return new LinkedHashMap<String, Object>();
|
||||
}
|
||||
};
|
||||
|
||||
static Map<String, Object> readMap(XContentParser parser) throws IOException {
|
||||
return readMap(parser, SIMPLE_MAP_FACTORY);
|
||||
}
|
||||
|
||||
static Map<String, Object> readOrderedMap(XContentParser parser) throws IOException {
|
||||
return readMap(parser, ORDERED_MAP_FACTORY);
|
||||
}
|
||||
|
||||
static Map<String, Object> readMap(XContentParser parser, MapFactory mapFactory) throws IOException {
|
||||
Map<String, Object> map = mapFactory.newMap();
|
||||
XContentParser.Token t = parser.currentToken();
|
||||
if (t == null) {
|
||||
t = parser.nextToken();
|
||||
}
|
||||
if (t == XContentParser.Token.START_OBJECT) {
|
||||
t = parser.nextToken();
|
||||
}
|
||||
for (; t == XContentParser.Token.FIELD_NAME; t = parser.nextToken()) {
|
||||
// Must point to field name
|
||||
String fieldName = parser.currentName();
|
||||
// And then the value...
|
||||
t = parser.nextToken();
|
||||
Object value = readValue(parser, mapFactory, t);
|
||||
map.put(fieldName, value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private static List<Object> readList(XContentParser parser, MapFactory mapFactory, XContentParser.Token t) throws IOException {
|
||||
ArrayList<Object> list = new ArrayList<Object>();
|
||||
while ((t = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||
list.add(readValue(parser, mapFactory, t));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static Object readValue(XContentParser parser, MapFactory mapFactory, XContentParser.Token t) throws IOException {
|
||||
if (t == XContentParser.Token.VALUE_NULL) {
|
||||
return null;
|
||||
} else if (t == XContentParser.Token.VALUE_STRING) {
|
||||
return parser.text();
|
||||
} else if (t == XContentParser.Token.VALUE_NUMBER) {
|
||||
XContentParser.NumberType numberType = parser.numberType();
|
||||
if (numberType == XContentParser.NumberType.INT) {
|
||||
return parser.intValue();
|
||||
} else if (numberType == XContentParser.NumberType.LONG) {
|
||||
return parser.longValue();
|
||||
} else if (numberType == XContentParser.NumberType.FLOAT) {
|
||||
return parser.floatValue();
|
||||
} else if (numberType == XContentParser.NumberType.DOUBLE) {
|
||||
return parser.doubleValue();
|
||||
}
|
||||
} else if (t == XContentParser.Token.VALUE_BOOLEAN) {
|
||||
return parser.booleanValue();
|
||||
} else if (t == XContentParser.Token.START_OBJECT) {
|
||||
return readMap(parser, mapFactory);
|
||||
} else if (t == XContentParser.Token.START_ARRAY) {
|
||||
return readList(parser, mapFactory, t);
|
||||
} else if (t == XContentParser.Token.VALUE_EMBEDDED_OBJECT) {
|
||||
return parser.binaryValue();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,203 +0,0 @@
|
|||
/*
|
||||
* Licensed to ElasticSearch and Shay Banon 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.common.xcontent.support;
|
||||
|
||||
import org.elasticsearch.common.bytes.BytesArray;
|
||||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
import org.elasticsearch.common.text.Text;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentGenerator;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class XContentMapConverter {
|
||||
|
||||
public static interface MapFactory {
|
||||
Map<String, Object> newMap();
|
||||
}
|
||||
|
||||
public static final MapFactory SIMPLE_MAP_FACTORY = new MapFactory() {
|
||||
@Override
|
||||
public Map<String, Object> newMap() {
|
||||
return new HashMap<String, Object>();
|
||||
}
|
||||
};
|
||||
|
||||
public static final MapFactory ORDERED_MAP_FACTORY = new MapFactory() {
|
||||
@Override
|
||||
public Map<String, Object> newMap() {
|
||||
return new LinkedHashMap<String, Object>();
|
||||
}
|
||||
};
|
||||
|
||||
public static Map<String, Object> readMap(XContentParser parser) throws IOException {
|
||||
return readMap(parser, SIMPLE_MAP_FACTORY);
|
||||
}
|
||||
|
||||
public static Map<String, Object> readOrderedMap(XContentParser parser) throws IOException {
|
||||
return readMap(parser, ORDERED_MAP_FACTORY);
|
||||
}
|
||||
|
||||
public static Map<String, Object> readMap(XContentParser parser, MapFactory mapFactory) throws IOException {
|
||||
Map<String, Object> map = mapFactory.newMap();
|
||||
XContentParser.Token t = parser.currentToken();
|
||||
if (t == null) {
|
||||
t = parser.nextToken();
|
||||
}
|
||||
if (t == XContentParser.Token.START_OBJECT) {
|
||||
t = parser.nextToken();
|
||||
}
|
||||
for (; t == XContentParser.Token.FIELD_NAME; t = parser.nextToken()) {
|
||||
// Must point to field name
|
||||
String fieldName = parser.currentName();
|
||||
// And then the value...
|
||||
t = parser.nextToken();
|
||||
Object value = readValue(parser, mapFactory, t);
|
||||
map.put(fieldName, value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private static List<Object> readList(XContentParser parser, MapFactory mapFactory, XContentParser.Token t) throws IOException {
|
||||
ArrayList<Object> list = new ArrayList<Object>();
|
||||
while ((t = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||
list.add(readValue(parser, mapFactory, t));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static Object readValue(XContentParser parser, MapFactory mapFactory, XContentParser.Token t) throws IOException {
|
||||
if (t == XContentParser.Token.VALUE_NULL) {
|
||||
return null;
|
||||
} else if (t == XContentParser.Token.VALUE_STRING) {
|
||||
return parser.text();
|
||||
} else if (t == XContentParser.Token.VALUE_NUMBER) {
|
||||
XContentParser.NumberType numberType = parser.numberType();
|
||||
if (numberType == XContentParser.NumberType.INT) {
|
||||
return parser.intValue();
|
||||
} else if (numberType == XContentParser.NumberType.LONG) {
|
||||
return parser.longValue();
|
||||
} else if (numberType == XContentParser.NumberType.FLOAT) {
|
||||
return parser.floatValue();
|
||||
} else if (numberType == XContentParser.NumberType.DOUBLE) {
|
||||
return parser.doubleValue();
|
||||
}
|
||||
} else if (t == XContentParser.Token.VALUE_BOOLEAN) {
|
||||
return parser.booleanValue();
|
||||
} else if (t == XContentParser.Token.START_OBJECT) {
|
||||
return readMap(parser, mapFactory);
|
||||
} else if (t == XContentParser.Token.START_ARRAY) {
|
||||
return readList(parser, mapFactory, t);
|
||||
} else if (t == XContentParser.Token.VALUE_EMBEDDED_OBJECT) {
|
||||
return parser.binaryValue();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void writeMap(XContentGenerator gen, Map<String, Object> map) throws IOException {
|
||||
gen.writeStartObject();
|
||||
|
||||
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
||||
gen.writeFieldName(entry.getKey());
|
||||
Object value = entry.getValue();
|
||||
if (value == null) {
|
||||
gen.writeNull();
|
||||
} else {
|
||||
writeValue(gen, value);
|
||||
}
|
||||
}
|
||||
|
||||
gen.writeEndObject();
|
||||
}
|
||||
|
||||
private static void writeIterable(XContentGenerator gen, Iterable iterable) throws IOException {
|
||||
gen.writeStartArray();
|
||||
for (Object value : iterable) {
|
||||
writeValue(gen, value);
|
||||
}
|
||||
gen.writeEndArray();
|
||||
}
|
||||
|
||||
private static void writeObjectArray(XContentGenerator gen, Object[] array) throws IOException {
|
||||
gen.writeStartArray();
|
||||
for (Object value : array) {
|
||||
writeValue(gen, value);
|
||||
}
|
||||
gen.writeEndArray();
|
||||
}
|
||||
|
||||
private static void writeValue(XContentGenerator gen, Object value) throws IOException {
|
||||
if (value == null) {
|
||||
gen.writeNull();
|
||||
return;
|
||||
}
|
||||
Class type = value.getClass();
|
||||
if (type == String.class) {
|
||||
gen.writeString((String) value);
|
||||
} else if (type == Integer.class) {
|
||||
gen.writeNumber(((Integer) value).intValue());
|
||||
} else if (type == Long.class) {
|
||||
gen.writeNumber(((Long) value).longValue());
|
||||
} else if (type == Float.class) {
|
||||
gen.writeNumber(((Float) value).floatValue());
|
||||
} else if (type == Double.class) {
|
||||
gen.writeNumber(((Double) value).doubleValue());
|
||||
} else if (type == Short.class) {
|
||||
gen.writeNumber(((Short) value).shortValue());
|
||||
} else if (type == Boolean.class) {
|
||||
gen.writeBoolean(((Boolean) value).booleanValue());
|
||||
} else if (value instanceof Map) {
|
||||
writeMap(gen, (Map) value);
|
||||
} else if (value instanceof Iterable) {
|
||||
writeIterable(gen, (Iterable) value);
|
||||
} else if (value instanceof Object[]) {
|
||||
writeObjectArray(gen, (Object[]) value);
|
||||
} else if (type == byte[].class) {
|
||||
gen.writeBinary((byte[]) value);
|
||||
} else if (value instanceof Date) {
|
||||
gen.writeString(XContentBuilder.defaultDatePrinter.print(((Date) value).getTime()));
|
||||
} else if (value instanceof Calendar) {
|
||||
gen.writeString(XContentBuilder.defaultDatePrinter.print((((Calendar) value)).getTimeInMillis()));
|
||||
} else if (value instanceof BytesReference) {
|
||||
BytesReference bytes = (BytesReference) value;
|
||||
if (!bytes.hasArray()) {
|
||||
bytes = bytes.toBytesArray();
|
||||
}
|
||||
gen.writeBinary(bytes.array(), bytes.arrayOffset(), bytes.length());
|
||||
} else if (value instanceof Text) {
|
||||
Text text = (Text) value;
|
||||
if (text.hasBytes() && text.bytes().hasArray()) {
|
||||
gen.writeUTF8String(text.bytes().array(), text.bytes().arrayOffset(), text.bytes().length());
|
||||
} else if (text.hasString()) {
|
||||
gen.writeString(text.string());
|
||||
} else {
|
||||
BytesArray bytesArray = text.bytes().toBytesArray();
|
||||
gen.writeUTF8String(bytesArray.array(), bytesArray.arrayOffset(), bytesArray.length());
|
||||
}
|
||||
} else {
|
||||
gen.writeString(value.toString());
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue