123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- local dir = require "pl.dir"
- local path = require "pl.path"
- local term = require "volksdata.term"
- local nsm = require "volksdata.namespace"
- local pkar = require "pocket_archive"
- local logger = pkar.logger
- -- "nil" table.
- local NT = {}
- local no_ll_pnames = {
- archive_path = true,
- checksum = true,
- size = true,
- submitted = true,
- sub_id = true,
- }
- local M = {
- -- Parsed typedef configurations.
- types = {},
- -- Field names. Order is kept in encoding laundry lists. The hardcoded
- -- values come first, all others are harvested from the typedef
- -- configuration and ordered alphabetically.
- pnames = {"content_type", "id", "source_path"},
- -- Term-to-URI map. URIs are volksdata.Term objects.
- id_to_uri = {},
- -- URI-to-term map. Keys are URI strings, not volksdata.Term objects,
- -- because key comparison wouldn't work with them.
- uri_to_id = {},
- }
- M.from_uri = function(type_uri)
- assert(type_uri)
- return M.types[M.uri_to_id[nsm.denormalize_uri(type_uri.data)]]
- end
- -- Parameters that do not get inherited.
- local NO_INHERIT = {abstract = true}
- local MODEL_PATH = path.join(pkar.config_path, "model")
- local gen_config = dofile(path.join(MODEL_PATH, "generation.lua"))
- local function add_term(id, uri_str)
- --if not uri then error(("Term %s has not a URI!"):format(term), 2) end
- if not uri_str then return end
- local uri = term.new_iriref_ns(uri_str)
- if not M.id_to_uri[id] then M.id_to_uri[id] = uri end
- if not M.uri_to_id[uri_str] then M.uri_to_id[uri_str] = id end
- end
- local function parse_model(mod_id)
- local hierarchy = {}
- local function traverse(mod_id)
- logger:debug("traversing: " .. mod_id)
- local model = dofile(path.join(
- MODEL_PATH, "typedef", mod_id .. ".lua"))
- -- Merge separate generator config
- model.gen = gen_config[mod_id]
- --model.id = mod_id
- --print("Model: ")
- --for k, v in pairs(model) do print (k, v) end
- -- Prepend to hierarchy.
- model.id = mod_id
- -- Store term-to-URI and URI-to-term mappings.
- add_term(model.id, model.uri)
- for prop, pdata in pairs(model.properties or {}) do
- add_term(prop, pdata.uri) end
- table.insert(hierarchy, 1, model)
- if model.broader then traverse(model.broader) end
- end
- traverse(mod_id)
- local lineage = {} -- Ordered lineage of types, from ancestor to leaf.
- local types = {} -- Set of all types.
- for _, mod in ipairs(hierarchy) do
- table.insert(lineage, mod.id)
- types[mod.id] = true
- end
- local function merge(src, dest)
- for k, v in pairs(src) do
- if NO_INHERIT[k] then goto continue end
- if type(v) == "table" then
- dest[k] = dest[k] or {}
- assert(type(dest[k]) == "table")
- merge(v, dest[k])
- else
- dest[k] = v
- end
- ::continue::
- end
- end
- local config = {lineage = lineage, types = types}
- for _, src_config in ipairs(hierarchy) do
- merge(src_config, config)
- end
- return config
- end
- local function setup_model()
- -- Temp store (set) for property names.
- local all_pnames = {}
- -- Collect all type names from config file names.
- for _, fpath in ipairs(dir.getfiles(
- path.join(MODEL_PATH, "typedef"), "*.lua")) do
- local mname = path.basename(fpath):gsub(".lua$", "")
- local typedef = parse_model(mname)
- -- Store parsed typedef configurations.
- M.types[mname] = typedef
- -- Store unique prop names.
- for pn in pairs(typedef.properties or NT) do
- if not no_ll_pnames[pn] then all_pnames[pn] = true end
- end
- end
- -- Remove hardcoded prop names, reorder, and append to module's pnames.
- local pnames_ordered = {}
- for _, hcpn in ipairs(M.pnames) do
- all_pnames[hcpn] = nil
- end
- for pn in pairs(all_pnames) do
- table.insert(pnames_ordered, pn)
- end
- table.sort(pnames_ordered)
- for _, pn in ipairs(pnames_ordered) do table.insert(M.pnames, pn) end
- logger:debug("Property names ordered: " .. table.concat(M.pnames, ", "))
- end
- setup_model()
- return M
|