diff options
author | Kaarle Ritvanen <kaarle.ritvanen@datakunkku.fi> | 2013-03-20 12:11:52 +0200 |
---|---|---|
committer | Kaarle Ritvanen <kaarle.ritvanen@datakunkku.fi> | 2013-03-25 12:48:07 +0200 |
commit | 0c7832085ca024f848c1fb4074d8783c1226dfde (patch) | |
tree | 6f71ae56daa97a044819b6650f97ce5e8144748b /acf/model/init.lua | |
parent | b14a24ff75864f0d4a6eed10effd3276df5147bd (diff) | |
download | aconf-0c7832085ca024f848c1fb4074d8783c1226dfde.tar.bz2 aconf-0c7832085ca024f848c1fb4074d8783c1226dfde.tar.xz |
refactor the way context is passed to Field and Collection objects
Diffstat (limited to 'acf/model/init.lua')
-rw-r--r-- | acf/model/init.lua | 103 |
1 files changed, 52 insertions, 51 deletions
diff --git a/acf/model/init.lua b/acf/model/init.lua index 44b1f5e..6b1fd64 100644 --- a/acf/model/init.lua +++ b/acf/model/init.lua @@ -36,9 +36,9 @@ require 'stringy' local Primitive = class(Field) -function Primitive:validate(txn, path, value) +function Primitive:validate(context, value) local t = self.dtype - if type(value) ~= t then raise(path, 'Not a '..t) end + if type(value) ~= t then raise(context.path, 'Not a '..t) end end @@ -49,15 +49,15 @@ function String:init(params) self.dtype = 'string' end -function String:validate(txn, path, value) - super(self, String):validate(txn, path, value) +function String:validate(context, value) + super(self, String):validate(context, value) if self['max-length'] and string.len(value) > self['max-length'] then - raise(path, 'Maximum length exceeded') + raise(context.path, 'Maximum length exceeded') end end -function String:meta(txn, path, addr) - local res = super(self, String):meta(txn, path, addr) +function String:meta(context) + local res = super(self, String):meta(context) res['max-length'] = self['max-length'] return res end @@ -70,10 +70,9 @@ function Number:init(params) self.dtype = 'number' end -function Number:_validate(txn, path, value) +function Number:_validate(context, value) return super(self, Number):_validate( - txn, - path, + context, value and tonumber(value) or value ) end @@ -81,9 +80,9 @@ end Integer = class(Number) -function Integer:validate(txn, path, value) - super(self, Integer):validate(txn, path, value) - if math.floor(value) ~= value then raise(path, 'Not an integer') end +function Integer:validate(context, value) + super(self, Integer):validate(context, value) + if math.floor(value) ~= value then raise(context.path, 'Not an integer') end end @@ -103,12 +102,10 @@ function Range:init(params) if not self.type then self.type = Integer end end -function Range:validate(txn, path, value) +function Range:validate(context, value) local comps = stringy.split(value, '-') - if #comps > 2 then raise(path, 'Invalid range') end - for _, v in ipairs(comps) do - to_field(self.type):_validate(txn, path, v) - end + if #comps > 2 then raise(context.path, 'Invalid range') end + for _, v in ipairs(comps) do to_field(self.type):_validate(context, v) end end @@ -120,16 +117,17 @@ function Reference:init(params) if not self.scope then self.scope = '/' end end -function Reference:abs_scope(path) - return pth.to_absolute(self.scope, pth.parent(path)) +function Reference:abs_scope(context) + return pth.to_absolute(self.scope, node.path(context.parent)) end -function Reference:meta(txn, path, addr) - local res = super(self, Reference):meta(txn, path, addr) - res.scope = self:abs_scope(path) +function Reference:meta(context) + local res = super(self, Reference):meta(context) + res.scope = self:abs_scope(context) + local txn = context.txn local objs = txn:get( - getmetatable(relabel('system', txn.search, txn, res.scope)).addr + node.addr(relabel('system', txn.search, txn, res.scope)) ) or {} res.choice = map(function(p) return pth.join(res.scope, p) end, objs) res['ui-choice'] = objs @@ -137,25 +135,26 @@ function Reference:meta(txn, path, addr) return res end -function Reference:follow(txn, path, value) - return txn:search(pth.join(self:abs_scope(path), value)) +function Reference:follow(context, value) + return context.txn:search(pth.join(self:abs_scope(context), value)) end -function Reference:load(txn, path, addr) - local ref = super(self, Reference):load(txn, path, addr) - return ref and self:follow(txn, path, ref) or nil +function Reference:load(context) + local ref = super(self, Reference):load(context) + return ref and self:follow(context, ref) or nil end -function Reference:_validate(txn, path, value) - super(self, Reference):_validate(txn, path, value) +function Reference:_validate(context, value) + super(self, Reference):_validate(context, value) if value == nil then return end - if object.isinstance(value, node.TreeNode) then - value = getmetatable(value).path - end - if value and pth.is_absolute(value) then - local scope = self:abs_scope(path) + if object.isinstance(value, node.TreeNode) then value = node.path(value) end + + local path = context.path + + if pth.is_absolute(value) then + local scope = self:abs_scope(context) local prefix = scope..'/' if not stringy.startswith(value, prefix) then raise(path, 'Reference out of scope ('..scope..')') @@ -169,7 +168,7 @@ function Reference:_validate(txn, path, value) end -- TODO check instance type - relabel(path, self.follow, self, txn, path, value) + relabel(path, self.follow, self, context, value) return value end @@ -188,9 +187,12 @@ function Collection:init(params, ctype) self.widget = self.dtype end -function Collection:load(txn, path, addr) +function Collection:load(context) -- automatically create missing collection (TODO: make this configurable?) - return self.ctype(txn, path, addr, to_field(self.type), self.required) + return self.ctype( + context, + {field=to_field(self.type), required=self.required} + ) end @@ -208,30 +210,29 @@ function Mixed:init() super(self, Mixed):init({type=Mixed}, node.Mixed) end -function Mixed:load(txn, path, addr) - local value = Primitive.load(self, txn, path, addr) - if type(value) == 'table' then - return super(self, Mixed):load(txn, path, addr) - end +function Mixed:load(context) + local value = Primitive.load(self, context) + if type(value) == 'table' then return super(self, Mixed):load(context) end return value end -function Mixed:save(txn, path, addr, value) - if type(value) == 'table' then - super(self, Mixed):save(txn, path, addr, value) - else Primitive.save(self, txn, path, addr, value) end +function Mixed:save(context, value) + if type(value) == 'table' then super(self, Mixed):save(context, value) + else Primitive.save(self, context, value) end end RootModel = new() -function RootModel:init(txn) super(self, RootModel):init(txn, '/') end +function RootModel:init(txn) super(self, RootModel):init{txn=txn, path='/'} end function register(name, path, field) local field = to_field(field) - function field:compute(txn, pth, addr) - return self:load(txn, '/'..name, path) + function field:compute(context) + context.path = '/'..name + context.addr = path + return self:load(context) end RootModel[name] = field end |