You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2015/05/01 20:49:14 UTC

incubator-tinkerpop git commit: Changed IoRegistry to an interface that vendors implement.

Repository: incubator-tinkerpop
Updated Branches:
  refs/heads/master a7a84e407 -> 8d818fb04


Changed IoRegistry to an interface that vendors implement.

IoRegistry has an accompanying AbstractIoRegistry that contains the methods previously part of the IoRegistry class.  We thus keep the conveience of those methods for implementers.  Update docs based on this change.


Project: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/commit/8d818fb0
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/tree/8d818fb0
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/diff/8d818fb0

Branch: refs/heads/master
Commit: 8d818fb04493a50e9163025606457a0f108553c5
Parents: a7a84e4
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Fri May 1 14:48:04 2015 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Fri May 1 14:48:04 2015 -0400

----------------------------------------------------------------------
 docs/src/implementations.asciidoc               | 15 ++--
 .../structure/io/AbstractIoRegistry.java        | 79 ++++++++++++++++++++
 .../gremlin/structure/io/IoRegistry.java        | 49 ++++--------
 .../structure/io/graphson/GraphSONMapper.java   |  7 +-
 .../gremlin/structure/io/gryo/GryoMapper.java   |  7 +-
 .../gremlin/structure/io/IoRegistryTest.java    | 17 +++--
 6 files changed, 125 insertions(+), 49 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8d818fb0/docs/src/implementations.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/implementations.asciidoc b/docs/src/implementations.asciidoc
index 1b85f6a..e858d61 100644
--- a/docs/src/implementations.asciidoc
+++ b/docs/src/implementations.asciidoc
@@ -235,7 +235,7 @@ IO Implementations
 
 If a `Graph` requires custom serializers for IO to work properly, implement the `Graph.io` method.  A typical example of where a `Graph` would require such a custom serializers is if their identifier system uses non-primitive values, such as OrientDB's `Rid` class.  From basic serialization of a single `Vertex` all the way up the stack to Gremlin Server, the need to know how to handle these complex identifiers is an important requirement.
 
-The first step to implementing custom serializers is to first create an `IoRegistry` object and register the custom classes and serializers to it. Each `Io` implementation has different requirements for what it expects from the `IoRegistry`:
+The first step to implementing custom serializers is to first implement the `IoRegistry` interface and register the custom classes and serializers to it. Each `Io` implementation has different requirements for what it expects from the `IoRegistry`:
 
 * *GraphML* - No custom serializers expected/allowed.
 * *GraphSON* - Register a Jackson `SimpleModule`.  The `SimpleModule` encapsulates specific classes to be serialized, so it does not need to be registered to a specific class in the `IoRegistry` (use `null`).
@@ -244,12 +244,17 @@ The first step to implementing custom serializers is to first create an `IoRegis
 ** Register the custom class with a specific Kryo `Serializer' implementation.
 ** Register the custom class with a `Function<Kryo, Serializer>` for those cases where the Kryo `Serializer` requires the `Kryo` instance to get constructed.
 
-The following code provides a simple example for registering classes as described above:
+This implementation should provide a zero-arg constructor as the stack may require instantiation via reflection. Consider extending `AbstractIoRegistry` for convenience as follows:
 
 [source,java]
-IoRegistry registry = new IoRegistry();
-registry.register(GraphSONIo.class, null, new MySimpleModule());
-registry.register(GryoIo.class, MySimpleClass.class, new MySimpleClassSerializer());
+----
+public class MyGraphIoRegistry extends AbstractIoRegistry {
+    public MyGraphIoRegistry() {
+        register(GraphSONIo.class, null, new MyGraphSimpleModule());
+        register(GryoIo.class, MyGraphIdClass.class, new MyGraphIdSerializer());
+    }
+}
+----
 
 In the `Graph.io` method, provide the `IoRegistry` object to the supplied `Builder` and call the `create` method to return that `Io` instance.   In this way, `Graph` implementations can pre-configure custom serializers for IO interactions and users will not need to know about those details. Following this pattern will ensure proper execution of the test suite as well as simplified usage for end-users.
 

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8d818fb0/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/AbstractIoRegistry.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/AbstractIoRegistry.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/AbstractIoRegistry.java
new file mode 100644
index 0000000..428e613
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/AbstractIoRegistry.java
@@ -0,0 +1,79 @@
+/*
+ * 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;
+
+import org.javatuples.Pair;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * Base implementation of the {@link IoRegistry} interface that provides implementation of the methods using a
+ * a {@code HashMap}.  Vendors should extend from this class if they have custom serializers to provide to IO
+ * instances.  Simply register their classes to it via the provided {@link #register(Class, Class, Object)} method.
+ * <p/>
+ * It is important that implementations provide a zero-arg constructor as there may be cases where it will need to be
+ * constructed via reflection.  As such, calls to {@link #register(Class, Class, Object)} should likely occur
+ * directly in the constructor.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public abstract class AbstractIoRegistry implements IoRegistry {
+    private final Map<Class<? extends Io>, List<Pair<Class, Object>>> registeredSerializers = new HashMap<>();
+
+    /**
+     * Add a "serializer" for the {@code Mapper}.  Note that what is accepted as a "serializer" is implementation
+     * specific.  An {@link Io} implementation will consult this registry for "serializer" classes
+     * it expects so refer to the {@link Io} implementation to understand what is expected for these values.
+     *
+     * @param clazz usually this is the class that is to be serialized - may be {@code null}
+     * @param serializer a serializer implementation
+     */
+    protected void register(final Class<? extends Io> ioClass, final Class clazz, final Object serializer) {
+        if (!registeredSerializers.containsKey(ioClass))
+            registeredSerializers.put(ioClass, new ArrayList<>());
+        registeredSerializers.get(ioClass).add(Pair.with(clazz, serializer));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<Pair<Class,Object>> find(final Class<? extends Io> builderClass) {
+        if (!registeredSerializers.containsKey(builderClass)) return Collections.emptyList();
+        return Collections.unmodifiableList(registeredSerializers.get(builderClass).stream()
+                .collect(Collectors.toList()));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public <S> List<Pair<Class,S>> find(final Class<? extends Io> builderClass, final Class<S> serializerType) {
+        if (!registeredSerializers.containsKey(builderClass)) return Collections.emptyList();
+        return Collections.unmodifiableList(registeredSerializers.get(builderClass).stream()
+                .filter(p -> serializerType.isAssignableFrom(p.getValue1().getClass()))
+                .map(p -> Pair.with(p.getValue0(), (S) p.getValue1()))
+                .collect(Collectors.toList()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8d818fb0/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoRegistry.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoRegistry.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoRegistry.java
index ffbcc38..fee2811 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoRegistry.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoRegistry.java
@@ -32,50 +32,29 @@ import java.util.Map;
 import java.util.stream.Collectors;
 
 /**
- * A generalized custom serializer registry for vendors implementing a {@link Graph}.  Vendors should register
- * custom serializers to this registry via the {@link #register(Class, Class, Object)} method.  The serializers
- * registered depend on the {@link Io} implementations that are expected to be supported.  There are currently
- * just two core implementations in {@link GryoIo} and {@link GraphSONIo}.  Both of these should be supported
- * for full compliance with the test suite.  There is no need to use this class if the {@link Graph} does not
- * have custom classes that require serialization.
+ * A generalized custom serializer registry for vendors implementing a {@link Graph}.  Vendors should provide an
+ * implementation of this interface if their implementation requires custom serialization of identifiers or other
+ * such content housed in their graph.  Consider extending from {@link AbstractIoRegistry} and ensure that the
+ * implementation has a zero-arg constructor, as implementations may need to be constructed from reflection
+ * given different parts of the TinkerPop stack.
+ * <p/>
+ * The serializers to register depend on the {@link Io} implementations that are expected to be supported.  There
+ * are currently two core implementations in {@link GryoIo} and {@link GraphSONIo}.  Both of these should be supported
+ * for full compliance with the test suite.
+ * <p/>
+ * There is no need to use this class if the {@link Graph} does not have custom classes that require serialization.
  *
  * @author Stephen Mallette (http://stephen.genoprime.com)
  */
-public class IoRegistry {
-    private final Map<Class<? extends Io>, List<Pair<Class, Object>>> registeredSerializers = new HashMap<>();
-
-    /**
-     * Add a "serializer" for the {@code Mapper}.  Note that what is accepted as a "serializer" is implementation
-     * specific.  An {@link Io} implementation will consult this registry for "serializer" classes
-     * it expects so refer to the {@link Io} implementation to understand what is expected for these values.
-     *
-     * @param clazz usually this is the class that is to be serialized - may be {@code null}
-     * @param serializer a serializer implementation
-     */
-    public void register(final Class<? extends Io> ioClass, final Class clazz, final Object serializer) {
-        if (!registeredSerializers.containsKey(ioClass))
-            registeredSerializers.put(ioClass, new ArrayList<>());
-        registeredSerializers.get(ioClass).add(Pair.with(clazz, serializer));
-    }
-
+public interface IoRegistry {
     /**
      * Find a list of all the serializers registered to an {@link Io} class by the {@link Graph}.
      */
-    public List<Pair<Class,Object>> find(final Class<? extends Io> builderClass) {
-        if (!registeredSerializers.containsKey(builderClass)) return Collections.emptyList();
-        return Collections.unmodifiableList(registeredSerializers.get(builderClass).stream()
-                .collect(Collectors.toList()));
-    }
+    public List<Pair<Class,Object>> find(final Class<? extends Io> builderClass);
 
     /**
      * Find a list of all the serializers, of a particular type, registered to an {@link Io} class by the
      * {@link Graph}.
      */
-    public <S> List<Pair<Class,S>> find(final Class<? extends Io> builderClass, final Class<S> serializerType) {
-        if (!registeredSerializers.containsKey(builderClass)) return Collections.emptyList();
-        return Collections.unmodifiableList(registeredSerializers.get(builderClass).stream()
-                .filter(p -> serializerType.isAssignableFrom(p.getValue1().getClass()))
-                .map(p -> Pair.with(p.getValue0(), (S) p.getValue1()))
-                .collect(Collectors.toList()));
-    }
+    public <S> List<Pair<Class,S>> find(final Class<? extends Io> builderClass, final Class<S> serializerType);
 }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8d818fb0/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapper.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapper.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapper.java
index 03af2d4..5b019a8 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapper.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapper.java
@@ -40,8 +40,11 @@ import java.util.List;
  * implementations to it as follows:
  * <pre>
  * {@code
- * IoRegistry registry = new IoRegistry();
- * registry.register(GraphSONIo.class, null, new MySimpleModule());
+ * public class MyGraphIoRegistry extends AbstractIoRegistry {
+ *   public MyGraphIoRegistry() {
+ *     register(GraphSONIo.class, null, new MyGraphSimpleModule());
+ *   }
+ * }
  * }
  * </pre>
  *

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8d818fb0/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java
index 7587897..0ba7911 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapper.java
@@ -107,8 +107,11 @@ import java.util.stream.Collectors;
  * For example:
  * <pre>
  * {@code
- * IoRegistry registry = new IoRegistry();
- * registry.register(GryoIo.class, MyCustomClass.class, new MyCustomClassSerializer());
+ * public class MyGraphIoRegistry extends AbstractIoRegistry {
+ *   public MyGraphIoRegistry() {
+ *     register(GryoIo.class, MyGraphIdClass.class, new MyGraphIdSerializer());
+ *   }
+ * }
  * }
  * </pre>
  *

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8d818fb0/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoRegistryTest.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoRegistryTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoRegistryTest.java
index 61b4da4..bca78f1 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoRegistryTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/IoRegistryTest.java
@@ -36,7 +36,7 @@ public class IoRegistryTest {
     public void shouldFindRegisteredClassesByIoImplementation() {
         // note that this is a non-standard usage of IoRegistry strictly for testing purposes - refer to javadocs
         // for proper usage
-        final IoRegistry registry = new IoRegistry();
+        final FakeIoRegistry registry = new FakeIoRegistry();
         registry.register(GryoIo.class, Long.class, "test");
         registry.register(GryoIo.class, Integer.class, 1);
         registry.register(GryoIo.class, String.class, 1L);
@@ -61,7 +61,7 @@ public class IoRegistryTest {
     public void shouldFindRegisteredClassesByIoImplementationAndSerializer() {
         // note that this is a non-standard usage of IoRegistry strictly for testing purposes - refer to javadocs
         // for proper usage
-        final IoRegistry registry = new IoRegistry();
+        final FakeIoRegistry registry = new FakeIoRegistry();
         registry.register(GryoIo.class, Long.class, "test");
         registry.register(GryoIo.class, Integer.class, 1);
         registry.register(GryoIo.class, String.class, 1L);
@@ -80,20 +80,27 @@ public class IoRegistryTest {
 
     @Test
     public void shouldReturnEmptyListIfIoKeyNotPresentOnFindByImplementation() {
-        final IoRegistry registry = new IoRegistry();
+        final FakeIoRegistry registry = new FakeIoRegistry();
         assertEquals(0, registry.find(GryoIo.class).size());
     }
 
     @Test
     public void shouldReturnEmptyListIfIoKeyNotPresentOnFindByImplementationAndSerializer() {
-        final IoRegistry registry = new IoRegistry();
+        final FakeIoRegistry registry = new FakeIoRegistry();
         assertEquals(0, registry.find(GryoIo.class, String.class).size());
     }
 
     @Test
     public void shouldReturnEmptyListIfIoKeyPresentButNoSerializer() {
-        final IoRegistry registry = new IoRegistry();
+        final FakeIoRegistry registry = new FakeIoRegistry();
         registry.register(GryoIo.class, Long.class, String.class);
         assertEquals(0, registry.find(GryoIo.class, Number.class).size());
     }
+
+    /**
+     * This class is just for simplicity of testing.  This is not a proper implementation of this class.
+     * Proper implementations should call {@link #register(Class, Class, Object)} within a zero-arg constructor.
+     */
+    public static class FakeIoRegistry extends AbstractIoRegistry {
+    }
 }