TINKERPOP-1565 Added a few GraphSON 3.0 classes
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/7ca3a298 Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/7ca3a298 Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/7ca3a298 Branch: refs/heads/TINKERPOP-1612 Commit: 7ca3a29826bbafca1733fd34f138b8b8d4252210 Parents: a3515cf Author: Stephen Mallette <sp...@genoprime.com> Authored: Wed Jan 18 12:53:22 2017 -0500 Committer: Stephen Mallette <sp...@genoprime.com> Committed: Thu Jan 19 15:15:33 2017 -0500 ---------------------------------------------------------------------- .../structure/io/graphson/GraphSONModule.java | 6 +- .../io/graphson/GraphSONXModuleV3d0.java | 142 ++++++++ .../io/graphson/JavaTimeSerializersV3d0.java | 323 +++++++++++++++++++ .../io/graphson/JavaUtilSerializersV3d0.java | 85 +++++ 4 files changed, 553 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7ca3a298/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java index dceae6b..f4acf12 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java @@ -200,7 +200,7 @@ abstract class GraphSONModule extends TinkerPopJacksonModule { addSerializer(Tree.class, new GraphSONSerializersV3d0.TreeJacksonSerializer()); // java.util - addSerializer(Map.Entry.class, new JavaUtilSerializersV2d0.MapEntryJacksonSerializer()); + addSerializer(Map.Entry.class, new JavaUtilSerializersV3d0.MapEntryJacksonSerializer()); // need to explicitly add serializers for those types because Jackson doesn't do it at all. addSerializer(Integer.class, new GraphSONSerializersV3d0.IntegerGraphSONSerializer()); @@ -238,8 +238,8 @@ abstract class GraphSONModule extends TinkerPopJacksonModule { addDeserializer(Tree.class, new GraphSONSerializersV3d0.TreeJacksonDeserializer()); // numbers - addDeserializer(Integer.class, new GraphSONSerializersV2d0.IntegerJackonsDeserializer()); - addDeserializer(Double.class, new GraphSONSerializersV2d0.DoubleJackonsDeserializer()); + addDeserializer(Integer.class, new GraphSONSerializersV3d0.IntegerJackonsDeserializer()); + addDeserializer(Double.class, new GraphSONSerializersV3d0.DoubleJackonsDeserializer()); // traversal addDeserializer(Bytecode.class, new GraphSONTraversalSerializersV2d0.BytecodeJacksonDeserializer()); http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7ca3a298/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONXModuleV3d0.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONXModuleV3d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONXModuleV3d0.java new file mode 100644 index 0000000..777c6c4 --- /dev/null +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONXModuleV3d0.java @@ -0,0 +1,142 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tinkerpop.gremlin.structure.io.graphson; + +/** + * @author Stephen Mallette (http://stephen.genoprime.com) + */ + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.net.InetAddress; +import java.nio.ByteBuffer; +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.MonthDay; +import java.time.OffsetDateTime; +import java.time.OffsetTime; +import java.time.Period; +import java.time.Year; +import java.time.YearMonth; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Version 3.0 of GraphSON extensions. + */ +public final class GraphSONXModuleV3d0 extends GraphSONModule { + + private static final Map<Class, String> TYPE_DEFINITIONS = Collections.unmodifiableMap( + new LinkedHashMap<Class, String>() {{ + put(ByteBuffer.class, "ByteBuffer"); + put(Short.class, "Int16"); + put(BigInteger.class, "BigInteger"); + put(BigDecimal.class, "BigDecimal"); + put(Byte.class, "Byte"); + put(Character.class, "Char"); + put(InetAddress.class, "InetAddress"); + + // Time serializers/deserializers + put(Duration.class, "Duration"); + put(Instant.class, "Instant"); + put(LocalDate.class, "LocalDate"); + put(LocalDateTime.class, "LocalDateTime"); + put(LocalTime.class, "LocalTime"); + put(MonthDay.class, "MonthDay"); + put(OffsetDateTime.class, "OffsetDateTime"); + put(OffsetTime.class, "OffsetTime"); + put(Period.class, "Period"); + put(Year.class, "Year"); + put(YearMonth.class, "YearMonth"); + put(ZonedDateTime.class, "ZonedDateTime"); + put(ZoneOffset.class, "ZoneOffset"); + }}); + + /** + * Constructs a new object. + */ + protected GraphSONXModuleV3d0(final boolean normalize) { + super("graphsonx-3.0"); + + /////////////////////// SERIALIZERS //////////////////////////// + + // java.time + addSerializer(Duration.class, new JavaTimeSerializersV3d0.DurationJacksonSerializer()); + addSerializer(Instant.class, new JavaTimeSerializersV3d0.InstantJacksonSerializer()); + addSerializer(LocalDate.class, new JavaTimeSerializersV3d0.LocalDateJacksonSerializer()); + addSerializer(LocalDateTime.class, new JavaTimeSerializersV3d0.LocalDateTimeJacksonSerializer()); + addSerializer(LocalTime.class, new JavaTimeSerializersV3d0.LocalTimeJacksonSerializer()); + addSerializer(MonthDay.class, new JavaTimeSerializersV3d0.MonthDayJacksonSerializer()); + addSerializer(OffsetDateTime.class, new JavaTimeSerializersV3d0.OffsetDateTimeJacksonSerializer()); + addSerializer(OffsetTime.class, new JavaTimeSerializersV3d0.OffsetTimeJacksonSerializer()); + addSerializer(Period.class, new JavaTimeSerializersV3d0.PeriodJacksonSerializer()); + addSerializer(Year.class, new JavaTimeSerializersV3d0.YearJacksonSerializer()); + addSerializer(YearMonth.class, new JavaTimeSerializersV3d0.YearMonthJacksonSerializer()); + addSerializer(ZonedDateTime.class, new JavaTimeSerializersV3d0.ZonedDateTimeJacksonSerializer()); + addSerializer(ZoneOffset.class, new JavaTimeSerializersV3d0.ZoneOffsetJacksonSerializer()); + + /////////////////////// DESERIALIZERS //////////////////////////// + + // java.time + addDeserializer(Duration.class, new JavaTimeSerializersV3d0.DurationJacksonDeserializer()); + addDeserializer(Instant.class, new JavaTimeSerializersV3d0.InstantJacksonDeserializer()); + addDeserializer(LocalDate.class, new JavaTimeSerializersV3d0.LocalDateJacksonDeserializer()); + addDeserializer(LocalDateTime.class, new JavaTimeSerializersV3d0.LocalDateTimeJacksonDeserializer()); + addDeserializer(LocalTime.class, new JavaTimeSerializersV3d0.LocalTimeJacksonDeserializer()); + addDeserializer(MonthDay.class, new JavaTimeSerializersV3d0.MonthDayJacksonDeserializer()); + addDeserializer(OffsetDateTime.class, new JavaTimeSerializersV3d0.OffsetDateTimeJacksonDeserializer()); + addDeserializer(OffsetTime.class, new JavaTimeSerializersV3d0.OffsetTimeJacksonDeserializer()); + addDeserializer(Period.class, new JavaTimeSerializersV3d0.PeriodJacksonDeserializer()); + addDeserializer(Year.class, new JavaTimeSerializersV3d0.YearJacksonDeserializer()); + addDeserializer(YearMonth.class, new JavaTimeSerializersV3d0.YearMonthJacksonDeserializer()); + addDeserializer(ZonedDateTime.class, new JavaTimeSerializersV3d0.ZonedDateTimeJacksonDeserializer()); + addDeserializer(ZoneOffset.class, new JavaTimeSerializersV3d0.ZoneOffsetJacksonDeserializer()); + } + + public static Builder build() { + return new Builder(); + } + + @Override + public Map<Class, String> getTypeDefinitions() { + return TYPE_DEFINITIONS; + } + + @Override + public String getTypeNamespace() { + return GraphSONTokens.GREMLINX_TYPE_NAMESPACE; + } + + public static final class Builder implements GraphSONModuleBuilder { + + private Builder() { + } + + @Override + public GraphSONModule create(final boolean normalize) { + return new GraphSONXModuleV3d0(normalize); + } + } +} http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7ca3a298/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV3d0.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV3d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV3d0.java new file mode 100644 index 0000000..1cb75e0 --- /dev/null +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaTimeSerializersV3d0.java @@ -0,0 +1,323 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tinkerpop.gremlin.structure.io.graphson; + +import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator; +import org.apache.tinkerpop.shaded.jackson.core.JsonParser; +import org.apache.tinkerpop.shaded.jackson.databind.DeserializationContext; +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.jsontype.TypeSerializer; +import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer; + +import java.io.IOException; +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.MonthDay; +import java.time.OffsetDateTime; +import java.time.OffsetTime; +import java.time.Period; +import java.time.Year; +import java.time.YearMonth; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; + +/** + * GraphSON serializers for classes in {@code java.time.*} for the version 3.0 of GraphSON. + */ +final class JavaTimeSerializersV3d0 { + + private JavaTimeSerializersV3d0() {} + + /** + * Base class for serializing the {@code java.time.*} to ISO-8061 formats. + */ + static abstract class AbstractJavaTimeSerializer<T> extends StdSerializer<T> { + + public 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()); + } + + @Override + public void serializeWithType(final T value, final JsonGenerator gen, + final SerializerProvider serializers, final TypeSerializer typeSer) throws IOException { + typeSer.writeTypePrefixForScalar(value, gen); + gen.writeString(value.toString()); + typeSer.writeTypeSuffixForScalar(value, gen); + } + } + /** + * Base class for serializing the {@code java.time.*} from ISO-8061 formats. + */ + abstract static class AbstractJavaTimeJacksonDeserializer<T> extends StdDeserializer<T> { + public AbstractJavaTimeJacksonDeserializer(final Class<T> clazz) { + super(clazz); + } + + public abstract T parse(final String val); + + @Override + public T deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException { + return parse(jsonParser.getText()); + } + } + + final static class DurationJacksonSerializer extends AbstractJavaTimeSerializer<Duration> { + + public DurationJacksonSerializer() { + super(Duration.class); + } + } + + final static class DurationJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<Duration> { + public DurationJacksonDeserializer() { + super(Duration.class); + } + + @Override + public Duration parse(final String val) { + return Duration.parse(val); + } + } + + final static class InstantJacksonSerializer extends AbstractJavaTimeSerializer<Instant> { + + public InstantJacksonSerializer() { + super(Instant.class); + } + } + + final static class InstantJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<Instant> { + public InstantJacksonDeserializer() { + super(Instant.class); + } + + @Override + public Instant parse(final String val) { + return Instant.parse(val); + } + } + + final static class LocalDateJacksonSerializer extends AbstractJavaTimeSerializer<LocalDate> { + + public LocalDateJacksonSerializer() { + super(LocalDate.class); + } + } + + final static class LocalDateJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<LocalDate> { + public LocalDateJacksonDeserializer() { + super(LocalDate.class); + } + + @Override + public LocalDate parse(final String val) { + return LocalDate.parse(val); + } + } + + final static class LocalDateTimeJacksonSerializer extends AbstractJavaTimeSerializer<LocalDateTime> { + + public LocalDateTimeJacksonSerializer() { + super(LocalDateTime.class); + } + } + + final static class LocalDateTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<LocalDateTime> { + public LocalDateTimeJacksonDeserializer() { + super(LocalDateTime.class); + } + + @Override + public LocalDateTime parse(final String val) { + return LocalDateTime.parse(val); + } + } + + final static class LocalTimeJacksonSerializer extends AbstractJavaTimeSerializer<LocalTime> { + + public LocalTimeJacksonSerializer() { + super(LocalTime.class); + } + } + + final static class LocalTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<LocalTime> { + public LocalTimeJacksonDeserializer() { + super(LocalTime.class); + } + + @Override + public LocalTime parse(final String val) { + return LocalTime.parse(val); + } + } + + final static class MonthDayJacksonSerializer extends AbstractJavaTimeSerializer<MonthDay> { + + public MonthDayJacksonSerializer() { + super(MonthDay.class); + } + } + + final static class MonthDayJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<MonthDay> { + public MonthDayJacksonDeserializer() { + super(MonthDay.class); + } + + @Override + public MonthDay parse(final String val) { + return MonthDay.parse(val); + } + } + + final static class OffsetDateTimeJacksonSerializer extends AbstractJavaTimeSerializer<OffsetDateTime> { + + public OffsetDateTimeJacksonSerializer() { + super(OffsetDateTime.class); + } + } + + final static class OffsetDateTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<OffsetDateTime> { + public OffsetDateTimeJacksonDeserializer() { + super(OffsetDateTime.class); + } + + @Override + public OffsetDateTime parse(final String val) { + return OffsetDateTime.parse(val); + } + } + + final static class OffsetTimeJacksonSerializer extends AbstractJavaTimeSerializer<OffsetTime> { + + public OffsetTimeJacksonSerializer() { + super(OffsetTime.class); + } + } + + final static class OffsetTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<OffsetTime> { + public OffsetTimeJacksonDeserializer() { + super(OffsetTime.class); + } + + @Override + public OffsetTime parse(final String val) { + return OffsetTime.parse(val); + } + } + + final static class PeriodJacksonSerializer extends AbstractJavaTimeSerializer<Period> { + + public PeriodJacksonSerializer() { + super(Period.class); + } + } + + final static class PeriodJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<Period> { + public PeriodJacksonDeserializer() { + super(Period.class); + } + + @Override + public Period parse(final String val) { + return Period.parse(val); + } + } + + final static class YearJacksonSerializer extends AbstractJavaTimeSerializer<Year> { + + public YearJacksonSerializer() { + super(Year.class); + } + } + + final static class YearJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<Year> { + public YearJacksonDeserializer() { + super(Year.class); + } + + @Override + public Year parse(final String val) { + return Year.parse(val); + } + } + + final static class YearMonthJacksonSerializer extends AbstractJavaTimeSerializer<YearMonth> { + + public YearMonthJacksonSerializer() { + super(YearMonth.class); + } + } + + final static class YearMonthJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<YearMonth> { + public YearMonthJacksonDeserializer() { + super(YearMonth.class); + } + + @Override + public YearMonth parse(final String val) { + return YearMonth.parse(val); + } + } + + final static class ZonedDateTimeJacksonSerializer extends AbstractJavaTimeSerializer<ZonedDateTime> { + + public ZonedDateTimeJacksonSerializer() { + super(ZonedDateTime.class); + } + } + + final static class ZonedDateTimeJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<ZonedDateTime> { + public ZonedDateTimeJacksonDeserializer() { + super(ZonedDateTime.class); + } + + @Override + public ZonedDateTime parse(final String val) { + return ZonedDateTime.parse(val); + } + } + + final static class ZoneOffsetJacksonSerializer extends AbstractJavaTimeSerializer<ZoneOffset> { + + public ZoneOffsetJacksonSerializer() { + super(ZoneOffset.class); + } + } + + final static class ZoneOffsetJacksonDeserializer extends AbstractJavaTimeJacksonDeserializer<ZoneOffset> { + public ZoneOffsetJacksonDeserializer() { + super(ZoneOffset.class); + } + + @Override + public ZoneOffset parse(final String val) { + return ZoneOffset.of(val); + } + } +} http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7ca3a298/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializersV3d0.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializersV3d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializersV3d0.java new file mode 100644 index 0000000..816a3f7 --- /dev/null +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/JavaUtilSerializersV3d0.java @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tinkerpop.gremlin.structure.io.graphson; + +import org.apache.tinkerpop.gremlin.structure.Element; +import org.apache.tinkerpop.shaded.jackson.core.JsonGenerator; +import org.apache.tinkerpop.shaded.jackson.databind.SerializationFeature; +import org.apache.tinkerpop.shaded.jackson.databind.SerializerProvider; +import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer; +import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer; + +import java.io.IOException; +import java.util.Date; +import java.util.Map; + +/** + * GraphSON serializers for classes in {@code java.util.*} for the version 3.0 of GraphSON. + */ +final class JavaUtilSerializersV3d0 { + + private JavaUtilSerializersV3d0() {} + + final static class MapEntryJacksonSerializer extends StdSerializer<Map.Entry> { + + public MapEntryJacksonSerializer() { + super(Map.Entry.class); + } + + @Override + public void serialize(final Map.Entry entry, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider) + throws IOException { + jsonGenerator.writeStartObject(); + ser(entry, jsonGenerator, serializerProvider); + jsonGenerator.writeEndObject(); + } + + @Override + public void serializeWithType(final Map.Entry entry, final JsonGenerator jsonGenerator, + final SerializerProvider serializerProvider, final TypeSerializer typeSerializer) throws IOException { + typeSerializer.writeTypePrefixForObject(entry, jsonGenerator); + ser(entry, jsonGenerator, serializerProvider); + typeSerializer.writeTypeSuffixForObject(entry, jsonGenerator); + } + + private static void ser(final Map.Entry entry, final JsonGenerator jsonGenerator, + final SerializerProvider serializerProvider) throws IOException { + // this treatment of keys is consistent with the current GraphSONKeySerializer which extends the + // StdKeySerializer + final Object key = entry.getKey(); + final Class cls = key.getClass(); + String k; + if (cls == String.class) + k = (String) key; + else if (Element.class.isAssignableFrom(cls)) + k = ((Element) key).id().toString(); + else if(Date.class.isAssignableFrom(cls)) { + if (serializerProvider.isEnabled(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS)) + k = String.valueOf(((Date) key).getTime()); + else + k = serializerProvider.getConfig().getDateFormat().format((Date) key); + } else if(cls == Class.class) + k = ((Class) key).getName(); + else + k = key.toString(); + + serializerProvider.defaultSerializeField(k, entry.getValue(), jsonGenerator); + } + } +}