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

org.apache.tinkerpop.gremlin.ogm.paths.relationships.Connection.kt Maven / Gradle / Ivy

There is a newer version: 0.21.0
Show newest version
@file:Suppress("UNCHECKED_CAST")

package org.apache.tinkerpop.gremlin.ogm.paths.relationships

import org.apache.tinkerpop.gremlin.ogm.elements.Vertex
import org.apache.tinkerpop.gremlin.ogm.exceptions.MissingEdge
import org.apache.tinkerpop.gremlin.ogm.paths.Path
import org.apache.tinkerpop.gremlin.ogm.paths.steps.StepTraverser
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal


/**
 * A path through the graph starting and ending at a vertex, which spans one or more relationships.
 * A special property of Connections is that they can be reversed.
 */
interface Connection : Path {

    /**
     * This Connection to reverse.
     */
    val inverse: Connection

    /**
     * The individual [Relationship]s that create this connection
     */
    fun relationships(): List>

    override fun path() = listOf(this)

    override fun invoke(from: StepTraverser): GraphTraversal<*, TO> {
        val serialized = from.traversal.map { fromObject ->
            from.graphMapper.serializeV(fromObject.get())
        }
        val traversed = relationships().fold(initial = serialized) { traversal, relationship ->
            if (relationship is Relationship.ToSingle) {
                traversal.coalesce(traversalTo(relationship), throwMissingEdge(relationship))
            } else {
                traversal.to(relationship)
            }
        }
        return traversed.map { toVertex -> from.graphMapper.deserializeV(toVertex.get()) }
    }

    interface FromOne : Connection {

        override val inverse: ToOne
    }

    interface FromOptional : FromOne {

        override val inverse: ToOptional
    }

    interface FromSingle : FromOne {

        override val inverse: ToSingle
    }

    interface FromMany : Connection {

        override val inverse: ToMany
    }

    interface ToOne : Connection, Path.ToOne {

        override val inverse: FromOne
    }

    interface ToOptional : ToOne, Path.ToOptional {

        override val inverse: FromOptional
    }

    interface ToSingle : ToOne, Path.ToSingle {

        override val inverse: FromSingle
    }

    interface ToMany : Connection, Path.ToMany {

        override val inverse: FromMany
    }

    interface OneToOne : FromOne, ToOne {

        override val inverse: OneToOne
    }

    interface OneToOptional : OneToOne, ToOptional {

        override val inverse: OptionalToOne
    }

    interface OneToSingle : OneToOne, ToSingle {

        override val inverse: SingleToOne
    }

    interface OptionalToOne : FromOptional, OneToOne {

        override val inverse: OneToOptional
    }

    interface SingleToOne : FromSingle, OneToOne {

        override val inverse: OneToSingle
    }

    interface OneToMany : FromOne, ToMany {

        override val inverse: ManyToOne
    }

    interface ManyToOne : FromMany, ToOne {

        override val inverse: OneToMany
    }

    interface OptionalToOptional : OptionalToOne, OneToOptional {

        override val inverse: OptionalToOptional
    }

    interface OptionalToSingle : OptionalToOne, OneToSingle {

        override val inverse: SingleToOptional
    }

    interface SingleToOptional : SingleToOne, OneToOptional {

        override val inverse: OptionalToSingle
    }

    interface SingleToSingle : SingleToOne, OneToSingle {

        override val inverse: SingleToSingle
    }

    interface OptionalToMany : FromOptional, OneToMany {

        override val inverse: ManyToOptional
    }

    interface SingleToMany : FromSingle, OneToMany {

        override val inverse: ManyToSingle
    }

    interface ManyToOptional : ManyToOne, ToOptional {

        override val inverse: OptionalToMany
    }

    interface ManyToSingle : ManyToOne, ToSingle {

        override val inverse: SingleToMany
    }

    interface ManyToMany : FromMany, ToMany {

        override val inverse: ManyToMany
    }

    companion object {

        private fun throwMissingEdge(relationship: Relationship<*, *>): GraphTraversal<*, org.apache.tinkerpop.gremlin.structure.Vertex> =
            DefaultGraphTraversal().map {
                throw MissingEdge(it.get(), relationship.name)
            } as GraphTraversal

        private fun traversalTo(relationship: Relationship<*, *>): GraphTraversal<*, org.apache.tinkerpop.gremlin.structure.Vertex> =
                DefaultGraphTraversal().to(relationship)

        private fun GraphTraversal<*, org.apache.tinkerpop.gremlin.structure.Vertex>.to(relationship: Relationship<*, *>) =
                when (relationship.direction) {
                    Relationship.Direction.FORWARD -> out(relationship.name)
                    Relationship.Direction.BACKWARD -> `in`(relationship.name)
                    null -> both(relationship.name)
                }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy