org.hl7.fhir.dstu3.formats.JsonCreatorCanonical Maven / Gradle / Ivy
package org.hl7.fhir.dstu3.formats;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Stack;
import com.google.gson.stream.JsonWriter;
public class JsonCreatorCanonical implements JsonCreator {
public class JsonCanValue {
String name;
private JsonCanValue(String name) {
this.name = name;
}
}
private class JsonCanNumberValue extends JsonCanValue {
private BigDecimal value;
private JsonCanNumberValue(String name, BigDecimal value) {
super(name);
this.value = value;
}
}
private class JsonCanIntegerValue extends JsonCanValue {
private Integer value;
private JsonCanIntegerValue(String name, Integer value) {
super(name);
this.value = value;
}
}
private class JsonCanBooleanValue extends JsonCanValue {
private Boolean value;
private JsonCanBooleanValue(String name, Boolean value) {
super(name);
this.value = value;
}
}
private class JsonCanStringValue extends JsonCanValue {
private String value;
private JsonCanStringValue(String name, String value) {
super(name);
this.value = value;
}
}
private class JsonCanNullValue extends JsonCanValue {
private JsonCanNullValue(String name) {
super(name);
}
}
public class JsonCanObject extends JsonCanValue {
boolean array;
List children = new ArrayList();
public JsonCanObject(String name, boolean array) {
super(name);
this.array = array;
}
public void addProp(JsonCanValue obj) {
children.add(obj);
}
}
Stack stack;
JsonCanObject root;
JsonWriter gson;
String name;
public JsonCreatorCanonical(OutputStreamWriter osw) {
stack = new Stack();
gson = new JsonWriter(osw);
name = null;
}
private String takeName() {
String res = name;
name = null;
return res;
}
@Override
public void setIndent(String indent) {
if (!indent.equals(""))
throw new Error("do not use pretty when canonical is set");
gson.setIndent(indent);
}
@Override
public void beginObject() throws IOException {
JsonCanObject obj = new JsonCanObject(takeName(), false);
if (stack.isEmpty())
root = obj;
else
stack.peek().addProp(obj);
stack.push(obj);
}
@Override
public void endObject() throws IOException {
stack.pop();
}
@Override
public void nullValue() throws IOException {
stack.peek().addProp(new JsonCanNullValue(takeName()));
}
@Override
public void name(String name) throws IOException {
this.name = name;
}
@Override
public void value(String value) throws IOException {
stack.peek().addProp(new JsonCanStringValue(takeName(), value));
}
@Override
public void value(Boolean value) throws IOException {
stack.peek().addProp(new JsonCanBooleanValue(takeName(), value));
}
@Override
public void value(BigDecimal value) throws IOException {
stack.peek().addProp(new JsonCanNumberValue(takeName(), value));
}
@Override
public void value(Integer value) throws IOException {
stack.peek().addProp(new JsonCanIntegerValue(takeName(), value));
}
@Override
public void beginArray() throws IOException {
JsonCanObject obj = new JsonCanObject(takeName(), true);
if (!stack.isEmpty())
stack.peek().addProp(obj);
stack.push(obj);
}
@Override
public void endArray() throws IOException {
stack.pop();
}
@Override
public void finish() throws IOException {
writeObject(root);
}
private void writeObject(JsonCanObject obj) throws IOException {
gson.beginObject();
List names = new ArrayList();
for (JsonCanValue v : obj.children)
names.add(v.name);
Collections.sort(names);
for (String n : names) {
gson.name(n);
JsonCanValue v = getPropForName(n, obj.children);
if (v instanceof JsonCanNumberValue)
gson.value(((JsonCanNumberValue) v).value);
else if (v instanceof JsonCanIntegerValue)
gson.value(((JsonCanIntegerValue) v).value);
else if (v instanceof JsonCanBooleanValue)
gson.value(((JsonCanBooleanValue) v).value);
else if (v instanceof JsonCanStringValue)
gson.value(((JsonCanStringValue) v).value);
else if (v instanceof JsonCanNullValue)
gson.nullValue();
else if (v instanceof JsonCanObject) {
JsonCanObject o = (JsonCanObject) v;
if (o.array)
writeArray(o);
else
writeObject(o);
} else
throw new Error("not possible");
}
gson.endObject();
}
private JsonCanValue getPropForName(String name, List children) {
for (JsonCanValue child : children)
if (child.name.equals(name))
return child;
return null;
}
private void writeArray(JsonCanObject arr) throws IOException {
gson.beginArray();
for (JsonCanValue v : arr.children) {
if (v instanceof JsonCanNumberValue)
gson.value(((JsonCanNumberValue) v).value);
else if (v instanceof JsonCanIntegerValue)
gson.value(((JsonCanIntegerValue) v).value);
else if (v instanceof JsonCanBooleanValue)
gson.value(((JsonCanBooleanValue) v).value);
else if (v instanceof JsonCanStringValue)
gson.value(((JsonCanStringValue) v).value);
else if (v instanceof JsonCanNullValue)
gson.nullValue();
else if (v instanceof JsonCanObject) {
JsonCanObject o = (JsonCanObject) v;
if (o.array)
writeArray(o);
else
writeObject(o);
} else
throw new Error("not possible");
}
gson.endArray();
}
@Override
public void link(String href) {
// not used
}
}