Delegation

This is an example of delegation in ocaps.

Delegation is probably the easiest thing in capabiities to understand, as you’re passing a reference to another object, either by passing it as a parameter, or through direct assignment.

Note that assigning a capability to a singleton object or to a thread local is not delegation, as you are exposing the capability globally rather than to a specific target.

Delegation is often combined with revocation, so that the delegated access to the capability can be revoked as necessary.

You can read Managing Capabilities in the guide for more information.

sourceimport ocaps._
import scala.util._

object Delegation {
  import Foo._

  final class Foo(private var name: String) {
    private def doTheThing() = {
      println(s"$name.doTheThing()")
    }

    private object capabilities {
      val doer: Doer = new Doer {
        override def doTheThing(): Unit = Foo.this.doTheThing()
      }
    }
  }

  object Foo {

    trait Doer {
      def doTheThing(): Unit
    }

    class Access private {
      def doer(foo: Foo): Doer = foo.capabilities.doer
    }

    object Access {
      def apply(): Access = new Access
    }
  }

  class User(name: String) {
    def setDoer(doer: Doer) = {
      maybeUser = Option(doer)
    }

    def delegateDoer(otherUser: User): Unit = {
      maybeUser.foreach { myDoer =>
        otherUser.setDoer(myDoer)
      }
    }

    private var maybeUser: Option[Doer] = None

    def doTheThing() = {
      try {
        maybeUser.foreach(_.doTheThing())
      } catch {
        case e: RevokedException =>
          e.printStackTrace()
      }
    }
  }

  def main(args: Array[String]): Unit = {
    val access = Foo.Access()

    val foo = new Foo("foo")
    val doer = access.doer(foo)

    val alice = new User("alice")
    alice.setDoer(doer)
    val bob = new User("alice")
    alice.delegateDoer(bob)

    println(s"bob doing the thing through delegation:")
    val result = Try(bob.doTheThing())
    println(s"bob result: $result")
  }
}
The source code for this page can be found here.