--[[ Copyright (c) 2012-2015 Kaarle Ritvanen See LICENSE file for license details --]] local M = {} local model = require('aconf.model.model') local node = require('aconf.model.node') local object = require('aconf.object') local pth = require('aconf.path') local address = require('aconf.path.address') local util = require('aconf.util') local setdefault = util.setdefault M.RootModel = model.new() function M.RootModel:init(context) object.super(self, M.RootModel):init( util.update(context, {path='/', addr='/null'}) ) 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 = address.split(addr) end local function defaults(top) return util.setdefaults(top, {members={}, paths={}, referrers={}}) end while #addr > 0 do local comp = address.escape(addr[1]) if create then top = setdefault(defaults(top).members, comp, {order=order}) order = order + 1 else top = top.members[comp] or top.members['*'] 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) 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(pth.rawjoin(scope, record.search), true).referrers, record.path ) end end end return M