Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.quarkus.devui.deployment.jsonrpc.DevUIDatabindCodec Maven / Gradle / Ivy
package io.quarkus.devui.deployment.jsonrpc;
import java.io.Closeable;
import java.io.IOException;
import java.time.Instant;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import io.quarkus.devui.runtime.jsonrpc.json.JsonMapper;
import io.quarkus.devui.runtime.jsonrpc.json.JsonTypeAdapter;
import io.quarkus.vertx.runtime.jackson.ByteArrayDeserializer;
import io.quarkus.vertx.runtime.jackson.ByteArraySerializer;
import io.quarkus.vertx.runtime.jackson.InstantDeserializer;
import io.quarkus.vertx.runtime.jackson.InstantSerializer;
import io.vertx.core.json.DecodeException;
import io.vertx.core.json.EncodeException;
public class DevUIDatabindCodec implements JsonMapper {
private final ObjectMapper mapper;
private final ObjectMapper prettyMapper;
private final Function, ?> runtimeObjectDeserializer;
private final Function, ?> runtimeArrayDeserializer;
private DevUIDatabindCodec(ObjectMapper mapper,
Function, ?> runtimeObjectDeserializer,
Function, ?> runtimeArrayDeserializer) {
this.mapper = mapper;
prettyMapper = mapper.copy();
prettyMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
this.runtimeObjectDeserializer = runtimeObjectDeserializer;
this.runtimeArrayDeserializer = runtimeArrayDeserializer;
}
@SuppressWarnings("unchecked")
@Override
public T fromValue(Object json, Class clazz) {
T value = mapper.convertValue(json, clazz);
if (clazz == Object.class) {
value = (T) adapt(value);
}
return value;
}
@Override
public T fromString(String str, Class clazz) throws DecodeException {
return fromParser(createParser(str), clazz);
}
private JsonParser createParser(String str) {
try {
return mapper.getFactory().createParser(str);
} catch (IOException e) {
throw new DecodeException("Failed to decode:" + e.getMessage(), e);
}
}
@SuppressWarnings("unchecked")
private T fromParser(JsonParser parser, Class type) throws DecodeException {
T value;
JsonToken remaining;
try {
value = mapper.readValue(parser, type);
remaining = parser.nextToken();
} catch (Exception e) {
throw new DecodeException("Failed to decode:" + e.getMessage(), e);
} finally {
close(parser);
}
if (remaining != null) {
throw new DecodeException("Unexpected trailing token");
}
if (type == Object.class) {
value = (T) adapt(value);
}
return value;
}
@Override
public String toString(Object object, boolean pretty) throws EncodeException {
try {
ObjectMapper theMapper = pretty ? prettyMapper : mapper;
return theMapper.writeValueAsString(object);
} catch (Exception e) {
throw new EncodeException("Failed to encode as JSON: " + e.getMessage(), e);
}
}
private static void close(Closeable parser) {
try {
parser.close();
} catch (IOException ignore) {
}
}
private Object adapt(Object o) {
try {
if (o instanceof List) {
List> list = (List>) o;
return runtimeArrayDeserializer.apply(list);
} else if (o instanceof Map) {
@SuppressWarnings("unchecked")
Map map = (Map) o;
return runtimeObjectDeserializer.apply(map);
}
return o;
} catch (Exception e) {
throw new DecodeException("Failed to decode: " + e.getMessage());
}
}
public static final class Factory implements JsonMapper.Factory {
@Override
public JsonMapper create(JsonTypeAdapter, Map> jsonObjectAdapter,
JsonTypeAdapter, List>> jsonArrayAdapter, JsonTypeAdapter, String> bufferAdapter) {
// We want our own mapper, separate from the user-configured one.
ObjectMapper mapper = new ObjectMapper();
// Non-standard JSON but we allow C style comments in our JSON
mapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
SimpleModule module = new SimpleModule("vertx-module-common");
module.addSerializer(Instant.class, new InstantSerializer());
module.addDeserializer(Instant.class, new InstantDeserializer());
module.addSerializer(byte[].class, new ByteArraySerializer());
module.addDeserializer(byte[].class, new ByteArrayDeserializer());
mapper.registerModule(module);
SimpleModule runtimeModule = new SimpleModule("vertx-module-runtime");
addAdapterToObject(runtimeModule, jsonObjectAdapter);
addAdapterToObject(runtimeModule, jsonArrayAdapter);
addAdapterToString(runtimeModule, bufferAdapter);
mapper.registerModule(runtimeModule);
return new DevUIDatabindCodec(mapper, jsonObjectAdapter.deserializer, jsonArrayAdapter.deserializer);
}
private static void addAdapterToObject(SimpleModule module, JsonTypeAdapter adapter) {
module.addSerializer(adapter.type, new JsonSerializer<>() {
@Override
public void serialize(T value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
jgen.writeObject(adapter.serializer.apply(value));
}
});
}
private static void addAdapterToString(SimpleModule module, JsonTypeAdapter adapter) {
module.addSerializer(adapter.type, new JsonSerializer<>() {
@Override
public void serialize(T value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
jgen.writeString(adapter.serializer.apply(value));
}
});
module.addDeserializer(adapter.type, new JsonDeserializer() {
@Override
public T deserialize(JsonParser parser, DeserializationContext ctxt) throws IOException {
return adapter.deserializer.apply(parser.getText());
}
});
}
}
}