diff --git a/README.md b/README.md index 6f7a225..8b9aa33 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,8 @@ This service creates two types of resources: ### `sign:SignedResource` The signed resource is a document that has been signed. It has the following properties: -* `sign:text` *: the content of the document that was signed +* `sign:text` *: (unless prov:generated exists) the content of the document that was signed +* `prov:generated` *: (unless sign:text exists) the uri of the file that has been generated, holding the contents of the document that was signed * `sign:signatory` *: the agent that signed the document * `sign:signatoryRoles`: the roles the agent had at the moment of signing (the same agent might be able to log into a specific role) * `dct:created` *: creation date of the signature @@ -66,24 +67,41 @@ The signed resource is a document that has been signed. It has the following pro * `sign:hashAlgorithm`: the hashing algorithm that was used -Fields denoted with an asterix `*` are used for the hashValue -You can use the following snippet in mu-cl-resources +Fields denoted with an asterix `*` are used for the hashValue. If the content is stored in a file, the contents of that file are used for the hash, if the content is stored in the triplestore, then that value is used directly. +You can use the following snippet in mu-cl-resources (which also defines the file resource): ```lisp +(define-resource file () + :class (s-prefix "nfo:FileDataObject") + :properties `((:name :string ,(s-prefix "nfo:fileName")) + (:format :string ,(s-prefix "dct:format")) + (:size :number ,(s-prefix "nfo:fileSize")) + (:extension :string ,(s-prefix "dbpedia:fileExtension")) + (:created :datetime ,(s-prefix "nfo:fileCreated"))) + :has-one `((file :via ,(s-prefix "nie:dataSource") + :inverse t + :as "download")) + :resource-base (s-url "http://data.example.com/files/") + :features `(include-uri) + :on-path "files" +) (define-resource signed-resource () :class (s-prefix "sign:SignedResource") :properties `((:content :string ,(s-prefix "sign:text")) (:hash-value :string ,(s-prefix "sign:hashValue")) (:hash-algo :string ,(s-prefix "sign:hashAlgorithm")) (:created-on :datetime ,(s-prefix "dct:created"))) + :has-one `((file :via ,(s-prefix "prov:generated") + :as "file")) ) ``` ### `sign:PublishedResource` The published resource is a document as it has been published. The content of the published may be different from the actual document, as senstive information may be removed. -* `sign:text` *: the content of the document as it is published -* `sign:signatory` *: the agent that published the document +* `sign:text`: (unless prov:generated exists) the content of the document as it is published +* `prov:generated`: (unless sign:text exists) the uri of the file that has been generated, holding the contents of the document as it is published +* `sign:signatory`: the agent that published the document * `sign:signatoryRoles`: the roles the agent had at the moment of publishing (the same agent might be able to log into a specific role) -* `dct:created` *: creation date of the publication +* `dct:created`: creation date of the publication * `dct:subject`: the document that was published * `sign:hashValue`: the hash that was calculated when publishing the document * `sign:hashAlgorithm`: the hashing algorithm that was used diff --git a/models/signed-resource.js b/models/signed-resource.js index 3cf2c56..11e11bb 100644 --- a/models/signed-resource.js +++ b/models/signed-resource.js @@ -15,7 +15,6 @@ export default class SignedResource { BIND(${sparqlEscapeUri(uri)} as ?uri) ?uri a sign:SignedResource; mu:uuid ?uuid; - sign:text ?html; sign:hashValue ?hashValue; sign:hashAlgorithm ?hashAlgorithm; dct:created ?created; @@ -27,6 +26,11 @@ export default class SignedResource { ?blockchainStatus mu:uuid ?blockchainStatusUuid. ?signatory mu:uuid ?signatoryUuid. + { + { ?uri sign:text ?html. } + UNION + { ?uri prov:generated ?file. } + } OPTIONAL { ?uri ext:deleted ?deleted. } OPTIONAL { ?uri ext:signsAgenda ?agenda. @@ -71,6 +75,7 @@ export default class SignedResource { uri, uuid, html, + file, hashValue, hashAlgorithm, created, @@ -92,7 +97,8 @@ export default class SignedResource { return new SignedResource({ uri: uri.value, uuid: uuid.value, - html: html.value, + html: html?.value, + file: file?.value, hashValue: hashValue.value, hashAlgorithm: hashAlgorithm.value, created: created.value, @@ -117,6 +123,7 @@ export default class SignedResource { uri, uuid, html, + file, hashValue, hashAlgorithm, created, @@ -138,6 +145,7 @@ export default class SignedResource { this.uuid = uuid; this.uri = uri; this.html = html; + this.file = file; this.signatory = signatory; this.created = created; this.signatoryRole = signatoryRole; @@ -213,6 +221,7 @@ export default class SignedResource { attributes: { uri: this.uri, content: this.html, + file: this.file, 'hash-value': this.hashValue, 'created-on': this.created, deleted: this.deleted, diff --git a/support/pre-importer.js b/support/pre-importer.js index 688f2a1..9915d52 100644 --- a/support/pre-importer.js +++ b/support/pre-importer.js @@ -97,6 +97,8 @@ async function handleVersionedResource( .join(' ') : ''; const content = await getVersionedContent(versionedUri, contentPredicate); + // This creates a new file each time, even if getVersionedContent has just retrieved it from a + // file. This is to make handling deletes and document changes easier. const fileMetadata = await persistContentToFile(content); const logicalFileUri = await writeFileMetadataToDb(fileMetadata);