package com.datastax.dse.driver.internal.core.graph;
import com.datastax.dse.driver.api.core.data.geometry.Geometry;
import com.datastax.dse.driver.api.core.data.geometry.LineString;
import com.datastax.dse.driver.api.core.data.geometry.Point;
import com.datastax.dse.driver.api.core.data.geometry.Polygon;
import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList;
import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap;
import com.datastax.oss.driver.shaded.guava.common.net.InetAddresses;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.util.List;
import java.util.Map;
import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator;
import org.apache.tinkerpop.shaded.jackson.core.JsonParseException;
import org.apache.tinkerpop.shaded.jackson.core.JsonParser;
import org.apache.tinkerpop.shaded.jackson.core.Version;
import org.apache.tinkerpop.shaded.jackson.databind.DeserializationContext;
import org.apache.tinkerpop.shaded.jackson.databind.JsonDeserializer;
import org.apache.tinkerpop.shaded.jackson.databind.JsonSerializer;
import org.apache.tinkerpop.shaded.jackson.databind.SerializerProvider;
import org.apache.tinkerpop.shaded.jackson.databind.deser.std.StdDeserializer;
import org.apache.tinkerpop.shaded.jackson.databind.module.SimpleModule;
import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer;
public class GraphSON1SerdeTP {
static class DefaultInetAddressDeserializer<T extends InetAddress> extends StdDeserializer<T> {
private static final long serialVersionUID = 1L;
private final Class<T> inetClass;
DefaultInetAddressDeserializer(Class<T> inetClass) {
super(inetClass);
this.inetClass = inetClass;
}
@Override
public T deserialize(JsonParser parser, DeserializationContext ctx) throws IOException {
String ip = parser.readValueAs(String.class);
try {
InetAddress inet = InetAddresses.forString(ip);
return inetClass.cast(inet);
} catch (ClassCastException e) {
throw new JsonParseException(
parser,
String.format("Inet address cannot be cast to %s: %s", inetClass.getSimpleName(), ip),
e);
} catch (IllegalArgumentException e) {
throw new JsonParseException(parser, String.format("Expected inet address, got %s", ip), e);
}
}
}
static class DefaultGeometryDeserializer<T extends Geometry> extends StdDeserializer<T> {
private static final long serialVersionUID = 1L;
private final Class<T> geometryClass;
DefaultGeometryDeserializer(Class<T> geometryClass) {
super(geometryClass);
this.geometryClass = geometryClass;
}
@Override
public T deserialize(JsonParser parser, DeserializationContext ctx) throws IOException {
String wkt = parser.readValueAs(String.class);
Geometry geometry;
if (wkt.startsWith("POINT")) geometry = Point.fromWellKnownText(wkt);
else if (wkt.startsWith("LINESTRING")) geometry = LineString.fromWellKnownText(wkt);
else if (wkt.startsWith("POLYGON")) geometry = Polygon.fromWellKnownText(wkt);
else throw new JsonParseException(parser, "Unknown geometry type: " + wkt);
return geometryClass.cast(geometry);
}
}
abstract static class AbstractJavaTimeSerializer<T> extends StdSerializer<T> {
private static final long serialVersionUID = 1L;
AbstractJavaTimeSerializer(final Class<T> clazz) {
super(clazz);
}
@Override
public void serialize(
final T value, final JsonGenerator gen, final SerializerProvider serializerProvider)
throws IOException {
gen.writeString(value.toString());
}
}
abstract static class AbstractJavaTimeJacksonDeserializer<T> extends StdDeserializer<T> {
private static final long serialVersionUID = 1L;
AbstractJavaTimeJacksonDeserializer(final Class<T> clazz) {
super(clazz);
}
abstract T parse(final String val);
@Override
public T deserialize(
final JsonParser jsonParser, final DeserializationContext deserializationContext)
throws IOException {
return parse(jsonParser.getText());
}
}
static final class DurationJacksonSerializer
extends AbstractJavaTimeSerializer<java.time.Duration> {
private static final long serialVersionUID = 1L;
DurationJacksonSerializer() {
super(java.time.Duration.class);
}
}
static final class DurationJacksonDeserializer
extends AbstractJavaTimeJacksonDeserializer<java.time.Duration> {
private static final long serialVersionUID = 1L;
DurationJacksonDeserializer() {
super(java.time.Duration.class);
}
@Override
public java.time.Duration parse(final String val) {
return java.time.Duration.parse(val);
}
}
static final class InstantJacksonSerializer
extends AbstractJavaTimeSerializer<java.time.Instant> {
private static final long serialVersionUID = 1L;
InstantJacksonSerializer() {
super(java.time.Instant.class);
}
}
static final class InstantJacksonDeserializer
extends AbstractJavaTimeJacksonDeserializer<java.time.Instant> {
private static final long serialVersionUID = 1L;
InstantJacksonDeserializer() {
super(java.time.Instant.class);
}
@Override
public java.time.Instant parse(final String val) {
return java.time.Instant.parse(val);
}
}
static final class LocalDateJacksonSerializer
extends AbstractJavaTimeSerializer<java.time.LocalDate> {
private static final long serialVersionUID = 1L;
LocalDateJacksonSerializer() {
super(java.time.LocalDate.class);
}
}
static final class LocalDateJacksonDeserializer
extends AbstractJavaTimeJacksonDeserializer<java.time.LocalDate> {
private static final long serialVersionUID = 1L;
LocalDateJacksonDeserializer() {
super(java.time.LocalDate.class);
}
@Override
public java.time.LocalDate parse(final String val) {
return java.time.LocalDate.parse(val);
}
}
static final class LocalTimeJacksonSerializer
extends AbstractJavaTimeSerializer<java.time.LocalTime> {
private static final long serialVersionUID = 1L;
LocalTimeJacksonSerializer() {
super(java.time.LocalTime.class);
}
}
static final class LocalTimeJacksonDeserializer
extends AbstractJavaTimeJacksonDeserializer<java.time.LocalTime> {
private static final long serialVersionUID = 1L;
LocalTimeJacksonDeserializer() {
super(java.time.LocalTime.class);
}
@Override
public java.time.LocalTime parse(final String val) {
return java.time.LocalTime.parse(val);
}
}
static class DefaultGraphNodeSerializer extends StdSerializer<LegacyGraphNode> {
private static final long serialVersionUID = 1L;
DefaultGraphNodeSerializer() {
super(LegacyGraphNode.class);
}
@Override
public void serialize(
LegacyGraphNode value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
throws IOException {
jsonGenerator.writeTree(value.getDelegate());
}
}
static class DefaultGeometrySerializer extends StdSerializer<Geometry> {
private static final long serialVersionUID = 1L;
DefaultGeometrySerializer() {
super(Geometry.class);
}
@Override
public void serialize(
Geometry value, JsonGenerator jsonGenerator, SerializerProvider serializers)
throws IOException {
jsonGenerator.writeString(value.asWellKnownText());
}
}
static class GraphSON1DefaultModule extends SimpleModule {
private static final long serialVersionUID = 1L;
GraphSON1DefaultModule(String name, Version version) {
super(name, version, createDeserializers(), createSerializers());
}
private static Map<Class<?>, JsonDeserializer<?>> createDeserializers() {
return ImmutableMap.<Class<?>, JsonDeserializer<?>>builder()
.put(InetAddress.class, new DefaultInetAddressDeserializer<>(InetAddress.class))
.put(Inet4Address.class, new DefaultInetAddressDeserializer<>(Inet4Address.class))
.put(Inet6Address.class, new DefaultInetAddressDeserializer<>(Inet6Address.class))
.put(Geometry.class, new DefaultGeometryDeserializer<>(Geometry.class))
.put(Point.class, new DefaultGeometryDeserializer<>(Point.class))
.put(LineString.class, new DefaultGeometryDeserializer<>(LineString.class))
.put(Polygon.class, new DefaultGeometryDeserializer<>(Polygon.class))
.build();
}
private static List<JsonSerializer<?>> createSerializers() {
return ImmutableList.<JsonSerializer<?>>builder()
.add(new DefaultGraphNodeSerializer())
.add(new DefaultGeometrySerializer())
.build();
}
}
static class GraphSON1JavaTimeModule extends SimpleModule {
private static final long serialVersionUID = 1L;
GraphSON1JavaTimeModule(String name, Version version) {
super(name, version, createDeserializers(), createSerializers());
}
private static Map<Class<?>, JsonDeserializer<?>> createDeserializers() {
return ImmutableMap.<Class<?>, JsonDeserializer<?>>builder()
.put(java.time.Duration.class, new DurationJacksonDeserializer())
.put(java.time.Instant.class, new InstantJacksonDeserializer())
.put(java.time.LocalDate.class, new LocalDateJacksonDeserializer())
.put(java.time.LocalTime.class, new LocalTimeJacksonDeserializer())
.build();
}
private static List<JsonSerializer<?>> createSerializers() {
return ImmutableList.<JsonSerializer<?>>builder()
.add(new DurationJacksonSerializer())
.add(new InstantJacksonSerializer())
.add(new LocalDateJacksonSerializer())
.add(new LocalTimeJacksonSerializer())
.build();
}
}
}