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

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

There is a newer version: 0.21.0
Show newest version
package org.apache.tinkerpop.gremlin.ogm.paths.relationships

import org.apache.tinkerpop.gremlin.ogm.elements.Vertex

/**
 * A [Relationship] defines a path between two vertices that does not travel through any other vertices.
 * Each [Relationship] must be registered with a GraphMapper.
 */
interface Relationship : Connection {

    /**
     * Relationships may be asymmetric, meaning if vertex A relates to vertex B, that
     * does not imply B relates to A. Thus, a relationship name and two vertices is not
     * enough to represent the full semantics of a [Relationship], we also need [Direction]
     * to specify the origin and target of an asymmetric relationship.
     */
    enum class Direction {
        FORWARD,
        BACKWARD;

        val inverse: Direction
            get() = when (this) {
                FORWARD -> BACKWARD
                BACKWARD -> FORWARD
            }
    }

    /**
     * The name of the [Relationship] that will be stored to the graph. [Relationship.name]s
     * must be globally unique.
     */
    val name: String

    /**
     * The [Direction] of the [Relationship], or null if the [Relationship] is [Symmetric]
     */
    val direction: Direction?

    override fun relationships() = listOf(this)

    override val inverse: Relationship

    data class SymmetricSingleToSingle(
            override val name: String
    ) : SingleToSingle, Symmetric {

        override val inverse: SymmetricSingleToSingle get() = this
    }

    data class SymmetricOptionalToOptional(
            override val name: String
    ) : OptionalToOptional, Symmetric {

        override val inverse: SymmetricOptionalToOptional get() = this
    }

    data class SymmetricManyToMany(
            override val name: String
    ) : ManyToMany, Symmetric {

        override val inverse: SymmetricManyToMany get() = this
    }

    data class AsymmetricOptionalToOptional(
            override val name: String,
            override val direction: Direction = Direction.FORWARD
    ) : OptionalToOptional {

        override val inverse: AsymmetricOptionalToOptional
            get() = AsymmetricOptionalToOptional(
                    name = name,
                    direction = direction.inverse)
    }

    data class AsymmetricOptionalToSingle(
            override val name: String,
            override val direction: Direction = Direction.FORWARD
    ) : OptionalToSingle {

        override val inverse: AsymmetricSingleToOptional
            get() = AsymmetricSingleToOptional(
                    name = name,
                    direction = direction.inverse)
    }

    data class AsymmetricSingleToOptional(
            override val name: String,
            override val direction: Direction = Direction.FORWARD
    ) : SingleToOptional {

        override val inverse: AsymmetricOptionalToSingle
            get() = AsymmetricOptionalToSingle(
                    name = name,
                    direction = direction.inverse)
    }

    data class AsymmetricSingleToSingle(
            override val name: String,
            override val direction: Direction = Direction.FORWARD
    ) : SingleToSingle {

        override val inverse: AsymmetricSingleToSingle
            get() = AsymmetricSingleToSingle(
                    name = name,
                    direction = direction.inverse)
    }

    data class AsymmetricSingleToMany(
            override val name: String
    ) : SingleToMany, AsymmetricOneToMany {

        override val inverse: AsymmetricManyToSingle
            get() = AsymmetricManyToSingle(
                    name = name)
    }

    data class AsymmetricOptionalToMany(
            override val name: String
    ) :  OptionalToMany, AsymmetricOneToMany {

        override val inverse: AsymmetricManyToOptional
            get() = AsymmetricManyToOptional(
                    name = name)
    }

    /**
     * We restrict creating ManyToOne relationships by clients to prevent creation of a
     * ManyToOne relationship that is equivalent to meaning to an already defined OneToMany
     * relationship, but using a different name. To get a ManyToOne relationship, define it
     * as its OneToMany equivalent then get its inverse.
     */
    data class AsymmetricManyToOptional internal constructor(
            override val name: String
    ) : ManyToOptional, AsymmetricManyToOne {

        override val inverse: AsymmetricOptionalToMany
            get() = AsymmetricOptionalToMany(
                    name = name)
    }

    /**
     * We restrict creating ManyToOne relationships by clients to prevent creation of a
     * ManyToOne relationship that is equivalent to meaning to an already defined OneToMany
     * relationship, but using a different name. To get a ManyToOne relationship, define it
     * as its OneToMany equivalent then get its inverse.
     */
    data class AsymmetricManyToSingle internal constructor(
            override val name: String
    ) : ManyToSingle, AsymmetricManyToOne {

        override val inverse: AsymmetricSingleToMany
            get() = AsymmetricSingleToMany(
                    name = name)
    }

    data class AsymmetricManyToMany(
            override val name: String,
            override val direction: Direction = Direction.FORWARD
    ) : ManyToMany {

        override val inverse: AsymmetricManyToMany
            get() = AsymmetricManyToMany(
                    name = name,
                    direction = direction.inverse)
    }

    interface FromOne : Relationship, Connection.FromOne {

        override val inverse: ToOne
    }

    interface FromOptional : FromOne, Connection.FromOptional {

        override val inverse: ToOptional
    }

    interface FromSingle : FromOne, Connection.FromSingle {

        override val inverse: ToSingle
    }

    interface FromMany : Relationship, Connection.FromMany {

        override val inverse: ToMany
    }

    interface ToOne : Relationship, Connection.ToOne {

        override val inverse: FromOne
    }

    interface ToOptional : ToOne, Connection.ToOptional {

        override val inverse: FromOptional
    }

    interface ToSingle : ToOne, Connection.ToSingle {

        override val inverse: FromSingle
    }

    interface ToMany : Relationship, Connection.ToMany {

        override val inverse: FromMany
    }

    interface OneToOne : FromOne, ToOne, Connection.OneToOne {

        override val inverse: OneToOne
    }

    interface OneToOptional : OneToOne, ToOptional, Connection.OneToOptional {

        override val inverse: OptionalToOne
    }

    interface OneToSingle : OneToOne, ToSingle, Connection.OneToSingle {

        override val inverse: SingleToOne
    }

    interface OptionalToOne : FromOptional, OneToOne, Connection.OptionalToOne {

        override val inverse: OneToOptional
    }

    interface SingleToOne : FromSingle, OneToOne, Connection.SingleToOne {

        override val inverse: OneToSingle
    }

    interface OneToMany : FromOne, ToMany, Connection.OneToMany {

        override val inverse: ManyToOne
    }

    interface ManyToOne : FromMany, ToOne, Connection.ManyToOne {

        override val inverse: OneToMany
    }

    interface OptionalToOptional : OptionalToOne, OneToOptional, Connection.OptionalToOptional {

        override val inverse: OptionalToOptional
    }

    interface OptionalToSingle : OptionalToOne, OneToSingle, Connection.OptionalToSingle {

        override val inverse: SingleToOptional
    }

    interface SingleToOptional : SingleToOne, OneToOptional, Connection.SingleToOptional {

        override val inverse: OptionalToSingle
    }

    interface SingleToSingle : SingleToOne, OneToSingle, Connection.SingleToSingle {

        override val inverse: SingleToSingle
    }

    interface OptionalToMany : FromOptional, OneToMany, Connection.OptionalToMany {

        override val inverse: ManyToOptional
    }

    interface SingleToMany : FromSingle, OneToMany, Connection.SingleToMany {

        override val inverse: ManyToSingle
    }

    interface ManyToOptional : ManyToOne, ToOptional, Connection.ManyToOptional {

        override val inverse: OptionalToMany
    }

    interface ManyToSingle : ManyToOne, ToSingle, Connection.ManyToSingle {

        override val inverse: SingleToMany
    }

    interface ManyToMany : FromMany, ToMany, Connection.ManyToMany {

        override val inverse: ManyToMany
    }

    interface Symmetric : Relationship {

        override val direction: Direction? get() = null
    }

    interface AsymmetricManyToOne : ManyToOne {

        override val direction: Direction? get() = Direction.BACKWARD
    }

    interface AsymmetricOneToMany : OneToMany {

        override val direction: Direction? get() = Direction.FORWARD
    }

    companion object {

        /**
         * Creates a [Relationship] that is uni-directional. When traversed from a 'FROM' object,
         * there will be 0 or 1 'TO' objects. When the [inverse] is traversed from a 'TO' object,
         * there will be 0 or 1 'FROM' objects.
         */
        inline fun  asymmetricOptionalToOptional(
                name: String,
                direction: Direction = Direction.FORWARD
        ) = AsymmetricOptionalToOptional(
                name = name,
                direction = direction)

        /**
         * Creates a [Relationship] that is uni-directional. When traversed from a 'FROM' object,
         * there will be exactly 1 'TO' objects. When the [inverse] is traversed from a 'TO' object,
         * there will be 0 or 1 'FROM' objects.
         */
        inline fun  asymmetricOptionalToSingle(
                name: String,
                direction: Direction = Direction.FORWARD
        ) = AsymmetricOptionalToSingle(
                name = name,
                direction = direction)

        /**
         * Creates a [Relationship] that is uni-directional. When traversed from a 'FROM' object,
         * there will be 0 or 1 'TO' objects. When the [inverse] is traversed from a 'TO' object,
         * there will be exactly 1 'FROM' object.
         */
        inline fun  asymmetricSingleToOptional(
                name: String,
                direction: Direction = Direction.FORWARD
        ) = AsymmetricSingleToOptional(
                name = name,
                direction = direction)

        /**
         * Creates a [Relationship] that is uni-directional. When traversed from a 'FROM' object,
         * there will be exactly 1 'TO' object. When the [inverse] is traversed from a 'TO' object,
         * there will be exactly 1 'FROM' object.
         */
        inline fun  asymmetricSingleToSingle(
                name: String,
                direction: Direction = Direction.FORWARD
        ) = AsymmetricSingleToSingle(
                name = name,
                direction = direction)

        /**
         * Creates a [Relationship] that is uni-directional. When traversed from a 'FROM' object,
         * there will be exactly 1 'TO' object. When the [inverse] is traversed from a 'TO' object,
         * there will be exactly 1 'FROM' object.
         */
        inline fun  asymmetricSingleToMany(
                name: String
        ) = AsymmetricSingleToMany(
                name = name)

        /**
         * Creates a [Relationship] that is uni-directional. When traversed from a 'FROM' object,
         * there will be 0 or more 'TO' objects. When the [inverse] is traversed from a 'TO' object,
         * there will be 0 or 1 'FROM' object.
         */
        inline fun  asymmetricOptionalToMany(
                name: String
        ) = AsymmetricOptionalToMany(
                name = name)

        /**
         * Creates a [Relationship] that is uni-directional. When traversed from a 'FROM' object,
         * there will be 0 or more 'TO' objects. When the [inverse] is traversed from a 'TO' object,
         * there will be 0 or more 'FROM' objects.
         */
        inline fun  asymmetricManyToMany(
                name: String,
                direction: Direction = Direction.FORWARD
        ) = AsymmetricManyToMany(
                name = name,
                direction = direction)

        /**
         * Creates a [Relationship] that is bi-directional. When traversed from a 'FROM' object,
         * there will be 0 or 1 'TO' objects. When the [inverse] is traversed from a 'TO' object,
         * there will be 0 or 1 'FROM' objects.
         */
        inline fun  symmetricOptionalToOptional(
                name: String
        ) = SymmetricOptionalToOptional(
                name = name)

        /**
         * Creates a [Relationship] that is bi-directional. When traversed from a 'FROM' object,
         * there will be exactly 1 'TO' object. When the [inverse] is traversed from a 'TO' object,
         * there will be exactly 1 'FROM' object.
         */
        inline fun  symmetricSingleToSingle(
                name: String
        ) = SymmetricSingleToSingle(
                name = name)

        /**
         * Creates a [Relationship] that is bi-directional. When traversed from a 'FROM' object,
         * there will be 0 or more 'TO' objects. When the [inverse] is traversed from a 'TO' object,
         * there will be 0 or more 'FROM' objects.
         */
        inline fun  symmetricManyToMany(
                name: String
        ) = SymmetricManyToMany(
                name = name)
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy