blob: 7d8f82ffa4a61634ba7c150c69cb5193f6056726 [file] [log] [blame]
--Copyright 2021 The casbin Authors. All Rights Reserved.
--
--Licensed under the Apache License, Version 2.0 (the "License");
--you may not use this file except in compliance with the License.
--You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
--Unless required by applicable law or agreed to in writing, software
--distributed under the License is distributed on an "AS IS" BASIS,
--WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--See the License for the specific language governing permissions and
--limitations under the License.
local Util = require("src/util/Util")
local Config = {
DEFAULT_SECTION = "default",
DEFAULT_COMMENT = "#",
DEFAULT_COMMENT_SEM = ";",
DEFAULT_MULTI_LINE_SEPARATOR = "\\\\", -- This is equivalent to "\\" in the text since "\" is a special character in Lua
}
--[[
* newConfig create an empty configuration representation from file.
*
* @param confName the path of the model file.
* @return the constructor of Config.
]]
function Config:newConfig(confName)
local c = {}
setmetatable(c,self)
self.__index = self
c.data = {}
c:parse(confName)
return c
end
--[[
* newConfigFromText create an empty configuration representation from text.
*
* @param text the model text.
* @return the constructor of Config.
]]
function Config:newConfigFromText(text)
local c = {}
setmetatable(c,self)
self.__index = self
c.data = {}
local lines = {}
string.gsub(text, '[^'.."\r\n"..']+', function(w) table.insert(lines, w) end )
c:parseBuffer(lines)
return c
end
-- addConfig adds a new section->key:value to the configuration.
function Config:addConfig(section, option, value)
if section == "" then section = self.DEFAULT_SECTION end
if self.data[section] == nil then
self.data[section] = {}
end
self.data[section][option] = value
end
function Config:parse(fname)
local lines = {}
local f = assert(io.open(fname,"r"))
if f then
for line in f:lines() do
table.insert(lines, line)
end
end
f:close()
self:parseBuffer(lines)
end
function Config:parseBuffer(lines)
local section = ""
local buf = {}
local lineNum = 0
local canWrite = false
local line
while true do
if canWrite then
if self:write(section, lineNum, buf) == true then
buf = {}
end
canWrite = false
end
lineNum = lineNum + 1
line = lines[lineNum]
if lineNum>#lines then
if #buf>0 then
self:write(section, lineNum, buf)
end
break
end
line = Util.trim(line)
if line == "" or self.DEFAULT_COMMENT == string.sub(line, 1, 1) or self.DEFAULT_COMMENT_SEM == string.sub(line, 1, 1) then
canWrite = true
elseif "[" == string.sub(line, 1, 1) and "]" == string.sub(line, -1, -1) then
if #buf>0 then
if self:write(section, lineNum, buf) == true then
buf = {}
end
end
section = string.sub(line, 2, -2)
else
local p
if self.DEFAULT_MULTI_LINE_SEPARATOR == string.sub(line, -2, -1) then
p = Util.trim(string.sub(line, 1, -3))
p = p .. " "
else
p = line
canWrite = true
end
table.insert(buf, p)
end
end
end
function Config:write(section, lineNum, b)
local buf = ""
for _, v in pairs(b) do
buf = buf .. v
end
if buf == "" then return end
local optionVal = Util.split(buf, "=", 1)
if #optionVal~=2 then
error("parse the content error : line "..lineNum.." , "..optionVal[1].." = ?")
end
local option = Util.trim(optionVal[1])
local value = Util.trim(optionVal[2])
self:addConfig(section, option, value)
return true
end
-- getBool lookups up the value using the provided key and converts the value to a bool
function Config:getBool(key)
local s = self:get(key)
if string.upper(s) == "TRUE" then
return true
elseif string.upper(s) == "FALSE" then
return false
else
error("Not a boolean value")
end
end
-- getNum lookups up the value using the provided key and converts the value to a number
function Config:getNum(key)
local s = self:get(key)
if tonumber(s) then
return tonumber(s)
else
error("Not a num value")
end
end
-- getString lookups up the value using the provided key and converts the value to a string
function Config:getString(key)
return self:get(key)
end
--[[
Strings lookups up the value using the provided key and converts the value to an array
of string by splitting the string by comma.
]]
function Config:getStrings(key)
local s = self:get(key)
if s == "" then return end
local v = Util.split(s, ",")
return v
end
-- Set sets the value for the specific key in the Config
function Config:set(key, value)
if #key == 0 then
error("key is empty")
end
local section = ""
local option
local keys = Util.split(string.lower(key), "::")
if #keys >= 2 then
section = keys[1]
option = keys[2]
else
option = keys[1]
end
self:addConfig(section, option, value)
end
-- section.key or key
function Config:get(key)
local section = self.DEFAULT_SECTION
local option
local keys = Util.split(string.lower(key), "::")
if #keys >= 2 then
section = keys[1]
option = keys[2]
else
option = keys[1]
end
if self.data[section] == nil then
return ""
elseif self.data[section][option] == nil then
return ""
else
return self.data[section][option]
end
end
return Config