deserialize-jsonld.scm
1 | ;;;; Copyright (C) 2020 Julien Lepiller <julien@lepiller.eu> |
2 | ;;;; |
3 | ;;;; This library is free software; you can redistribute it and/or |
4 | ;;;; modify it under the terms of the GNU Lesser General Public |
5 | ;;;; License as published by the Free Software Foundation; either |
6 | ;;;; version 3 of the License, or (at your option) any later version. |
7 | ;;;; |
8 | ;;;; This library is distributed in the hope that it will be useful, |
9 | ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
11 | ;;;; Lesser General Public License for more details. |
12 | ;;;; |
13 | ;;;; You should have received a copy of the GNU Lesser General Public |
14 | ;;;; License along with this library; if not, write to the Free Software |
15 | ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
16 | ;;;; |
17 | |
18 | (define-module (jsonld deserialize-jsonld) |
19 | #:use-module (ice-9 match) |
20 | #:use-module (jsonld iri) |
21 | #:use-module (jsonld json) |
22 | #:use-module (jsonld generate-blank-node-identifier) |
23 | #:use-module (jsonld object-to-rdf) |
24 | #:use-module ((rdf rdf) #:hide (blank-node?)) |
25 | #:export (deserialize-jsonld |
26 | well-formed? |
27 | rdf-iri |
28 | xsd-iri |
29 | blank-node->rdf-blank-node)) |
30 | |
31 | (define (uniq lst) |
32 | (match lst |
33 | (() '()) |
34 | ((element lst ...) |
35 | (if (member element lst) |
36 | (uniq lst) |
37 | (cons element (uniq lst)))))) |
38 | |
39 | (define (blank-node->rdf-blank-node node) |
40 | "Convert a blank node generated from the generate blank node algorithm to |
41 | a representation suitable for guile-rdf. This involves removing the leading |
42 | _:b and converting to a number." |
43 | (string->number (substring node 3))) |
44 | |
45 | (define (rdf-iri name) |
46 | (string-append "http://www.w3.org/1999/02/22-rdf-syntax-ns#" name)) |
47 | |
48 | (define (xsd-iri name) |
49 | (string-append "http://www.w3.org/2001/XMLSchema#" name)) |
50 | |
51 | (define (well-formed? node) |
52 | (or (absolute-iri? node) (blank-node? node))) |
53 | |
54 | (define* (deserialize-jsonld generate-blank-node node-map dataset |
55 | #:key produce-generalized-rdf? rdf-direction) |
56 | ;; 1 |
57 | (for-each-pair |
58 | (lambda (graph-name graph) |
59 | ;; 1.1 |
60 | (when (or (well-formed? graph-name) (equal? graph-name "@default")) |
61 | ;; 1.2 |
62 | (let ((triples (if (equal? graph-name "@default") |
63 | (rdf-dataset-default-graph dataset) |
64 | '()))) |
65 | ;; 1.3 |
66 | (for-each-pair |
67 | (lambda (subject node) |
68 | ;; 1.3.1 |
69 | (when (well-formed? subject) |
70 | (when (blank-node? subject) |
71 | (set! subject (blank-node->rdf-blank-node subject))) |
72 | ;; 1.3.2 |
73 | (for-each-pair |
74 | (lambda (property values) |
75 | (cond |
76 | ((equal? property "@type") |
77 | (for-each |
78 | (lambda (type) |
79 | (when (well-formed? type) |
80 | (when (blank-node? type) |
81 | (set! type (blank-node->rdf-blank-node type))) |
82 | (set! triples |
83 | (cons |
84 | (make-rdf-triple subject (rdf-iri "type") |
85 | type) |
86 | triples)))) |
87 | (array->list values))) |
88 | ((json-keyword? property) |
89 | #t) |
90 | ((and (blank-node? property) (not produce-generalized-rdf?)) |
91 | #t) |
92 | ((not (well-formed? property)) |
93 | #t) |
94 | (else |
95 | (when (blank-node? property) |
96 | (set! property (blank-node->rdf-blank-node property))) |
97 | (for-each |
98 | (lambda (item) |
99 | (let* ((res |
100 | (object-to-rdf generate-blank-node |
101 | rdf-direction item '())) |
102 | (list-triples (assoc-ref res "list-triples")) |
103 | (res (assoc-ref res "result"))) |
104 | (unless (equal? res #nil) |
105 | (set! triples |
106 | (cons |
107 | (make-rdf-triple subject property res) |
108 | (append triples list-triples)))))) |
109 | (array->list values))))) |
110 | (alist-sort-by-key node)))) |
111 | (alist-sort-by-key graph)) |
112 | ;; 1.2 (cont.) |
113 | (set! triples (uniq triples)) |
114 | (if (equal? graph-name "@default") |
115 | (set! dataset |
116 | (make-rdf-dataset triples (rdf-dataset-named-graphs dataset))) |
117 | (unless (null? triples) |
118 | (set! dataset |
119 | (make-rdf-dataset (rdf-dataset-default-graph dataset) |
120 | (alist-set |
121 | (rdf-dataset-named-graphs dataset) |
122 | (if (blank-node? graph-name) |
123 | (blank-node->rdf-blank-node graph-name) |
124 | graph-name) |
125 | triples)))))))) |
126 | node-map) |
127 | dataset) |
128 |