1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
# -*- coding: utf-8 -*-
module Plugin::Intent
class IntentToken < Diva::Model
field.uri :uri, required: true
field.has :model, Diva::Model
field.has :intent, Plugin::Intent::Intent, required: true
field.has :parent, Plugin::Intent::IntentToken
# 引数の情報からIntentTokenを作成し、それを開く
def self.open(*args)
self.new(*args).open
end
def initialize(*rest)
super
self[:source] = self[:model]
end
# 設定された情報を使ってURI又はModelを開く
def open
if model?
Plugin.call(:open, self)
else
Deferred.new{
Diva.Model(intent.model_slug).find_by_uri(uri)
}.next{|m|
Delayer::Deferred.fail("#{intent.model_slug}(#{uri}) does not exists.") unless m
self.model = m
Plugin.call(:open, self)
}.trap{|err|
error err
forward
}
end
self
end
def forward
Plugin.call(:intent_forward, self)
end
# _self_ から親のIntentTokenを再帰的に遡って、そのIntentTokenを引数に繰り返すEnumeratorを返す。
# ==== Return
# [Enumerator] IntentTokenを列挙する
def ancestors
Enumerator.new do |yielder|
cur = self
loop do
break unless cur
yielder << cur
cur = cur.parent
end
end
end
# ancestorsと同じようなもの。ただし、IntentToken#intentに関して繰り返す。
# ==== Return
# [Enumerator] Intentを列挙する
def intent_ancestors
ancestors.lazy.map(&:intent)
end
end
end
|