;;;; Copyright (C) 2020 Julien Lepiller ;;;; ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either ;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;;; Lesser General Public License for more details. ;;;; ;;;; You should have received a copy of the GNU Lesser General Public ;;;; License along with this library; if not, write to the Free Software ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;;;; (define-module (jsonld deserialize-jsonld) #:use-module (iri iri) #:use-module (ice-9 match) #:use-module (jsonld json) #:use-module (jsonld generate-blank-node-identifier) #:use-module (jsonld object-to-rdf) #:use-module ((rdf rdf) #:hide (blank-node?)) #:export (deserialize-jsonld well-formed? rdf-iri xsd-iri blank-node->rdf-blank-node)) (define (uniq lst) (match lst (() '()) ((element lst ...) (if (member element lst) (uniq lst) (cons element (uniq lst)))))) (define (blank-node->rdf-blank-node node) "Convert a blank node generated from the generate blank node algorithm to a representation suitable for guile-rdf. This involves removing the leading _:b and converting to a number." (string->number (substring node 3))) (define (rdf-iri name) (string-append "http://www.w3.org/1999/02/22-rdf-syntax-ns#" name)) (define (xsd-iri name) (string-append "http://www.w3.org/2001/XMLSchema#" name)) (define (well-formed? node) (or (absolute-iri? node) (blank-node? node))) (define* (deserialize-jsonld generate-blank-node node-map dataset #:key produce-generalized-rdf? rdf-direction) ;; 1 (pk 'node-map node-map) (for-each-pair (lambda (graph-name graph) ;; 1.1 (when (or (well-formed? graph-name) (equal? graph-name "@default")) ;; 1.2 (let ((triples (if (equal? graph-name "@default") (rdf-dataset-default-graph dataset) '()))) ;; 1.3 (for-each-pair (lambda (subject node) ;; 1.3.1 (when (well-formed? subject) (when (blank-node? subject) (set! subject (blank-node->rdf-blank-node subject))) ;; 1.3.2 (for-each-pair (lambda (property values) (cond ((equal? property "@type") (for-each (lambda (type) (when (well-formed? type) (when (blank-node? type) (set! type (blank-node->rdf-blank-node type))) (set! triples (cons (make-rdf-triple subject (rdf-iri "type") type) triples)))) (array->list values))) ((json-keyword? property) #t) ((and (blank-node? property) (not produce-generalized-rdf?)) #t) ((not (well-formed? property)) #t) (else (when (blank-node? property) (set! property (blank-node->rdf-blank-node property))) (for-each (lambda (item) (let* ((res (object-to-rdf generate-blank-node rdf-direction item '())) (list-triples (assoc-ref res "list-triples")) (res (assoc-ref res "result"))) (unless (json-null? res) (set! triples (cons (make-rdf-triple subject property res) (append triples list-triples)))))) (array->list values))))) (alist-sort-by-key node)))) (alist-sort-by-key graph)) ;; 1.2 (cont.) (set! triples (uniq triples)) (if (equal? graph-name "@default") (set! dataset (make-rdf-dataset triples (rdf-dataset-named-graphs dataset))) (unless (null? triples) (set! dataset (make-rdf-dataset (rdf-dataset-default-graph dataset) (alist-set (rdf-dataset-named-graphs dataset) (if (blank-node? graph-name) (blank-node->rdf-blank-node graph-name) graph-name) triples)))))))) node-map) dataset)