org.apache.tinkerpop.gremlin.ogm.paths.relationships.Connection.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kotlin-gremlin-ogm Show documentation
Show all versions of kotlin-gremlin-ogm Show documentation
The Object Graph Mapping Library for Kotlin and Gremlin
@file:Suppress("UNCHECKED_CAST")
package org.apache.tinkerpop.gremlin.ogm.paths.relationships
import org.apache.tinkerpop.gremlin.ogm.GraphVertex
import org.apache.tinkerpop.gremlin.ogm.elements.Vertex
import org.apache.tinkerpop.gremlin.ogm.exceptions.MissingEdge
import org.apache.tinkerpop.gremlin.ogm.exceptions.ObjectNotSaved
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 ->
val id = from.graphMapper.vertexID(fromObject.get()) ?: throw ObjectNotSaved(fromObject.get())
from.graphMapper.traversal.V(id).next()
}
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.deserialize(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<*, GraphVertex> =
DefaultGraphTraversal().map {
throw MissingEdge(it.get(), relationship.name)
} as GraphTraversal
private fun traversalTo(relationship: Relationship<*, *>): GraphTraversal<*, GraphVertex> =
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