You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by jo...@apache.org on 2019/02/04 15:59:06 UTC

[tinkerpop] branch TINKERPOP-2149 created (now e98a01f)

This is an automated email from the ASF dual-hosted git repository.

jorgebg pushed a change to branch TINKERPOP-2149
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git.


      at e98a01f  TINKERPOP-2149 Add fallback resolver to TypeSerializerRegistry

This branch includes the following new commits:

     new e98a01f  TINKERPOP-2149 Add fallback resolver to TypeSerializerRegistry

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[tinkerpop] 01/01: TINKERPOP-2149 Add fallback resolver to TypeSerializerRegistry

Posted by jo...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

jorgebg pushed a commit to branch TINKERPOP-2149
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit e98a01f1193383c2c51a4dd951e505d681db6106
Author: Jorge Bay Gondra <jo...@gmail.com>
AuthorDate: Mon Feb 4 16:59:02 2019 +0100

    TINKERPOP-2149 Add fallback resolver to TypeSerializerRegistry
---
 .../driver/ser/binary/TypeSerializerRegistry.java  | 44 ++++++++++++++++------
 .../ser/binary/TypeSerializerRegistryTest.java     | 38 +++++++++++++++++++
 .../ser/binary/types/sample/SamplePerson.java      |  2 +-
 3 files changed, 72 insertions(+), 12 deletions(-)

diff --git a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/TypeSerializerRegistry.java b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/TypeSerializerRegistry.java
index 89022b8..ee9f08d 100644
--- a/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/TypeSerializerRegistry.java
+++ b/gremlin-driver/src/main/java/org/apache/tinkerpop/gremlin/driver/ser/binary/TypeSerializerRegistry.java
@@ -82,6 +82,7 @@ import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Function;
 
 public class TypeSerializerRegistry {
 
@@ -164,6 +165,7 @@ public class TypeSerializerRegistry {
 
     public static class Builder {
         private final List<RegistryEntry> list = new LinkedList<>();
+        private Function<Class<?>, TypeSerializer<?>> fallbackResolver;
 
         /**
          * Adds a serializer for a built-in type.
@@ -214,10 +216,18 @@ public class TypeSerializerRegistry {
         }
 
         /**
+         * Provides a way to resolve the type serializer to use when there isn't any direct match.
+         */
+        public Builder withFallbackResolver(Function<Class<?>, TypeSerializer<?>> fallbackResolver) {
+            this.fallbackResolver = fallbackResolver;
+            return this;
+        }
+
+        /**
          * Creates a new {@link TypeSerializerRegistry} instance based on the serializers added.
          */
         public TypeSerializerRegistry create() {
-            return new TypeSerializerRegistry(list);
+            return new TypeSerializerRegistry(list, fallbackResolver);
         }
     }
 
@@ -256,6 +266,7 @@ public class TypeSerializerRegistry {
     private final Map<Class<?>, TypeSerializer<?>> serializersByInterface = new LinkedHashMap<>();
     private final Map<DataType, TypeSerializer<?>> serializersByDataType = new HashMap<>();
     private final Map<String, CustomTypeSerializer> serializersByCustomTypeName = new HashMap<>();
+    private Function<Class<?>, TypeSerializer<?>> fallbackResolver;
 
     /**
      * Stores serializers by class, where the class resolution involved a lookup or special conditions.
@@ -263,7 +274,8 @@ public class TypeSerializerRegistry {
      */
     private final ConcurrentHashMap<Class<?>, TypeSerializer<?>> serializersByImplementation = new ConcurrentHashMap<>();
 
-    private TypeSerializerRegistry(final Collection<RegistryEntry> entries) {
+    private TypeSerializerRegistry(final Collection<RegistryEntry> entries,
+                                   final Function<Class<?>, TypeSerializer<?>> fallbackResolver) {
         final Set<Class> providedTypes = new HashSet<>(entries.size());
 
         // Include user-provided entries first
@@ -274,6 +286,8 @@ public class TypeSerializerRegistry {
 
         // Followed by the defaults
         Arrays.stream(defaultEntries).filter(e -> !providedTypes.contains(e.type)).forEach(this::put);
+
+        this.fallbackResolver = fallbackResolver;
     }
 
     private void put(final RegistryEntry entry) {
@@ -316,15 +330,16 @@ public class TypeSerializerRegistry {
             serializer = serializersByImplementation.get(type);
         }
 
-        if (null == serializer && Enum.class.isAssignableFrom(type)) {
+        if (serializer != null) {
+            return (TypeSerializer) serializer;
+        }
+
+        // Use different lookup techniques and cache the lookup result when successful
+
+        if (Enum.class.isAssignableFrom(type)) {
             // maybe it's a enum - enums with bodies are weird in java, they are subclasses of themselves, so
             // Columns.values will be of type Column$2.
             serializer = serializers.get(type.getSuperclass());
-
-            // In case it matched, store the match
-            if (serializer != null) {
-                serializersByImplementation.put(type, serializer);
-            }
         }
 
         if (null == serializer) {
@@ -332,14 +347,21 @@ public class TypeSerializerRegistry {
             for (Map.Entry<Class<?>, TypeSerializer<?>> entry : serializersByInterface.entrySet()) {
                 if (entry.getKey().isAssignableFrom(type)) {
                     serializer = entry.getValue();
-                    // Store the type-to-interface match, to avoid looking it up in the future
-                    serializersByImplementation.put(type, serializer);
                     break;
                 }
             }
         }
 
-        return validateInstance(serializer, type.getTypeName());
+        if (null == serializer && fallbackResolver != null) {
+            serializer = fallbackResolver.apply(type);
+        }
+
+        validateInstance(serializer, type.getTypeName());
+
+        // Store the lookup match to avoid looking it up in the future
+        serializersByImplementation.put(type, serializer);
+
+        return (TypeSerializer<DT>) serializer;
     }
 
     public <DT> TypeSerializer<DT> getSerializer(final DataType dataType) throws SerializationException {
diff --git a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/TypeSerializerRegistryTest.java b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/TypeSerializerRegistryTest.java
index 40524c5..732abc0 100644
--- a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/TypeSerializerRegistryTest.java
+++ b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/TypeSerializerRegistryTest.java
@@ -21,12 +21,15 @@ package org.apache.tinkerpop.gremlin.driver.ser.binary;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.ByteBufAllocator;
 import org.apache.tinkerpop.gremlin.driver.ser.SerializationException;
+import org.apache.tinkerpop.gremlin.driver.ser.binary.types.sample.SamplePerson;
+import org.apache.tinkerpop.gremlin.driver.ser.binary.types.sample.SamplePersonSerializer;
 import org.apache.tinkerpop.gremlin.structure.Property;
 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 import org.junit.Test;
 
 import java.util.UUID;
 
+import static junit.framework.TestCase.assertEquals;
 import static junit.framework.TestCase.assertSame;
 
 public class TypeSerializerRegistryTest {
@@ -75,6 +78,41 @@ public class TypeSerializerRegistryTest {
         assertSame(expectedForProperty, registry.getSerializer(DataType.PROPERTY));
     }
 
+    @Test
+    public void shouldUseFallbackResolverWhenThereIsNoMatch() {
+        final int[] called = {0};
+        final TypeSerializerRegistry registry = TypeSerializerRegistry.build()
+                .withFallbackResolver(t -> {
+                    called[0]++;
+                    return null;
+                }).create();
+
+        String message = null;
+        try {
+            registry.getSerializer(SamplePerson.class);
+        } catch (SerializationException ex) {
+            message = ex.getMessage();
+        }
+
+        assertEquals("Serializer for type org.apache.tinkerpop.gremlin.driver.ser.binary.types.sample.SamplePerson not found", message);
+        assertEquals(1, called[0]);
+    }
+
+    @Test
+    public void shouldUseFallbackResolverReturnValue() throws SerializationException {
+        TypeSerializer expected = new SamplePersonSerializer();
+        final int[] called = {0};
+        final TypeSerializerRegistry registry = TypeSerializerRegistry.build()
+                .withFallbackResolver(t -> {
+                    called[0]++;
+                    return expected;
+                }).create();
+
+        TypeSerializer<SamplePerson> serializer = registry.getSerializer(SamplePerson.class);
+        assertEquals(1, called[0]);
+        assertSame(expected, serializer);
+    }
+
     private static class TestVertexPropertySerializer extends TestBaseTypeSerializer<VertexProperty> {
 
         @Override
diff --git a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/types/sample/SamplePerson.java b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/types/sample/SamplePerson.java
index 10d9bcb..fd4d05a 100644
--- a/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/types/sample/SamplePerson.java
+++ b/gremlin-driver/src/test/java/org/apache/tinkerpop/gremlin/driver/ser/binary/types/sample/SamplePerson.java
@@ -24,7 +24,7 @@ import java.util.Objects;
 /**
  * A sample custom data type containing few properties.
  */
-class SamplePerson {
+public class SamplePerson {
     private final String name;
     private final Date birthDate;