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

.circumflex-core.2.3.source-code.model.scala Maven / Gradle / Ivy

package ru.circumflex
package core

/*!# Data model support

To make Circumflex components independent from various view technologies
we introduce some basic interfaces here. Different components implement
these interfaces while view technologies should provide proper support
for them.
*/
trait Wrapper[T] {
  def item: T
}

/*!# Containers

Containers are generic data-carrier units. They wrap mutable variable
with common functionality like setters, accessors, mutators and metadata.
`ValueHolder` of Circumflex ORM uses container functionality, see its
docs for more information.

By convention containers should be tested for equality by their external
attributes (like name, identifier, etc.), **but not their internal value**.
Implementations should provide sensible `canEqual`, `equal` and `hashCode`
methods, but internal value should not be taken into consideration.
*/
trait Container[T] {
  protected var _value: Option[T] = None

  /*!## Setters

  Setters provide a handy mechanism for preprocessing values before
  setting them. They are functions `T => T` which are applied one-by-one
  each time you set new non-null value.
  */
  protected var _setters: Seq[T => T] = Nil
  def setters: Seq[T => T] = _setters
  def addSetter(f: T => T): this.type = {
    _setters ++= List(f)
    this
  }

  /*!## Accessing & Setting Values

  Values are stored internally as `Option[T]`. `None` stands both for
  uninitialized and `null` values.
  */
  def value: Option[T] = _value
  def get = value
  def apply(): T = value.get
  def getOrElse(default: => T): T = value.getOrElse(default)
  def isEmpty: Boolean = value == None

  def set(v: Option[T]): this.type = {
    _value = v.map { v =>
      setters.foldLeft(v) { (v, f) => f(v) }
    }
    this
  }
  def set(v: T): this.type = set(any2option(v))
  def setNull(): this.type = set(None)
  def :=(v: T) = set(v)

  /*!## Methods from `Option`

  Since `ValueHolder` is just a wrapper around `Option`, we provide
  some methods to work with your values in functional style
  (they delegate to their equivalents in `Option`).
  */
  def map[B](f: T => B): Option[B] =
    value.map(f)
  def flatMap[B](f: T => Option[B]): Option[B] =
    value.flatMap(f)
  def orElse[B >: T](alternative: => Option[B]): Option[B] =
    value.orElse(alternative)

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy