| /* |
| * 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.Direction; |
| import org.apache.tinkerpop.gremlin.structure.Edge; |
| import org.apache.tinkerpop.gremlin.structure.Graph; |
| 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.GraphWriter; |
| import org.apache.tinkerpop.gremlin.structure.io.Mapper; |
| import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedFactory; |
| import org.apache.tinkerpop.gremlin.structure.util.star.StarGraph; |
| import org.apache.tinkerpop.gremlin.structure.util.star.StarGraphGryoSerializer; |
| import org.apache.tinkerpop.shaded.kryo.Kryo; |
| import org.apache.tinkerpop.shaded.kryo.io.Output; |
| |
| import java.io.IOException; |
| import java.io.OutputStream; |
| import java.util.Iterator; |
| |
| /** |
| * The {@link GraphWriter} for the Gremlin Structure serialization format based on Kryo. The format is meant to be |
| * non-lossy in terms of Gremlin Structure to Gremlin Structure migrations (assuming both structure implementations |
| * support the same graph features). |
| * <p/> |
| * This implementation is not thread-safe. Have one {@code GraphWriter} instance per thread. |
| * |
| * @author Stephen Mallette (http://stephen.genoprime.com) |
| */ |
| public final class GryoWriter implements GraphWriter { |
| private Kryo kryo; |
| |
| private GryoWriter(final Mapper<Kryo> gryoMapper) { |
| this.kryo = gryoMapper.createMapper(); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void writeGraph(final OutputStream outputStream, final Graph g) throws IOException { |
| writeVertices(outputStream, g.vertices(), Direction.BOTH); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void writeVertices(final OutputStream outputStream, final Iterator<Vertex> vertexIterator, final Direction direction) throws IOException { |
| kryo.getRegistration(StarGraph.class).setSerializer(StarGraphGryoSerializer.with(direction)); |
| final Output output = new Output(outputStream); |
| while (vertexIterator.hasNext()) { |
| writeVertexInternal(output, vertexIterator.next()); |
| } |
| output.flush(); |
| kryo.getRegistration(StarGraph.class).setSerializer(StarGraphGryoSerializer.with(Direction.BOTH)); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void writeVertices(final OutputStream outputStream, final Iterator<Vertex> vertexIterator) throws IOException { |
| writeVertices(outputStream, vertexIterator, null); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void writeVertex(final OutputStream outputStream, final Vertex v, final Direction direction) throws IOException { |
| kryo.getRegistration(StarGraph.class).setSerializer(StarGraphGryoSerializer.with(direction)); |
| final Output output = new Output(outputStream); |
| writeVertexInternal(output, v); |
| output.flush(); |
| kryo.getRegistration(StarGraph.class).setSerializer(StarGraphGryoSerializer.with(Direction.BOTH)); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void writeVertex(final OutputStream outputStream, final Vertex v) throws IOException { |
| writeVertex(outputStream, v, null); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void writeEdge(final OutputStream outputStream, final Edge e) throws IOException { |
| final Output output = new Output(outputStream); |
| writeHeader(output); |
| kryo.writeObject(output, DetachedFactory.detach(e, true)); |
| output.flush(); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void writeVertexProperty(final OutputStream outputStream, final VertexProperty vp) throws IOException { |
| final Output output = new Output(outputStream); |
| writeHeader(output); |
| kryo.writeObject(output, DetachedFactory.detach(vp, true)); |
| output.flush(); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void writeProperty(final OutputStream outputStream, final Property p) throws IOException { |
| final Output output = new Output(outputStream); |
| writeHeader(output); |
| kryo.writeObject(output, DetachedFactory.detach(p, true)); |
| output.flush(); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void writeObject(final OutputStream outputStream, final Object object) { |
| final Output output = new Output(outputStream); |
| this.kryo.writeClassAndObject(output, object); |
| output.flush(); |
| } |
| |
| void writeVertexInternal(final Output output, final Vertex v) throws IOException { |
| writeHeader(output); |
| kryo.writeObject(output, StarGraph.of(v)); |
| kryo.writeClassAndObject(output, VertexTerminator.INSTANCE); |
| } |
| |
| void writeHeader(final Output output) throws IOException { |
| output.writeBytes(GryoMapper.HEADER); |
| } |
| |
| public static Builder build() { |
| return new Builder(); |
| } |
| |
| public final static class Builder implements WriterBuilder<GryoWriter> { |
| /** |
| * Always creates the most current version available. |
| */ |
| private Mapper<Kryo> gryoMapper = GryoMapper.build().create(); |
| |
| private Builder() { |
| } |
| |
| /** |
| * Supply a mapper {@link GryoMapper} instance to use as the serializer for the {@code KryoWriter}. |
| */ |
| public Builder mapper(final Mapper<Kryo> gryoMapper) { |
| this.gryoMapper = gryoMapper; |
| return this; |
| } |
| |
| /** |
| * Create the {@code GryoWriter}. |
| */ |
| public GryoWriter create() { |
| return new GryoWriter(this.gryoMapper); |
| } |
| } |
| } |