org.elasticsearch.xcontent.support.MapXContentParser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of elasticsearch-x-content Show documentation
Show all versions of elasticsearch-x-content Show documentation
Elasticsearch subproject :libs:elasticsearch-x-content
The newest version!
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/
package org.elasticsearch.xcontent.support;
import org.elasticsearch.xcontent.DeprecationHandler;
import org.elasticsearch.xcontent.NamedXContentRegistry;
import org.elasticsearch.xcontent.XContentLocation;
import org.elasticsearch.xcontent.XContentType;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.CharBuffer;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* Wraps a map generated by XContentParser's map() method into XContent Parser
*/
public class MapXContentParser extends AbstractXContentParser {
private final XContentType xContentType;
private TokenIterator iterator;
private boolean closed;
public MapXContentParser(
NamedXContentRegistry xContentRegistry,
DeprecationHandler deprecationHandler,
Map map,
XContentType xContentType
) {
super(xContentRegistry, deprecationHandler);
this.xContentType = xContentType;
this.iterator = new MapIterator(null, null, map);
}
@Override
protected boolean doBooleanValue() throws IOException {
if (iterator != null && iterator.currentValue() instanceof Boolean aBoolean) {
return aBoolean;
} else {
throw new IllegalStateException("Cannot get boolean value for the current token " + currentToken());
}
}
@Override
protected short doShortValue() throws IOException {
return numberValue().shortValue();
}
@Override
protected int doIntValue() throws IOException {
return numberValue().intValue();
}
@Override
protected long doLongValue() throws IOException {
return numberValue().longValue();
}
@Override
protected float doFloatValue() throws IOException {
return numberValue().floatValue();
}
@Override
protected double doDoubleValue() throws IOException {
return numberValue().doubleValue();
}
@Override
public XContentType contentType() {
return xContentType;
}
@Override
public void allowDuplicateKeys(boolean allowDuplicateKeys) {
throw new UnsupportedOperationException("Allowing duplicate keys is not possible for maps");
}
@Override
public Token nextToken() throws IOException {
if (iterator == null) {
return null;
} else {
iterator = iterator.next();
}
return currentToken();
}
@Override
public void skipChildren() throws IOException {
Token token = currentToken();
if (token == Token.START_OBJECT || token == Token.START_ARRAY) {
iterator = iterator.skipChildren();
}
}
@Override
public Token currentToken() {
if (iterator == null) {
return null;
} else {
return iterator.currentToken();
}
}
@Override
public String currentName() throws IOException {
if (iterator == null) {
return null;
} else {
return iterator.currentName();
}
}
@Override
public String text() throws IOException {
if (iterator != null) {
if (currentToken() == Token.VALUE_STRING || currentToken() == Token.VALUE_NUMBER || currentToken() == Token.VALUE_BOOLEAN) {
return iterator.currentValue().toString();
} else if (currentToken() == Token.FIELD_NAME) {
return iterator.currentName();
} else {
return null;
}
} else {
throw new IllegalStateException("Cannot get text for the current token " + currentToken());
}
}
@Override
public CharBuffer charBuffer() throws IOException {
throw new UnsupportedOperationException("use text() instead");
}
@Override
public Object objectText() throws IOException {
throw new UnsupportedOperationException("use text() instead");
}
@Override
public Object objectBytes() throws IOException {
throw new UnsupportedOperationException("use text() instead");
}
@Override
public boolean hasTextCharacters() {
return false;
}
@Override
public char[] textCharacters() throws IOException {
throw new UnsupportedOperationException("use text() instead");
}
@Override
public int textLength() throws IOException {
throw new UnsupportedOperationException("use text() instead");
}
@Override
public int textOffset() throws IOException {
throw new UnsupportedOperationException("use text() instead");
}
@Override
public Number numberValue() throws IOException {
if (iterator != null && currentToken() == Token.VALUE_NUMBER) {
return (Number) iterator.currentValue();
} else {
throw new IllegalStateException("Cannot get numeric value for the current token " + currentToken());
}
}
@Override
public NumberType numberType() throws IOException {
Number number = numberValue();
if (number instanceof Integer) {
return NumberType.INT;
} else if (number instanceof BigInteger) {
return NumberType.BIG_INTEGER;
} else if (number instanceof Long) {
return NumberType.LONG;
} else if (number instanceof Float) {
return NumberType.FLOAT;
} else if (number instanceof Double) {
return NumberType.DOUBLE;
} else if (number instanceof BigDecimal) {
return NumberType.BIG_DECIMAL;
}
throw new IllegalStateException("No matching token for number_type [" + number.getClass() + "]");
}
@Override
public byte[] binaryValue() throws IOException {
if (iterator != null && iterator.currentValue() instanceof byte[] bytes) {
return bytes;
} else {
throw new IllegalStateException("Cannot get binary value for the current token " + currentToken());
}
}
@Override
public XContentLocation getTokenLocation() {
return new XContentLocation(0, 0);
}
@Override
public boolean isClosed() {
return closed;
}
@Override
public void close() throws IOException {
closed = true;
}
/**
* Iterator over the elements of the map
*/
private abstract static class TokenIterator {
protected final TokenIterator parent;
protected final String name;
protected Token currentToken;
protected State state = State.BEFORE;
TokenIterator(TokenIterator parent, String name) {
this.parent = parent;
this.name = name;
}
public abstract TokenIterator next();
public abstract TokenIterator skipChildren();
public Token currentToken() {
return currentToken;
}
public abstract Object currentValue();
/**
* name of the field name of the current element
*/
public abstract String currentName();
/**
* field name that the child element needs to inherit.
*
* In most cases this is the same as currentName() except with embedded arrays. In "foo": [[42]] the first START_ARRAY
* token will have the name "foo", but the second START_ARRAY will have no name.
*/
public abstract String childName();
@SuppressWarnings("unchecked")
TokenIterator processValue(Object value) {
if (value instanceof Map) {
return new MapIterator(this, childName(), (Map) value).next();
} else if (value instanceof List) {
return new ArrayIterator(this, childName(), (List