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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
--[[
Copyright (c) 2012-2013 Kaarle Ritvanen
See LICENSE file for license details
--]]
local M = {}
local model = require('acf.model.model')
local node = require('acf.model.node')
local object = require('acf.object')
local pth = require('acf.path')
local util = require('acf.util')
local setdefault = util.setdefault
M.RootModel = model.new()
function M.RootModel:init(txn)
object.super(self, M.RootModel):init{txn=txn, path='/', addr='/null/root'}
end
function M.RootModel:has_permission(user, permission)
return permission == 'read'
end
function M.RootModel:meta(path)
local obj = self:fetch(path, true)
if object.isinstance(obj, node.TreeNode) then return node.meta(obj) end
return node.mmeta(self:fetch(pth.parent(path), true), pth.name(path))
end
local _topology = {}
local order = 0
function M.topology(addr, create)
local top = _topology
if type(addr) == 'table' then addr = util.copy(addr)
else addr = pth.split(addr) end
local function defaults(top)
return util.setdefaults(top, {members={}, paths={}, referrers={}})
end
while #addr > 0 do
if create then
top = setdefault(defaults(top).members, addr[1], {})
else
top = top.members[addr[1]] or top.members[pth.wildcard]
if not top then return end
end
table.remove(addr, 1)
end
return defaults(top)
end
function M.register(name, field, params)
if not params then params = {} end
params.create = true
M.RootModel[name] = model.to_field(field, params)
local root = M.RootModel()
for _, record in ipairs(node.topology(root:fetch(name))) do
local top = M.topology(record.addr, true)
setdefault(top, 'order', order)
order = order + 1
local function set(k, v)
setdefault(top, k, v)
assert(top[k] == v)
end
set('type', record.type)
table.insert(top.paths, record.path)
if record.scope then
local scope = node.addr(
root:fetch(pth.to_absolute(record.scope, pth.parent(record.path)))
)
set('scope', scope)
table.insert(M.topology(scope, true).referrers, record.path)
end
end
end
return M
|