com.amertkara.tinkerpop.blueprints.impl.mongodb.MongoDBGraph.java Source code

Java tutorial

Introduction

Here is the source code for com.amertkara.tinkerpop.blueprints.impl.mongodb.MongoDBGraph.java

Source

/**
 * 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 com.amertkara.tinkerpop.blueprints.impl.mongodb;

import java.util.NoSuchElementException;
import java.util.Properties;
import java.util.Set;

import org.bson.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.mongodb.DBRef;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.MongoWriteConcernException;
import com.mongodb.MongoWriteException;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Element;
import com.tinkerpop.blueprints.Features;
import com.tinkerpop.blueprints.GraphQuery;
import com.tinkerpop.blueprints.KeyIndexableGraph;
import com.tinkerpop.blueprints.MetaGraph;
import com.tinkerpop.blueprints.Parameter;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.util.ExceptionFactory;

/**
 * @author Mert Kara (https://github.com/amertkara)
 * @since 0.1.0
 */
public class MongoDBGraph implements MetaGraph<MongoDatabase>, KeyIndexableGraph {
    private static final Logger logger = LoggerFactory.getLogger(MongoDBGraph.class.getName());
    private static final Features FEATURES = new Features();

    private MongoClient mongoClient;
    private MongoDatabase rawGraph;
    private String edgeCollection;
    private String vertexCollection;

    static {
        // TODO: put the features
    }

    /**
     * TODO: Implement constructors that take {@link Properties} and {@link MongoClientOptions}
     * 
     * @param host
     * @param port
     * @param databaseName
     * @param edgeCollection
     * @param vertexCollection
     */
    public MongoDBGraph(final String host, final int port, final String databaseName, final String edgeCollection,
            final String vertexCollection) {

        if (edgeCollection == null || edgeCollection.isEmpty() || vertexCollection == null
                || vertexCollection.isEmpty() || databaseName == null || databaseName.isEmpty()) {
            throw new IllegalStateException("edgeCollection, vertexCollection and databaseName cannot be empty.");
        }

        if (host != null && !host.isEmpty()) {
            mongoClient = new MongoClient(host, port);
        } else {
            mongoClient = new MongoClient();
        }

        this.edgeCollection = edgeCollection;
        this.vertexCollection = vertexCollection;
        this.rawGraph = mongoClient.getDatabase(databaseName);

        this.rawGraph.getCollection(edgeCollection).createIndex(
                new Document(MongoDBConstants.FIELD_ID, new Integer(1)).append("unique", new Boolean(true)));
        this.rawGraph.getCollection(vertexCollection).createIndex(
                new Document(MongoDBConstants.FIELD_ID, new Integer(1)).append("unique", new Boolean(true)));
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.tinkerpop.blueprints.Graph#getFeatures()
     */
    @Override
    public Features getFeatures() {
        return FEATURES;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.tinkerpop.blueprints.Graph#addVertex(java.lang.Object)
     */
    @Override
    public Vertex addVertex(Object id) throws MongoWriteException, MongoWriteConcernException {
        if (id == null) {
            id = getCollectionNextID(vertexCollection);
        }

        MongoDBVertexIterable vertexIt;
        MongoDBVertex vertex;

        // Insert the new edge
        this.rawGraph.getCollection(vertexCollection).insertOne(new Document(MongoDBConstants.FIELD_ID, id));

        // TODO: Performance can be improved by getting rid of the second call.
        // Fetch the newly created edge
        vertexIt = new MongoDBVertexIterable(
                this.rawGraph.getCollection(vertexCollection).find(new Document(MongoDBConstants.FIELD_ID, id)),
                this);

        try {
            vertex = (MongoDBVertex) vertexIt.iterator().next();
        } catch (NoSuchElementException nsee) {
            logger.warn("Newly created vertex could not be fetched. The error message: " + nsee.getMessage());
            vertex = null;
        }

        return vertex;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.tinkerpop.blueprints.Graph#getVertex(java.lang.Object)
     */
    @Override
    public Vertex getVertex(Object id) {
        if (null == id) {
            throw ExceptionFactory.vertexIdCanNotBeNull();
        }

        MongoDBVertex vertex;
        MongoDBVertexIterable vertexIt;

        try {
            if (id instanceof Long) {
                id = (Long) id;
            } else if (id instanceof Number) {
                id = new Long(((Number) id).longValue());
            } else {
                id = new Long(Double.valueOf(id.toString()).longValue());
            }

            vertexIt = new MongoDBVertexIterable(
                    this.rawGraph.getCollection(vertexCollection).find(new Document(MongoDBConstants.FIELD_ID, id)),
                    this);
            vertex = (MongoDBVertex) vertexIt.iterator().next();
        } catch (NoSuchElementException nsee) {
            logger.warn("Vertex could not be fetched. The error message: " + nsee.getMessage());
            vertex = null;
        } catch (NumberFormatException nfe) {
            logger.warn("Given id could not be converted to Long. The error message:  " + nfe.getMessage());
            vertex = null;
        }

        return vertex;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.tinkerpop.blueprints.Graph#removeVertex(com.tinkerpop.blueprints.
     * Vertex)
     */
    @Override
    public void removeVertex(Vertex vertex) {
        // TODO Auto-generated method stub

    }

    /*
     * (non-Javadoc)
     * 
     * @see com.tinkerpop.blueprints.Graph#getVertices()
     */
    @Override
    public Iterable<Vertex> getVertices() {
        // TODO Auto-generated method stub
        return null;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.tinkerpop.blueprints.Graph#getVertices(java.lang.String,
     * java.lang.Object)
     */
    @Override
    public Iterable<Vertex> getVertices(String key, Object value) {
        // TODO Auto-generated method stub
        return null;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.tinkerpop.blueprints.Graph#addEdge(java.lang.Object,
     * com.tinkerpop.blueprints.Vertex, com.tinkerpop.blueprints.Vertex,
     * java.lang.String)
     */
    @Override
    public Edge addEdge(Object id, Vertex outVertex, Vertex inVertex, String label)
            throws MongoWriteException, MongoWriteConcernException {
        if (label == null) {
            throw ExceptionFactory.edgeLabelCanNotBeNull();
        }

        if (id == null) {
            id = getCollectionNextID(edgeCollection);
        }

        MongoDBEdgeIterable edgeIt;
        MongoDBEdge edge;

        // Insert the new edge
        this.rawGraph.getCollection(edgeCollection)
                .insertOne(new Document(MongoDBConstants.FIELD_ID, id).append(MongoDBConstants.FIELD_LABEL, label)
                        .append(MongoDBConstants.FIELD_OUTV, new DBRef(vertexCollection, outVertex.getId()))
                        .append(MongoDBConstants.FIELD_INV, new DBRef(vertexCollection, inVertex.getId())));

        // Fetch the newly created edge
        edgeIt = new MongoDBEdgeIterable(
                this.rawGraph.getCollection(edgeCollection).find(new Document(MongoDBConstants.FIELD_ID, id)),
                this);

        try {
            edge = (MongoDBEdge) edgeIt.iterator().next();
        } catch (NoSuchElementException nsee) {
            logger.warn("Newly created edge could not be fetched. The error message: " + nsee.getMessage());
            edge = null;
        }

        return edge;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.tinkerpop.blueprints.Graph#getEdge(java.lang.Object)
     */
    @Override
    public Edge getEdge(Object id) {
        // TODO Auto-generated method stub
        return null;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.tinkerpop.blueprints.Graph#removeEdge(com.tinkerpop.blueprints.Edge)
     */
    @Override
    public void removeEdge(Edge edge) {
        // TODO Auto-generated method stub

    }

    /*
     * (non-Javadoc)
     * 
     * @see com.tinkerpop.blueprints.Graph#getEdges()
     */
    @Override
    public Iterable<Edge> getEdges() {
        // TODO Auto-generated method stub
        return null;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.tinkerpop.blueprints.Graph#getEdges(java.lang.String,
     * java.lang.Object)
     */
    @Override
    public Iterable<Edge> getEdges(String key, Object value) {
        // TODO Auto-generated method stub
        return null;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.tinkerpop.blueprints.Graph#query()
     */
    @Override
    public GraphQuery query() {
        // TODO Auto-generated method stub
        return null;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.tinkerpop.blueprints.Graph#shutdown()
     */
    @Override
    public void shutdown() {
        mongoClient.close();
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.tinkerpop.blueprints.KeyIndexableGraph#dropKeyIndex(java.lang.String,
     * java.lang.Class)
     */
    @Override
    public <T extends Element> void dropKeyIndex(String key, Class<T> elementClass) {
        // TODO Auto-generated method stub

    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.tinkerpop.blueprints.KeyIndexableGraph#createKeyIndex(java.lang.String
     * , java.lang.Class, com.tinkerpop.blueprints.Parameter[])
     */
    @Override
    public <T extends Element> void createKeyIndex(String key, Class<T> elementClass,
            Parameter... indexParameters) {
        // TODO Auto-generated method stub

    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.tinkerpop.blueprints.KeyIndexableGraph#getIndexedKeys(java.lang.Class
     * )
     */
    @Override
    public <T extends Element> Set<String> getIndexedKeys(Class<T> elementClass) {
        // TODO Auto-generated method stub
        return null;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.tinkerpop.blueprints.MetaGraph#getRawGraph()
     */
    @Override
    public MongoDatabase getRawGraph() {
        return this.rawGraph;
    }

    /**
     * @return the edge collection
     */
    public MongoCollection<Document> getEdgeCollection() {
        return this.rawGraph.getCollection(edgeCollection);
    }

    /**
     * @return the vertex collection
     */
    public MongoCollection<Document> getVertexCollection() {
        return this.rawGraph.getCollection(vertexCollection);
    }

    /**
     * Gets the next avaliable id {@link MongoDBConstants#FIELD_ID} in a given
     * collection.
     * 
     * @param collectionName
     * @return Integer
     */
    public Integer getCollectionNextID(String collectionName) {
        Integer lastId = null;

        try {
            lastId = (Integer) this.rawGraph.getCollection(collectionName).find()
                    .sort(new Document(MongoDBConstants.FIELD_ID, new Integer(-1))).iterator().next()
                    .get(MongoDBConstants.FIELD_ID);
            return Integer.valueOf(lastId.intValue() + 1);
        } catch (NoSuchElementException nsee) {
            lastId = Integer.valueOf(1);
        }

        return lastId;
    }
}