org.h2.util.json.JSONValueTarget Maven / Gradle / Ivy
/*
* Copyright 2004-2019 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (https://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.util.json;
import java.math.BigDecimal;
import java.util.ArrayDeque;
/**
* JSON value target.
*/
public final class JSONValueTarget extends JSONTarget {
private final ArrayDeque stack;
private final ArrayDeque names;
private boolean needSeparator;
private String memberName;
private JSONValue result;
/**
* Creates new instance of JSON value target.
*/
public JSONValueTarget() {
stack = new ArrayDeque<>();
names = new ArrayDeque<>();
}
@Override
public void startObject() {
beforeValue();
names.push(memberName != null ? memberName : "");
memberName = null;
stack.push(new JSONObject());
}
@Override
public void endObject() {
if (memberName != null) {
throw new IllegalStateException();
}
JSONValue value = stack.poll();
if (!(value instanceof JSONObject)) {
throw new IllegalStateException();
}
memberName = names.pop();
afterValue(value);
}
@Override
public void startArray() {
beforeValue();
names.push(memberName != null ? memberName : "");
memberName = null;
stack.push(new JSONArray());
}
@Override
public void endArray() {
JSONValue value = stack.poll();
if (!(value instanceof JSONArray)) {
throw new IllegalStateException();
}
memberName = names.pop();
afterValue(value);
}
@Override
public void member(String name) {
if (memberName != null || !(stack.peek() instanceof JSONObject)) {
throw new IllegalStateException();
}
memberName = name;
beforeValue();
}
@Override
public void valueNull() {
beforeValue();
afterValue(JSONNull.NULL);
}
@Override
public void valueFalse() {
beforeValue();
afterValue(JSONBoolean.FALSE);
}
@Override
public void valueTrue() {
beforeValue();
afterValue(JSONBoolean.TRUE);
}
@Override
public void valueNumber(BigDecimal number) {
beforeValue();
afterValue(new JSONNumber(number));
}
@Override
public void valueString(String string) {
beforeValue();
afterValue(new JSONString(string));
}
private void beforeValue() {
if (memberName == null && stack.peek() instanceof JSONObject) {
throw new IllegalStateException();
}
if (needSeparator) {
if (stack.isEmpty()) {
throw new IllegalStateException();
}
needSeparator = false;
}
}
private void afterValue(JSONValue value) {
JSONValue parent = stack.peek();
if (parent == null) {
result = value;
} else if (parent instanceof JSONObject) {
((JSONObject) parent).addMember(memberName, value);
} else {
((JSONArray) parent).addElement(value);
}
needSeparator = true;
memberName = null;
}
@Override
public boolean isPropertyExpected() {
return memberName == null && stack.peek() instanceof JSONObject;
}
@Override
public boolean isValueSeparatorExpected() {
return needSeparator;
}
@Override
public JSONValue getResult() {
if (!stack.isEmpty() || result == null) {
throw new IllegalStateException();
}
return result;
}
}