com.datastax.driver.dse.graph.GraphSON2GremlinDriverModule Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dse-java-driver-core Show documentation
Show all versions of dse-java-driver-core Show documentation
A driver for DataStax Enterprise (DSE)
and Apache Cassandra 1.2+ clusters that works exclusively with the
Cassandra Query Language version 3 (CQL3) and Cassandra's binary protocol,
supporting DSE-specific features such as geospatial types, DSE Graph and DSE authentication.
/*
* Copyright (C) 2012-2017 DataStax Inc.
*
* This software can be used solely with DataStax Enterprise. Please consult the license at
* http://www.datastax.com/terms/datastax-dse-driver-license-terms
*/
package com.datastax.driver.dse.graph;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
class GraphSON2GremlinDriverModule extends GraphSON2JacksonModule {
GraphSON2GremlinDriverModule() {
super("graph-graphson2gremlin");
addSerializer(Integer.class, new IntegerGraphSONSerializer());
addSerializer(Double.class, new DoubleGraphSONSerializer());
addDeserializer(Vertex.class, new VertexGraphSON2Deserializer());
addDeserializer(VertexProperty.class, new VertexPropertyGraphSON2Deserializer());
addDeserializer(Property.class, new PropertyGraphSON2Deserializer());
addDeserializer(Edge.class, new EdgeGraphSON2Deserializer());
addDeserializer(Path.class, new PathGraphSON2Deserializer());
}
@Override
public Map, String> getTypeDefinitions() {
// Override the TinkerPop classes' types.
final ImmutableMap.Builder, String> builder = ImmutableMap.builder();
builder.put(Integer.class, "Int32");
builder.put(Long.class, "Int64");
builder.put(Double.class, "Double");
builder.put(Float.class, "Float");
builder.put(Vertex.class, "Vertex");
builder.put(VertexProperty.class, "VertexProperty");
builder.put(Property.class, "Property");
builder.put(Edge.class, "Edge");
builder.put(Path.class, "Path");
builder.put(List.class, "Tree");
return builder.build();
}
@Override
public String getTypeNamespace() {
// Override the classes from the TinkerPop domain.
return "g";
}
final static class IntegerGraphSONSerializer extends StdScalarSerializer {
IntegerGraphSONSerializer() {
super(Integer.class);
}
@Override
public void serialize(final Integer integer, final JsonGenerator jsonGenerator,
final SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeNumber(((Integer) integer).intValue());
}
}
final static class DoubleGraphSONSerializer extends StdScalarSerializer {
DoubleGraphSONSerializer() {
super(Double.class);
}
@Override
public void serialize(final Double doubleValue, final JsonGenerator jsonGenerator,
final SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeNumber(doubleValue);
}
}
abstract static class ParentGremlinGraphSON2Deserializer extends StdDeserializer {
T parent;
protected ParentGremlinGraphSON2Deserializer(Class clazz) {
super(clazz);
}
@Override
public T deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
parent = newObject();
JsonParser contextualParser = new GremlinContextualJsonParser(jsonParser, parent);
contextualParser.nextToken();
// This will automatically parse all typed stuff.
@SuppressWarnings("unchecked")
final Map mapData = deserializationContext.readValue(contextualParser, Map.class);
return initializeObject(mapData, parent);
}
abstract T newObject();
abstract T initializeObject(Map data, T objectToInitialize);
}
abstract static class ParentChildGremlinGraphSON2Deserializer extends ParentGremlinGraphSON2Deserializer {
Element parent;
protected ParentChildGremlinGraphSON2Deserializer(Class clazz) {
super(clazz);
}
@Override
public T deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
parent = ContextualDelegateParser.class.isAssignableFrom(jsonParser.getClass())
? (Element) ((ContextualDelegateParser) jsonParser).getContext().get(0)
: null;
T currentParent = newObject();
JsonParser contextualParser = new GremlinContextualJsonParser(jsonParser, currentParent);
contextualParser.nextToken();
// This will automatically parse all typed stuff.
@SuppressWarnings("unchecked")
final Map mapData = deserializationContext.readValue(contextualParser, Map.class);
return initializeObject(mapData, currentParent);
}
}
abstract static class ChildGremlinGraphSON2Deserializer extends StdDeserializer {
protected Element parent;
protected ChildGremlinGraphSON2Deserializer(Class clazz) {
super(clazz);
}
@Override
public T deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
parent = ContextualDelegateParser.class.isAssignableFrom(jsonParser.getClass())
? (Element) ((ContextualDelegateParser) jsonParser).getContext().get(0)
: null;
jsonParser.nextToken();
// This will automatically parse all typed stuff.
@SuppressWarnings("unchecked")
final Map mapData = deserializationContext.readValue(jsonParser, Map.class);
return createObject(mapData);
}
abstract T createObject(Map data);
}
final static class VertexGraphSON2Deserializer extends ParentGremlinGraphSON2Deserializer {
VertexGraphSON2Deserializer() {
super(Vertex.class);
}
@Override
Vertex newObject() {
return new DefaultVertex();
}
@SuppressWarnings("unchecked")
@Override
public Vertex initializeObject(final Map map, Vertex element) {
DefaultVertex vertex = (DefaultVertex) element;
vertex.id = new ObjectGraphNode(map.get("id"));
vertex.label = map.get("label").toString();
if (map.containsKey("properties")) {
ImmutableMultimap.Builder builder = ImmutableMultimap.builder();
for (Map.Entry> propertyEntry : ((Map>) map.get("properties")).entrySet()) {
for (VertexProperty vp : propertyEntry.getValue()) {
builder.put(propertyEntry.getKey(), new ObjectGraphNode(vp));
}
}
vertex.properties = builder.build();
}
return vertex;
}
}
final static class VertexPropertyGraphSON2Deserializer extends ParentChildGremlinGraphSON2Deserializer {
VertexPropertyGraphSON2Deserializer() {
super(VertexProperty.class);
}
@Override
VertexProperty newObject() {
return new DefaultVertexProperty();
}
@SuppressWarnings("unchecked")
@Override
public VertexProperty initializeObject(Map map, VertexProperty element) {
DefaultVertexProperty vp = (DefaultVertexProperty) element;
vp.id = new ObjectGraphNode(map.get("id"));
// DSE Graph includes VP's labels by default, but in theory the field in
// the protocol in TinkerPop is optional, so we might as well be prepared.
if (map.containsKey("label")) {
vp.label = map.get("label").toString();
}
vp.value = new ObjectGraphNode(map.get("value"));
if (map.containsKey("properties")) {
ImmutableMultimap.Builder builder = ImmutableMultimap.builder();
for (Map.Entry propertyEntry : ((Map) map.get("properties")).entrySet()) {
DefaultProperty prop = new DefaultProperty();
prop.name = propertyEntry.getKey();
prop.value = new ObjectGraphNode(propertyEntry.getValue());
prop.parent = vp;
builder.putAll(propertyEntry.getKey(), new ObjectGraphNode(prop));
}
vp.properties = builder.build();
}
vp.parent = (Vertex)parent;
return vp;
}
}
final static class PropertyGraphSON2Deserializer extends ChildGremlinGraphSON2Deserializer {
PropertyGraphSON2Deserializer() {
super(Property.class);
}
@Override
public Property createObject(Map map) {
DefaultProperty prop = new DefaultProperty();
prop.name = map.get("key").toString();
prop.value = new ObjectGraphNode(map.get("value"));
prop.parent = parent;
return prop;
}
}
final static class EdgeGraphSON2Deserializer extends ParentGremlinGraphSON2Deserializer {
EdgeGraphSON2Deserializer() {
super(Edge.class);
}
@Override
Edge newObject() {
return new DefaultEdge();
}
@SuppressWarnings("unchecked")
@Override
public Edge initializeObject(Map map, Edge element) {
DefaultEdge edge = (DefaultEdge) element;
edge.id = new ObjectGraphNode(map.get("id"));
edge.label = map.get("label").toString();
if (map.containsKey("properties")) {
ImmutableMultimap.Builder builder = ImmutableMultimap.builder();
for (Map.Entry propertyEntry : ((Map) map.get("properties")).entrySet()) {
builder.putAll(propertyEntry.getKey(), new ObjectGraphNode(propertyEntry.getValue()));
}
edge.properties = builder.build();
}
edge.inV = new ObjectGraphNode(map.get("inV"));
// inVLabel might become redundant, we want to make sure we're resilient there.
if (map.containsKey("inVLabel"))
edge.inVLabel = map.get("inVLabel").toString();
edge.outV = new ObjectGraphNode(map.get("outV"));
// outVLabel might become redundant, we want to make sure we're resilient there.
if (map.containsKey("outVLabel"))
edge.outVLabel = map.get("outVLabel").toString();
return edge;
}
}
final static class PathGraphSON2Deserializer extends AbstractObjectDeserializer {
PathGraphSON2Deserializer() {
super(Path.class);
}
@Override
public Path createObject(Map map) {
DefaultPath path = new DefaultPath();
path.labels = new ArrayList>();
@SuppressWarnings("unchecked")
List> labels = (List>) map.get("labels");
for (List labelsSet : labels) {
path.labels.add(new HashSet(labelsSet));
}
path.objects = new ArrayList();
@SuppressWarnings("unchecked")
List