guile-jsonld/jsonld/iri-expansion.scm

iri-expansion.scm

1
;;;; Copyright (C) 2019, 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 iri-expansion)
19
  #:use-module (jsonld context)
20
  #:use-module (jsonld create-term-definition)
21
  #:use-module (jsonld download)
22
  #:use-module (jsonld iri)
23
  #:use-module (jsonld json)
24
  #:use-module (jsonld options)
25
  #:use-module (json)
26
  #:use-module (web uri)
27
  #:use-module (rnrs bytevectors)
28
  #:use-module (ice-9 match)
29
  #:use-module (srfi srfi-9)
30
  #:export (iri-expansion
31
            expand-key
32
            json-key-expanded-to?))
33
34
(define (expand-key active-context key)
35
  (assoc-ref
36
    (iri-expansion active-context key #:vocab? #t)
37
    "iri"))
38
39
(define (json-key-expanded-to? active-context element value)
40
  (and
41
    (json-object? element)
42
    (not
43
      (null?
44
        (filter
45
          (lambda (kv)
46
            (equal? value (expand-key active-context (car kv))))
47
          element)))))
48
49
(define* (iri-expansion active-context iri
50
                        #:key document-relative? vocab? (local-context '())
51
                              (defined '())
52
                              (options (new-jsonld-options)))
53
  "Expand an IRI.  This is an implementation of the IRI expansion algorithm 
54
defined in the JsonLD API specification."
55
  ;; 2
56
  (when (and (keyword-form? iri) (not (json-keyword? iri)))
57
    ;; Should give a warning and return null, we only return null without warning
58
    (set! iri #nil))
59
  ;; if not 1 or 2
60
  (unless (or (json-keyword? iri) (equal? iri #nil))
61
    ;; 3
62
    (when (and local-context (json-has-key? local-context iri))
63
      (let ((def (assoc-ref defined iri)))
64
        (unless (or (equal? def 'true) (equal? def #f))
65
          (let ((result (create-term-definition active-context local-context iri defined
66
                                                #:options options)))
67
            (set! active-context (assoc-ref result "active-context"))
68
            (set! defined (assoc-ref result "defined"))))))
69
    (cond
70
      ((not (string? iri))
71
       #t)
72
      ;; 4
73
      ((and (term-definition? (term-definition-ref active-context iri))
74
            (json-keyword?
75
              (term-definition-iri (term-definition-ref active-context iri))))
76
       (set! iri (term-definition-iri (term-definition-ref active-context iri))))
77
      ;; 5
78
      ((and vocab?
79
            (term-definition? (term-definition-ref active-context iri)))
80
       (set! iri (term-definition-iri (term-definition-ref active-context iri))))
81
      ;; 6
82
      ((and (not (equal? iri ""))
83
            (string-index (substring iri 1) #\:))
84
       ;; 6.1
85
       (let ((prefix (car (string-split iri #\:)))
86
             (suffix (string-join (cdr (string-split iri #\:)) ":")))
87
         (if (or (equal? prefix "_")
88
                 (and (> (string-length suffix) 1) (equal? (substring suffix 0 2) "//")))
89
           ;; 6.2
90
           (set! iri iri)
91
           (begin
92
             ;; 6.3
93
             (when (and (json-object? local-context)
94
                        (json-has-key? local-context prefix))
95
               (let ((def (assoc-ref defined prefix)))
96
                 (unless (or (equal? def 'true))
97
                   (let* ((result (create-term-definition active-context local-context prefix defined
98
                                                          #:options options)))
99
                     (set! active-context (assoc-ref result "active-context"))
100
                     (set! defined (assoc-ref result "defined"))))))
101
             ;; 6.4
102
             (if (and
103
                   (term-definition? (term-definition-ref active-context prefix))
104
                   (term-definition-iri (term-definition-ref active-context prefix))
105
                   (term-definition-prefix? (term-definition-ref active-context prefix)))
106
               (set! iri
107
                 (string-append (term-definition-iri
108
                                  (term-definition-ref active-context prefix))
109
                                suffix))
110
               ;; 6.5
111
               (cond
112
                 ((absolute-iri? iri)
113
                  (set! iri iri))
114
                 ;; 7
115
                 ((and vocab? (active-context-vocab active-context))
116
                  (set! iri (string-append (active-context-vocab active-context)
117
                                           iri)))
118
                 (else
119
                   (if (and document-relative? (not (equal? (active-context-base active-context) #nil)))
120
                       ;; 8
121
                       (set! iri (resolve-iri (or
122
                                                (active-context-base active-context)
123
                                                (jsonld-options-base options))
124
                                              iri))
125
                       ;; 9
126
                       (set! iri iri)))))))))
127
      ;; 7
128
      ((and vocab? (active-context-vocab active-context))
129
       (set! iri (string-append (active-context-vocab active-context)
130
                                iri)))
131
      (else
132
        (if (and document-relative? (not (equal? (active-context-base active-context) #nil)))
133
          ;; 8
134
          (set! iri (resolve-iri (or
135
                                   (active-context-base active-context)
136
                                   (jsonld-options-base options))
137
                                 iri))
138
          ;; 9
139
          (set! iri iri)))))
140
  ;; return an alist of potentially modified objects: iri (the return iri),
141
  ;; defined and active-context.
142
  `(("iri" . ,iri) ("active-context" . ,active-context) ("defined" . ,defined)))
143