All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.tinkerpop.gremlin.console.plugin.GephiRemoteAcceptor.groovy Maven / Gradle / Ivy

package com.tinkerpop.gremlin.console.plugin

import com.tinkerpop.gremlin.groovy.plugin.RemoteAcceptor
import com.tinkerpop.gremlin.structure.Edge
import com.tinkerpop.gremlin.structure.Graph
import com.tinkerpop.gremlin.structure.Vertex
import groovy.json.JsonSlurper
import groovyx.net.http.HTTPBuilder
import org.codehaus.groovy.tools.shell.Groovysh
import org.codehaus.groovy.tools.shell.IO

import static groovyx.net.http.ContentType.JSON

/**
 * @author Stephen Mallette (http://stephen.genoprime.com)
 */
class GephiRemoteAcceptor implements RemoteAcceptor {

    private String host = "localhost"
    private int port = 8080
    private String workspace = "workspace0"

    private final Groovysh shell
    private final IO io

    public GephiRemoteAcceptor(final Groovysh shell, final IO io) {
        this.shell = shell
        this.io = io
    }

    @Override
    Object connect(final List args) {
        if (args.size() >= 1)
            workspace = args[0]

        if (args.size() >= 2)
            host = args[1]

        if (args.size() >= 3) {
            try {
                port = Integer.parseInt(args[2])
            } catch (Exception ex) {
                return "port must be an integer value"
            }
        }

        return "connection to Gephi - http://$host:$port/$workspace"
    }

    @Override
    Object configure(final List args) {
        if (args.size() != 2)
            return "expects [host |port |workspace ]"

        if (args[0] == "host")
            host = args[1]
        else if (args[0] == "port") {
            try {
                port = Integer.parseInt(args[1])
            } catch (Exception ex) {
                return "port must be an integer value"
            }
        } else if (args[0] == "workspace")
            workspace = args[1]
        else
            return "expects [host |port |workspace ]"

        return "connection to Gephi - http://$host:$port/$workspace"
    }

    @Override
    Object submit(final List args) {
        final String line = String.join(" ", args)
        final Object o = shell.execute(line)
        if (o instanceof Graph) {
            clearGraph()
            def g = (Graph) o
            g.V().sideEffect { addVertexToGephi(it.instance()) }.iterate()
        }
    }

    @Override
    void close() throws IOException {

    }

    def addVertexToGephi(def Vertex v, def boolean ignoreEdges = false) {
        def props = v.values()
        props.put('label', v.label())

        // only add if it does not exist in graph already
        if (!getFromGephiGraph([operation: "getNode", id: v.id().toString()]).isPresent())
            updateGephiGraph([an: [(v.id().toString()): props]])

        if (!ignoreEdges) {
            v.outE().sideEffect {
                addEdgeToGephi(it.instance())
            }.iterate()
        }
    }

    def addEdgeToGephi(def Edge e) {
        def props = e.values()
        props.put('label', e.label())
        props.put('source', e.outV().id().next().toString())
        props.put('target', e.inV().id().next().toString())
        props.put('directed', true)

        // make sure the in vertex is there but don't add its edges - that will happen later as we are looping
        // all vertices in the graph
        addVertexToGephi(e.inV().next(), true)

        // both vertices are definitely there now, so add the edge
        updateGephiGraph([ae: [(e.id().toString()): props]])
    }

    def clearGraph() {
        updateGephiGraph([dn: [filter: "ALL"]])
    }

    def getFromGephiGraph(def Map queryArgs) {
        def http = new HTTPBuilder("http://$host:$port/")
        def resp = http.get(path: "/$workspace", query: queryArgs).getText()

        // gephi streaming plugin does not set the content type or respect the Accept header - treat as text
        if (resp.isEmpty())
            return Optional.empty()
        else
            return Optional.of(new JsonSlurper().parseText(resp))
    }

    def updateGephiGraph(def Map postBody) {
        def http = new HTTPBuilder("http://$host:$port/")
        http.post(path: "/$workspace", requestContentType: JSON, body: postBody, query: [format: "JSON", operation: "updateGraph"])
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy