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/04/16 14:10:45 UTC

incubator-tinkerpop git commit: Add revised Io interface with IoRegistry.

Repository: incubator-tinkerpop
Updated Branches:
  refs/heads/refactor-io [created] 8a3b38ab6


Add revised Io interface with IoRegistry.

Allows implementers to register all their serialization classes with the IoRegistry which the Io implementations can consult for custom serializers.  This should get rid of the old Graph.Io interface which had tighter coupling to the Reader/Writer implementations.  At this point the two Io interfaces are still in there side-by-side.


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

Branch: refs/heads/refactor-io
Commit: 8a3b38ab60b562c10d8f12f9d38b64748221f84e
Parents: f366285
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu Apr 16 08:08:20 2015 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Apr 16 08:08:20 2015 -0400

----------------------------------------------------------------------
 .../tinkerpop/gremlin/structure/Graph.java      |   5 +
 .../gremlin/structure/io/GraphReader.java       |   3 +
 .../gremlin/structure/io/GraphWriter.java       |   4 +
 .../tinkerpop/gremlin/structure/io/Io.java      |  71 +++++++++++++
 .../gremlin/structure/io/IoRegistry.java        |  62 ++++++++++++
 .../tinkerpop/gremlin/structure/io/Mapper.java  |   4 +
 .../gremlin/structure/io/graphml/GraphMLIo.java |  96 ++++++++++++++++++
 .../structure/io/graphml/GraphMLMapper.java     |  47 +++++++++
 .../structure/io/graphml/GraphMLReader.java     |   2 +-
 .../structure/io/graphml/GraphMLWriter.java     |   2 +-
 .../structure/io/graphson/GraphSONIo.java       |  99 ++++++++++++++++++
 .../structure/io/graphson/GraphSONMapper.java   |  16 ++-
 .../structure/io/graphson/GraphSONReader.java   |   2 +-
 .../structure/io/graphson/GraphSONWriter.java   |   2 +-
 .../gremlin/structure/io/gryo/GryoIo.java       | 100 +++++++++++++++++++
 .../gremlin/structure/io/gryo/GryoMapper.java   |  26 ++++-
 .../gremlin/structure/io/gryo/GryoReader.java   |   2 +-
 .../gremlin/structure/io/gryo/GryoWriter.java   |   3 +-
 18 files changed, 538 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8a3b38ab/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Graph.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Graph.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Graph.java
index f01441c..529f6bb 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Graph.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Graph.java
@@ -26,6 +26,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
 import org.apache.tinkerpop.gremlin.process.traversal.engine.StandardTraversalEngine;
 import org.apache.tinkerpop.gremlin.structure.io.DefaultIo;
+import org.apache.tinkerpop.gremlin.structure.io.Mapper;
 import org.apache.tinkerpop.gremlin.structure.io.graphml.GraphMLReader;
 import org.apache.tinkerpop.gremlin.structure.io.graphml.GraphMLWriter;
 import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONMapper;
@@ -252,6 +253,10 @@ public interface Graph extends AutoCloseable {
         return new DefaultIo(this);
     }
 
+    public default <I extends org.apache.tinkerpop.gremlin.structure.io.Io> I io(final org.apache.tinkerpop.gremlin.structure.io.Io.Builder<I> builder) {
+        return (I) builder.graph(this).create();
+    }
+
     /**
      * A collection of global {@link Variables} associated with the graph.
      * Variables are used for storing metadata about the graph.

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8a3b38ab/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/GraphReader.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/GraphReader.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/GraphReader.java
index f2066d2..cf5ee04 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/GraphReader.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/GraphReader.java
@@ -96,4 +96,7 @@ public interface GraphReader {
      */
     public Edge readEdge(final InputStream inputStream, final Function<DetachedEdge, Edge> edgeMaker) throws IOException;
 
+    public interface ReaderBuilder<T extends GraphReader> {
+        T create();
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8a3b38ab/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/GraphWriter.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/GraphWriter.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/GraphWriter.java
index d3075f3..c63476f 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/GraphWriter.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/GraphWriter.java
@@ -86,4 +86,8 @@ public interface GraphWriter {
      * Write an edge to a stream.
      */
     public void writeEdge(final OutputStream outputStream, final Edge e) throws IOException;
+
+    public interface WriterBuilder<T extends GraphWriter> {
+        T create();
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8a3b38ab/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/Io.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/Io.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/Io.java
new file mode 100644
index 0000000..5abcc1f
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/Io.java
@@ -0,0 +1,71 @@
+/*
+ * 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.apache.tinkerpop.gremlin.structure.Graph;
+
+import java.io.IOException;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public interface Io<R extends GraphReader.ReaderBuilder, W extends GraphWriter.WriterBuilder, M extends Mapper.Builder> {
+
+    /**
+     * Creates a {@link GraphReader.ReaderBuilder} implementation . Implementers should call the
+     * {@link #mapper()} function to feed its result to the builder.  In this way, custom class serializers
+     * registered to the {@link Mapper.Builder} by {@link Graph} implementations will end up being used for
+     * the serialization process.
+     */
+    public R reader();
+
+    /**
+     * Creates a {@link GraphWriter.WriterBuilder} implementation . Implementers should call the
+     * {@link #mapper()} function to feed its result to the builder.  In this way, custom class serializers
+     * registered to the {@link Mapper.Builder} by {@link Graph} implementations will end up being used for
+     * the serialization process.
+     */
+    public W writer();
+
+    /**
+     * Constructs a {@link Mapper.Builder} which is responsible for constructing the abstraction over different
+     * serialization methods.  Implementations should set defaults as required, but most importantly need to
+     * make the appropriate call to {@link Mapper.Builder#addRegistry(IoRegistry)} which will provide the
+     * builder with any required custom serializers of the {@link Graph}.
+     */
+    public M mapper();
+
+    /**
+     * Write a {@link Graph} to file using the default configuration of the {@link #writer()} and its supplied
+     * {@link #mapper()}.
+     */
+    public void write(final String file) throws IOException;
+
+    /**
+     * Read a {@link Graph} from file using the default configuration of the {@link #reader()} and its supplied
+     * {@link #mapper()}.
+     */
+    public void read(final String file) throws IOException;
+
+    public interface Builder<I extends Io> {
+        public Builder<? extends Io> registry(final IoRegistry registry);
+        public Builder<? extends Io> graph(final Graph g);
+        public I create();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8a3b38ab/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
new file mode 100644
index 0000000..7bd8560
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/IoRegistry.java
@@ -0,0 +1,62 @@
+/*
+ * 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.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class IoRegistry {
+    private final Map<Class<? extends Io.Builder>, 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.  Note that the {@link Io.Builder} implementation will consult this registry for "serializer" classes
+     * it expects so consult the {@link Io.Builder} 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.Builder> builderClass, final Class clazz, final Object serializer) {
+        if (registeredSerializers.containsKey(builderClass))
+            registeredSerializers.get(builderClass).add(Pair.with(clazz, serializer));
+        else
+            registeredSerializers.put(builderClass, Arrays.asList(Pair.with(clazz, serializer)));
+    }
+
+    public List<Pair<Class,Object>> find(final Class<? extends Io> builderClass) {
+        return Collections.unmodifiableList(registeredSerializers.get(builderClass).stream()
+                .collect(Collectors.toList()));
+    }
+
+    public <S> List<Pair<Class,S>> find(final Class<? extends Io> builderClass, final Class<S> c) {
+        return Collections.unmodifiableList(registeredSerializers.get(builderClass).stream()
+                .filter(p -> p.getValue1().getClass().isAssignableFrom(c))
+                .map(p -> Pair.with(p.getValue0(), (S) p.getValue1()))
+                .collect(Collectors.toList()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8a3b38ab/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/Mapper.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/Mapper.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/Mapper.java
index 64f23f3..1e11028 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/Mapper.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/Mapper.java
@@ -29,4 +29,8 @@ public interface Mapper<T> {
      * Create a new instance of the internal object mapper that an implementation represents.
      */
     public T createMapper();
+
+    public interface Builder<B extends Builder> {
+        public B addRegistry(final IoRegistry registry);
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8a3b38ab/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLIo.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLIo.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLIo.java
new file mode 100644
index 0000000..aa99d5c
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLIo.java
@@ -0,0 +1,96 @@
+/*
+ * 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.graphml;
+
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.io.Io;
+import org.apache.tinkerpop.gremlin.structure.io.IoRegistry;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class GraphMLIo implements Io<GraphMLReader.Builder, GraphMLWriter.Builder, GraphMLMapper.Builder> {
+    private final Graph graph;
+
+    public GraphMLIo(final Graph graph) {
+        this.graph = graph;
+    }
+
+    @Override
+    public GraphMLReader.Builder reader() {
+        return GraphMLReader.build();
+    }
+
+    @Override
+    public GraphMLWriter.Builder writer() {
+        return GraphMLWriter.build();
+    }
+
+    @Override
+    public GraphMLMapper.Builder mapper() {
+        return GraphMLMapper.build();
+    }
+
+    @Override
+    public void write(final String file) throws IOException {
+        try (final OutputStream out = new FileOutputStream(file)) {
+            writer().create().writeGraph(out, graph);
+        }
+    }
+
+    @Override
+    public void read(final String file) throws IOException {
+        try (final InputStream in = new FileInputStream(file)) {
+            reader().create().readGraph(in, graph);
+        }
+    }
+
+    public static Io.Builder<GraphMLIo> build() {
+        return new Builder();
+    }
+
+    public static class Builder implements Io.Builder<GraphMLIo> {
+
+        private Graph graph;
+
+        @Override
+        public Io.Builder<GraphMLIo> registry(final IoRegistry registry) {
+            // GraphML doesn't make use of a registry but the contract should simply exist
+            return this;
+        }
+
+        @Override
+        public Io.Builder<GraphMLIo> graph(final Graph g) {
+            this.graph = g;
+            return this;
+        }
+
+        @Override
+        public GraphMLIo create() {
+            if (null == graph) throw new IllegalArgumentException("The graph argument was not specified");
+            return new GraphMLIo(graph);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8a3b38ab/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLMapper.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLMapper.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLMapper.java
new file mode 100644
index 0000000..1443c19
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLMapper.java
@@ -0,0 +1,47 @@
+/*
+ * 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.graphml;
+
+import org.apache.tinkerpop.gremlin.structure.io.IoRegistry;
+import org.apache.tinkerpop.gremlin.structure.io.Mapper;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class GraphMLMapper implements Mapper<Object> {
+    @Override
+    public Object createMapper() {
+        throw new UnsupportedOperationException("GraphML does not have an object mapper - it is a format for full Graph serialization");
+    }
+
+    public static Builder build() {
+        return new Builder();
+    }
+
+    public static class Builder implements Mapper.Builder<Builder> {
+        @Override
+        public Builder addRegistry(final IoRegistry registry) {
+            throw new UnsupportedOperationException("GraphML does not accept custom serializers - it is a format for full Graph serialization");
+        }
+
+        public GraphMLMapper create() {
+            return new GraphMLMapper();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8a3b38ab/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLReader.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLReader.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLReader.java
index e93b804..13450c4 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLReader.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLReader.java
@@ -251,7 +251,7 @@ public class GraphMLReader implements GraphReader {
     /**
      * Allows configuration and construction of the GraphMLReader instance.
      */
-    public static final class Builder {
+    public static final class Builder implements ReaderBuilder<GraphMLReader> {
         private String vertexIdKey = T.id.getAccessor();
         private String edgeIdKey = T.id.getAccessor();
         private String edgeLabelKey = GraphMLTokens.LABEL_E;

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8a3b38ab/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLWriter.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLWriter.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLWriter.java
index 87ee99d..21b1f3d 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLWriter.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLWriter.java
@@ -374,7 +374,7 @@ public class GraphMLWriter implements GraphWriter {
         return new Builder();
     }
 
-    public static final class Builder {
+    public static final class Builder implements WriterBuilder<GraphMLWriter> {
         private boolean normalize = false;
         private Map<String, String> vertexKeyTypes = null;
         private Map<String, String> edgeKeyTypes = null;

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8a3b38ab/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONIo.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONIo.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONIo.java
new file mode 100644
index 0000000..d4deb6b
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONIo.java
@@ -0,0 +1,99 @@
+/*
+ * 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.Graph;
+import org.apache.tinkerpop.gremlin.structure.io.Io;
+import org.apache.tinkerpop.gremlin.structure.io.IoRegistry;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class GraphSONIo implements Io<GraphSONReader.Builder, GraphSONWriter.Builder, GraphSONMapper.Builder> {
+    private final IoRegistry registry;
+    private final Graph graph;
+
+    public GraphSONIo(final IoRegistry registry, final Graph graph) {
+        this.registry = registry;
+        this.graph = graph;
+    }
+
+    @Override
+    public GraphSONReader.Builder reader() {
+        return GraphSONReader.build().mapper(mapper().create());
+    }
+
+    @Override
+    public GraphSONWriter.Builder writer() {
+        return GraphSONWriter.build().mapper(mapper().create());
+    }
+
+    @Override
+    public GraphSONMapper.Builder mapper() {
+        return GraphSONMapper.build().addRegistry(this.registry);
+    }
+
+    @Override
+    public void write(final String file) throws IOException {
+        try (final OutputStream out = new FileOutputStream(file)) {
+            writer().create().writeGraph(out, graph);
+        }
+    }
+
+    @Override
+    public void read(final String file) throws IOException {
+        try (final InputStream in = new FileInputStream(file)) {
+            reader().create().readGraph(in, graph);
+        }
+    }
+
+    public static Io.Builder<GraphSONIo> build() {
+        return new Builder();
+    }
+
+    public static class Builder implements Io.Builder<GraphSONIo> {
+
+        private IoRegistry registry = null;
+        private Graph graph;
+
+        @Override
+        public Io.Builder<GraphSONIo> registry(final IoRegistry registry) {
+            this.registry = registry;
+            return this;
+        }
+
+        @Override
+        public Io.Builder<GraphSONIo> graph(final Graph g) {
+            this.graph = g;
+            return this;
+        }
+
+        @Override
+        public GraphSONIo create() {
+            if (null == graph) throw new IllegalArgumentException("The graph argument was not specified");
+            return new GraphSONIo(registry, graph);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8a3b38ab/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 5613ed9..2c589f3 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
@@ -23,7 +23,9 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.SerializationFeature;
 import com.fasterxml.jackson.databind.module.SimpleModule;
 import com.fasterxml.jackson.databind.ser.DefaultSerializerProvider;
+import org.apache.tinkerpop.gremlin.structure.io.IoRegistry;
 import org.apache.tinkerpop.gremlin.structure.io.Mapper;
+import org.javatuples.Pair;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -83,15 +85,22 @@ public class GraphSONMapper implements Mapper<ObjectMapper> {
         return new Builder();
     }
 
-    public static class Builder {
+    public static class Builder implements Mapper.Builder<Builder> {
         private List<SimpleModule> customModules = new ArrayList<>();
         private boolean loadCustomModules = false;
         private boolean normalize = false;
         private boolean embedTypes = false;
+        private IoRegistry registry = null;
 
         private Builder() {
         }
 
+        @Override
+        public Builder addRegistry(final IoRegistry registry) {
+            this.registry = registry;
+            return this;
+        }
+
         /**
          * Supply a mapper module for serialization/deserialization.
          */
@@ -126,6 +135,11 @@ public class GraphSONMapper implements Mapper<ObjectMapper> {
         }
 
         public GraphSONMapper create() {
+            if (registry != null) {
+                final List<Pair<Class, SimpleModule>> simpleModules = registry.find(GraphSONIo.class, SimpleModule.class);
+                simpleModules.stream().map(Pair::getValue1).forEach(this.customModules::add);
+            }
+
             return new GraphSONMapper(customModules, loadCustomModules, normalize, embedTypes);
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8a3b38ab/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONReader.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONReader.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONReader.java
index 470bfe3..67c8da0 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONReader.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONReader.java
@@ -210,7 +210,7 @@ public class GraphSONReader implements GraphReader {
         return new Builder();
     }
 
-    public static class Builder {
+    public static class Builder implements ReaderBuilder<GraphSONReader> {
         private long batchSize = BatchGraph.DEFAULT_BUFFER_SIZE;
         private String vertexIdKey = T.id.getAccessor();
         private String edgeIdKey = T.id.getAccessor();

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8a3b38ab/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONWriter.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONWriter.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONWriter.java
index 0a11d45..c480037 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONWriter.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONWriter.java
@@ -99,7 +99,7 @@ public class GraphSONWriter implements GraphWriter {
         return new Builder();
     }
 
-    public static class Builder {
+    public static class Builder implements WriterBuilder<GraphSONWriter> {
 
         private GraphSONMapper mapper = GraphSONMapper.build().create();
 

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8a3b38ab/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoIo.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoIo.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoIo.java
new file mode 100644
index 0000000..f5570d9
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoIo.java
@@ -0,0 +1,100 @@
+/*
+ * 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.gryo;
+
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.io.Io;
+import org.apache.tinkerpop.gremlin.structure.io.IoRegistry;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class GryoIo implements Io<GryoReader.Builder, GryoWriter.Builder, GryoMapper.Builder> {
+
+    private final IoRegistry registry;
+    private final Graph graph;
+
+    public GryoIo(final IoRegistry registry, final Graph graph) {
+        this.registry = registry;
+        this.graph = graph;
+    }
+
+    @Override
+    public GryoReader.Builder reader() {
+        return GryoReader.build().mapper(mapper().create());
+    }
+
+    @Override
+    public GryoWriter.Builder writer() {
+        return GryoWriter.build().mapper(mapper().create());
+    }
+
+    @Override
+    public GryoMapper.Builder mapper() {
+        return GryoMapper.build().addRegistry(this.registry);
+    }
+
+    @Override
+    public void write(final String file) throws IOException {
+        try (final OutputStream out = new FileOutputStream(file)) {
+            writer().create().writeGraph(out, graph);
+        }
+    }
+
+    @Override
+    public void read(final String file) throws IOException {
+        try (final InputStream in = new FileInputStream(file)) {
+            reader().create().readGraph(in, graph);
+        }
+    }
+
+    public static Io.Builder<GryoIo> build() {
+        return new Builder();
+    }
+
+    public static class Builder implements Io.Builder<GryoIo> {
+
+        private IoRegistry registry = null;
+        private Graph graph;
+
+        @Override
+        public Io.Builder<GryoIo> registry(final IoRegistry registry) {
+            this.registry = registry;
+            return this;
+        }
+
+        @Override
+        public Io.Builder<GryoIo> graph(final Graph g) {
+            this.graph = g;
+            return this;
+        }
+
+        @Override
+        public GryoIo create() {
+            if (null == graph) throw new IllegalArgumentException("The graph argument was not specified");
+            return new GryoIo(registry, graph);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8a3b38ab/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 5ab18e6..f50198f 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
@@ -38,6 +38,7 @@ import org.apache.tinkerpop.gremlin.structure.Edge;
 import org.apache.tinkerpop.gremlin.structure.Property;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.structure.io.IoRegistry;
 import org.apache.tinkerpop.gremlin.structure.io.Mapper;
 import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedEdge;
 import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedPath;
@@ -56,6 +57,7 @@ import org.apache.tinkerpop.shaded.kryo.io.Input;
 import org.apache.tinkerpop.shaded.kryo.io.Output;
 import org.apache.tinkerpop.shaded.kryo.util.DefaultStreamFactory;
 import org.apache.tinkerpop.shaded.kryo.util.MapReferenceResolver;
+import org.javatuples.Pair;
 import org.javatuples.Triplet;
 
 import java.io.IOException;
@@ -177,7 +179,7 @@ public final class GryoMapper implements Mapper<Kryo> {
         return Version.V_1_0_0.getBuilder();
     }
 
-    public static interface Builder {
+    public static interface Builder extends Mapper.Builder<Builder> {
         /**
          * Add mapper classes to serializes with gryo using standard serialization.
          */
@@ -335,11 +337,19 @@ public final class GryoMapper implements Mapper<Kryo> {
         private byte extendedVersion = DEFAULT_EXTENDED_VERSION;
         private BiPredicate<Byte, Byte> compliant = (readExt, serExt) -> readExt.equals(serExt);
 
+        private IoRegistry registry = null;
+
         /**
          * Starts numbering classes for Gryo serialization at 65536 to leave room for future usage by TinkerPop.
          */
         private final AtomicInteger currentSerializationId = new AtomicInteger(65536);
 
+        @Override
+        public Builder addRegistry(final IoRegistry registry) {
+            this.registry = registry;
+            return this;
+        }
+
         /**
          * {@inheritDoc}
          */
@@ -396,6 +406,20 @@ public final class GryoMapper implements Mapper<Kryo> {
 
         @Override
         public GryoMapper create() {
+            if (registry != null) {
+                final List<Pair<Class, Object>> serializers = registry.find(GryoIo.class);
+                serializers.forEach(p -> {
+                    if (null == p.getValue1())
+                        addCustom(p.getValue0());
+                    else if (p.getValue1() instanceof Serializer)
+                        addCustom(p.getValue0(), (Serializer) p.getValue1());
+                    else if (p.getValue1() instanceof Function)
+                        addCustom(p.getValue0(), (Function<Kryo, Serializer>) p.getValue1());
+                    else
+                        throw new RuntimeException("Invalid serializer"); // todo: cleanup exception handling
+                });
+            }
+
             return new GryoMapper(serializationList, this::writeHeader, this::readHeader);
         }
 

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8a3b38ab/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoReader.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoReader.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoReader.java
index 08ca97a..f64b53e 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoReader.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoReader.java
@@ -340,7 +340,7 @@ public class GryoReader implements GraphReader {
         return new Builder();
     }
 
-    public static class Builder {
+    public static class Builder implements ReaderBuilder<GryoReader> {
         private File tempFile;
         private long batchSize = BatchGraph.DEFAULT_BUFFER_SIZE;
         private String vertexIdKey = T.id.getAccessor();

http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/8a3b38ab/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoWriter.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoWriter.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoWriter.java
index 642e7d8..7e51676 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoWriter.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoWriter.java
@@ -30,6 +30,7 @@ import org.apache.tinkerpop.shaded.kryo.io.Output;
 
 import java.io.IOException;
 import java.io.OutputStream;
+import java.io.Writer;
 import java.nio.ByteBuffer;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -159,7 +160,7 @@ public class GryoWriter implements GraphWriter {
         return new Builder();
     }
 
-    public static class Builder {
+    public static class Builder implements WriterBuilder<GryoWriter> {
         /**
          * Always creates the most current version available.
          */