io.ebeaninternal.server.json.DJsonContext Maven / Gradle / Ivy
package io.ebeaninternal.server.json;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.core.PrettyPrinter;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import io.ebean.FetchPath;
import io.ebean.bean.EntityBean;
import io.ebean.config.JsonConfig;
import io.ebean.plugin.BeanType;
import io.ebean.text.json.EJson;
import io.ebean.text.json.JsonIOException;
import io.ebean.text.json.JsonReadOptions;
import io.ebean.text.json.JsonWriteBeanVisitor;
import io.ebean.text.json.JsonWriteOptions;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.api.SpiJsonContext;
import io.ebeaninternal.api.json.SpiJsonReader;
import io.ebeaninternal.api.json.SpiJsonWriter;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.type.TypeManager;
import io.ebeaninternal.util.ParamTypeHelper;
import io.ebeaninternal.util.ParamTypeHelper.ManyType;
import io.ebeaninternal.util.ParamTypeHelper.TypeInfo;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
/**
* Default implementation of JsonContext.
*/
public final class DJsonContext implements SpiJsonContext {
private static final PrettyPrinter PRETTY_PRINTER = new Pretty();
private final SpiEbeanServer server;
private final JsonFactory jsonFactory;
private final Object defaultObjectMapper;
private final JsonConfig.Include defaultInclude;
private final DJsonScalar jsonScalar;
private static class Pretty extends DefaultPrettyPrinter {
Pretty() {
_objectFieldValueSeparatorWithSpaces = ": ";
}
}
public DJsonContext(SpiEbeanServer server, JsonFactory jsonFactory, TypeManager typeManager) {
this.server = server;
this.jsonFactory = (jsonFactory != null) ? jsonFactory : new JsonFactory();
this.defaultObjectMapper = this.server.config().getObjectMapper();
this.defaultInclude = this.server.config().getJsonInclude();
this.jsonScalar = new DJsonScalar(typeManager);
}
@Override
public void writeScalar(JsonGenerator generator, Object scalarValue) throws IOException {
jsonScalar.write(generator, scalarValue);
}
@Override
public boolean isSupportedType(Type genericType) {
return server.isSupportedType(genericType);
}
@Override
public JsonGenerator createGenerator(Writer writer) throws JsonIOException {
try {
return jsonFactory.createGenerator(writer);
} catch (IOException e) {
throw new JsonIOException(e);
}
}
@Override
public JsonParser createParser(Reader reader) throws JsonIOException {
try {
return jsonFactory.createParser(reader);
} catch (IOException e) {
throw new JsonIOException(e);
}
}
@Override
public T toBean(Class cls, String json) throws JsonIOException {
return toBean(cls, new StringReader(json));
}
@Override
public T toBean(Class cls, String json, JsonReadOptions options) throws JsonIOException {
return toBean(cls, new StringReader(json), options);
}
@Override
public T toBean(Class cls, Reader jsonReader) throws JsonIOException {
return toBean(cls, createParser(jsonReader));
}
@Override
public T toBean(Class cls, Reader jsonReader, JsonReadOptions options) throws JsonIOException {
return toBean(cls, createParser(jsonReader), options);
}
@Override
public T toBean(Class cls, JsonParser parser) throws JsonIOException {
return toBean(cls, parser, null);
}
@Override
public T toBean(Class cls, JsonParser parser, JsonReadOptions options) throws JsonIOException {
BeanDescriptor desc = getDescriptor(cls);
try {
return desc.jsonRead(new ReadJson(desc, parser, options, determineObjectMapper(options), false), null, null);
} catch (IOException e) {
throw new JsonIOException(e);
}
}
@Override
public void toBean(T target, String json) throws JsonIOException {
toBean(target, new StringReader(json));
}
@Override
public void toBean(T target, String json, JsonReadOptions options) throws JsonIOException {
toBean(target, new StringReader(json), options);
}
@Override
public void toBean(T target, Reader jsonReader) throws JsonIOException {
toBean(target, createParser(jsonReader));
}
@Override
public void toBean(T target, Reader jsonReader, JsonReadOptions options) throws JsonIOException {
toBean(target, createParser(jsonReader), options);
}
@Override
public void toBean(T target, JsonParser parser) throws JsonIOException {
toBean(target, parser, null);
}
@SuppressWarnings("unchecked")
@Override
public void toBean(T target, JsonParser parser, JsonReadOptions options) throws JsonIOException {
BeanDescriptor desc = (BeanDescriptor) getDescriptor(target.getClass());
try {
desc.jsonRead(new ReadJson(desc, parser, options, determineObjectMapper(options), target != null), null, target);
} catch (IOException e) {
throw new JsonIOException(e);
}
}
@Override
public DJsonBeanReader createBeanReader(Class cls, JsonParser parser, JsonReadOptions options) throws JsonIOException {
BeanDescriptor desc = getDescriptor(cls);
return new DJsonBeanReader<>(desc, new ReadJson(desc, parser, options, determineObjectMapper(options), false));
}
@Override
public DJsonBeanReader createBeanReader(BeanType beanType, JsonParser parser, JsonReadOptions options) throws JsonIOException {
BeanDescriptor desc = (BeanDescriptor) beanType;
SpiJsonReader readJson = new ReadJson(desc, parser, options, determineObjectMapper(options), false);
return new DJsonBeanReader<>(desc, readJson);
}
@Override
public List toList(Class cls, String json) throws JsonIOException {
return toList(cls, new StringReader(json));
}
@Override
public List toList(Class cls, String json, JsonReadOptions options) throws JsonIOException {
return toList(cls, new StringReader(json), options);
}
@Override
public List toList(Class cls, Reader jsonReader) throws JsonIOException {
return toList(cls, createParser(jsonReader));
}
@Override
public List toList(Class cls, Reader jsonReader, JsonReadOptions options) throws JsonIOException {
return toList(cls, createParser(jsonReader), options);
}
@Override
public List toList(Class cls, JsonParser src) throws JsonIOException {
return toList(cls, src, null);
}
@Override
public List toList(Class cls, JsonParser src, JsonReadOptions options) throws JsonIOException {
BeanDescriptor desc = getDescriptor(cls);
SpiJsonReader readJson = new ReadJson(desc, src, options, determineObjectMapper(options), false);
try {
JsonToken currentToken = src.getCurrentToken();
if (currentToken != JsonToken.START_ARRAY) {
JsonToken event = src.nextToken();
if (event != JsonToken.START_ARRAY) {
throw new JsonParseException(src, "Expecting start_array event but got " + event);
}
}
List list = new ArrayList<>();
do {
// CHECKME: Should we update the list
T bean = desc.jsonRead(readJson, null, null);
if (bean == null) {
break;
} else {
list.add(bean);
}
} while (true);
return list;
} catch (IOException e) {
throw new JsonIOException(e);
}
}
@Override
public Object toObject(Type genericType, String json) throws JsonIOException {
return toObject(genericType, createParser(new StringReader(json)));
}
@Override
public Object toObject(Type genericType, Reader json) throws JsonIOException {
return toObject(genericType, createParser(json));
}
@Override
public Object toObject(Type genericType, JsonParser jsonParser) throws JsonIOException {
TypeInfo info = ParamTypeHelper.getTypeInfo(genericType);
ManyType manyType = info.getManyType();
switch (manyType) {
case NONE:
return toBean(info.getBeanType(), jsonParser);
case LIST:
return toList(info.getBeanType(), jsonParser);
default:
throw new JsonIOException("Type " + manyType + " not supported");
}
}
@Override
public void toJson(Object value, JsonGenerator generator) throws JsonIOException {
// generator passed in so don't close it
toJsonNoClose(value, generator, null);
}
@Override
public void toJson(Object value, JsonGenerator generator, FetchPath fetchPath) throws JsonIOException {
// generator passed in so don't close it
toJsonNoClose(value, generator, JsonWriteOptions.pathProperties(fetchPath));
}
@Override
public void toJson(Object o, JsonGenerator generator, JsonWriteOptions options) throws JsonIOException {
// generator passed in so don't close it
toJsonNoClose(o, generator, options);
}
@Override
public void toJson(Object o, Writer writer) throws JsonIOException {
// close generator
toJsonWithClose(o, createGenerator(writer), null);
}
@Override
public String toJson(Object value, FetchPath fetchPath) throws JsonIOException {
return toJson(value, JsonWriteOptions.pathProperties(fetchPath));
}
@Override
public void toJson(Object o, Writer writer, FetchPath fetchPath) throws JsonIOException {
// close generator
toJsonWithClose(o, createGenerator(writer), JsonWriteOptions.pathProperties(fetchPath));
}
@Override
public void toJson(Object o, Writer writer, JsonWriteOptions options) throws JsonIOException {
// close generator
toJsonWithClose(o, createGenerator(writer), options);
}
/**
* Write to the JsonGenerator and close when complete.
*/
private void toJsonWithClose(Object o, JsonGenerator generator, JsonWriteOptions options) throws JsonIOException {
try {
toJsonInternal(o, generator, options);
generator.close();
} catch (IOException e) {
throw new JsonIOException(e);
}
}
/**
* Write to the JsonGenerator and without closing it (as it was created externally).
*/
private void toJsonNoClose(Object o, JsonGenerator generator, JsonWriteOptions options) throws JsonIOException {
try {
toJsonInternal(o, generator, options);
} catch (IOException e) {
throw new JsonIOException(e);
}
}
@Override
public String toJsonPretty(Object value) throws JsonIOException {
return toJsonString(value, null, true);
}
@Override
public String toJson(Object o) throws JsonIOException {
return toJsonString(o, null, false);
}
@Override
public String toJson(Object o, JsonWriteOptions options) throws JsonIOException {
return toJsonString(o, options, false);
}
private String toJsonString(Object value, JsonWriteOptions options, boolean pretty) throws JsonIOException {
StringWriter writer = new StringWriter(500);
try (JsonGenerator gen = createGenerator(writer)) {
if (pretty) {
gen.setPrettyPrinter(PRETTY_PRINTER);
}
toJsonInternal(value, gen, options);
} catch (IOException e) {
throw new JsonIOException(e);
}
return writer.toString();
}
@SuppressWarnings("unchecked")
private void toJsonInternal(Object value, JsonGenerator gen, JsonWriteOptions options) throws IOException {
if (value == null) {
gen.writeNull();
} else if (value instanceof Number) {
gen.writeNumber(((Number) value).doubleValue());
} else if (value instanceof Boolean) {
gen.writeBoolean((Boolean) value);
} else if (value instanceof String) {
gen.writeString((String) value);
// } else if (o instanceof JsonElement) {
} else if (value instanceof Map, ?>) {
toJsonFromMap((Map
© 2015 - 2024 Weber Informatics LLC | Privacy Policy