Browse Source

Fix internal ID linking in submission and dump CLI command.

scossu 2 weeks ago
parent
commit
392d7600ed
3 changed files with 31 additions and 9 deletions
  1. 2 0
      config/model/typedef/anything.lua
  2. 22 2
      src/submission.lua
  3. 7 7
      src/util/pkar.lua

+ 2 - 0
config/model/typedef/anything.lua

@@ -31,9 +31,11 @@ return {
         },
         --]]
         sub_id = {
+            uri = "pas:submissionID",
             description = "Unique ID for the submission that the resource \z
                 was created or updated in.",
             type = "string",
+            min_cardinality = 1,
         },
         ext_id = {
             uri = "dc:identifier",

+ 22 - 2
src/submission.lua

@@ -49,6 +49,9 @@ local NT = {}
 -- Local path to URI mapping. For linking between newly created resources.
 local path_to_uri
 
+-- Track IDs in SIP to validate links created in a submission.
+local sip_ids
+
 
 -- Initialize libmagic database.
 local magic = libmagic.open(libmagic.MIME_TYPE, libmagic.NO_CHECK_COMPRESS )
@@ -86,6 +89,7 @@ local function generate_sip(ll_path)
 
     local sip = {root_path = path.dirname(ll_path)}
     path_to_uri = {}
+    sip_ids = {}
 
     local tn_dir = path.join(sip.root_path, "proc", "tn")
     dir.makepath(tn_dir)
@@ -117,6 +121,7 @@ local function generate_sip(ll_path)
                 id = "par:" .. (row.id or idgen()),
                 sub_id = sub_id,
             }
+            sip_ids[sip[i].id] = true  -- Add to common sip ID set.
             for k, v in pairs(row) do
                 if not v or k == "id" then goto cont1 end  -- skip empty strings.
                 if pkar.config.md.single_values[k] then sip[i][k] = v
@@ -162,6 +167,7 @@ local function generate_sip(ll_path)
         -- Create implicit members from single-file artifact.
         if rmod.types.artifact and path.isfile(fpath) then
             local file_id = "par:" .. idgen()
+            sip_ids[file_id] = true
             -- Insert file resource and move it into a new sub-folder.
             table.insert(sip, {
                 content_type = rmod.default_fmodel or "file",
@@ -232,14 +238,26 @@ local function rsrc_to_graph(rsrc)
             if prop == "content_type" then
                 o = term.new_iriref_ns(rmod.uri)
             elseif pconf.type == "resource" then
-                if not vv:match("^[a-z]*:") then
+                -- "par:" could have been added previously.
+                local rel_id = "par:" .. vv:gsub("^par:", "")
+                if
+                    not sip_ids[rel_id]
+                    and not repo.gr:contains(triple.new(
+                        term.new_iriref_ns(rel_id),
+                        pkar.RDF_TYPE,
+                        term.new_iriref_ns("pas:Anything")
+                ))
+                then
                     -- Convert local path to URIs.
                     v[i] = path_to_uri[vv]
                     if not v[i] then error(
                         ("Not a valid path: %s for property: %s on res: %s")
                         :format(vv, prop, rsrc.id))
                     end
+                    logger:debug("Converted path ".. vv .. " to URI: " .. v[i])
+                else v[i] = rel_id
                 end
+                --if not v[i]:find("^par:") then dbg() end
                 o = term.new_iriref_ns(v[i])
             elseif pconf.type == "ext_resource" then
                 o = term.new_iriref(vv)
@@ -252,7 +270,9 @@ local function rsrc_to_graph(rsrc)
             local proxy_s
             for i, vv in ipairs(v) do
                 -- Add linked list proxies.
-                local brick_uri = term.new_iriref_ns("par:" .. idgen())
+                local brick_id = "par:" .. idgen()
+                local brick_uri = term.new_iriref_ns(brick_id)
+                sip_ids[brick_id] = true
                 if i == 1 then
                     proxy_s = s
                     it:add_iter(triple.new(

+ 7 - 7
src/util/pkar.lua

@@ -86,13 +86,13 @@ dump_res = cli.command {
 
     function(args)
         local s = term.new_iriref_ns(args.id)
-        local out = repo.serialize_rsrc(s, args.format)
-        if args.output ~= "" then
-            local fh = assert(io.open(args.output, "w"))
-            fh:write(out)
-            fh:close()
-            print("File written to ", args.output)
-        else print(out) end
+        args.output = args.output or io.stdout
+        local fh = assert(io.open(args.output, "w"))
+        for chunk in repo.serialize_rsrc(s, args.format) do
+            fh:write(chunk)
+        end
+        fh:close()
+        print("File written to ", args.output)
     end,
 }