json-ld 3.2.3 → 3.2.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/lib/json/ld/api.rb +23 -16
- data/lib/json/ld/compact.rb +16 -16
- data/lib/json/ld/context.rb +52 -84
- data/lib/json/ld/expand.rb +23 -23
- data/lib/json/ld/from_rdf.rb +56 -17
- data/lib/json/ld/streaming_writer.rb +6 -6
- data/lib/json/ld/to_rdf.rb +10 -8
- data/lib/json/ld/writer.rb +3 -3
- data/spec/context_spec.rb +31 -11
- data/spec/frame_spec.rb +43 -0
- data/spec/from_rdf_spec.rb +67 -0
- data/spec/to_rdf_spec.rb +133 -0
- metadata +27 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7df92f96bef30d3af100b145f427533e3fa5bc2a91369e1edc86fd41dc2946bb
|
4
|
+
data.tar.gz: fcd7f3972ea390ace60be529f3106bd04823c8cddbb5efd050d0c9d134586028
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c1df99a21da6ae271caeedc44e0f66fffe77dbae771297153b45286d70a96044dcc97ea62a3aaffe74ac11a847ae52bf641410ba74e43cfed51c5f773c69c9a
|
7
|
+
data.tar.gz: ed0e35ecdaf9118b0ee81a34bb72f92e9344678a8c3e4311f4bed4a35d58bb217b2f4810e1f8cc5c59c97312399e716a237b5c1e841fd538c730d4e8e9e151c7
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.2.
|
1
|
+
3.2.4
|
data/lib/json/ld/api.rb
CHANGED
@@ -66,6 +66,7 @@ module JSON::LD
|
|
66
66
|
# @param [String, #read, Hash, Array, JSON::LD::Context] context
|
67
67
|
# An external context to use additionally to the context embedded in input when expanding the input.
|
68
68
|
# @param [Hash{Symbol => Object}] options
|
69
|
+
# @option options [Symbol] :adapter used with MultiJson
|
69
70
|
# @option options [RDF::URI, String, #to_s] :base
|
70
71
|
# The Base IRI to use when expanding the document. This overrides the value of `input` if it is a _IRI_. If not specified and `input` is not an _IRI_, the base IRI defaults to the current document IRI if in a browser context, or the empty string if there is no document context. If not specified, and a base IRI is found from `input`, options[:base] will be modified with this value.
|
71
72
|
# @option options [Boolean] :compactArrays (true)
|
@@ -74,10 +75,10 @@ module JSON::LD
|
|
74
75
|
# Creates document relative IRIs when compacting, if `true`, otherwise leaves expanded.
|
75
76
|
# @option options [Proc] :documentLoader
|
76
77
|
# The callback of the loader to be used to retrieve remote documents and contexts. If specified, it must be used to retrieve remote documents and contexts; otherwise, if not specified, the processor's built-in loader must be used. See {documentLoader} for the method signature.
|
77
|
-
# @option options [Boolean] :lowercaseLanguage
|
78
|
-
# By default, language tags are left as is. To normalize to lowercase, set this option to `true`.
|
79
78
|
# @option options [String, #read, Hash, Array, JSON::LD::Context] :expandContext
|
80
79
|
# A context that is used to initialize the active context when expanding a document.
|
80
|
+
# @option options [Boolean] :extendedRepresentation (false)
|
81
|
+
# Use the extended internal representation.
|
81
82
|
# @option options [Boolean] :extractAllScripts
|
82
83
|
# If set, when given an HTML input without a fragment identifier, extracts all `script` elements with type `application/ld+json` into an array during expansion.
|
83
84
|
# @option options [Boolean, String, RDF::URI] :flatten
|
@@ -86,19 +87,19 @@ module JSON::LD
|
|
86
87
|
# When set, this has the effect of inserting a context definition with `@language` set to the associated value, creating a default language for interpreting string values.
|
87
88
|
# @option options [Symbol] :library
|
88
89
|
# One of :nokogiri or :rexml. If nil/unspecified uses :nokogiri if available, :rexml otherwise.
|
90
|
+
# @option options [Boolean] :lowercaseLanguage
|
91
|
+
# By default, language tags are left as is. To normalize to lowercase, set this option to `true`.
|
92
|
+
# @option options [Boolean] :ordered (true)
|
93
|
+
# Order traversal of dictionary members by key when performing algorithms.
|
89
94
|
# @option options [String] :processingMode
|
90
95
|
# Processing mode, json-ld-1.0 or json-ld-1.1.
|
91
|
-
#
|
92
|
-
# @option options [Boolean] rdfstar (false)
|
96
|
+
# @option options [Boolean] :rdfstar (false)
|
93
97
|
# support parsing JSON-LD-star statement resources.
|
94
98
|
# @option options [Boolean] :rename_bnodes (true)
|
95
99
|
# Rename bnodes as part of expansion, or keep them the same.
|
96
100
|
# @option options [Boolean] :unique_bnodes (false)
|
97
101
|
# Use unique bnode identifiers, defaults to using the identifier which the node was originally initialized with (if any).
|
98
|
-
# @option options [Symbol] :adapter used with MultiJson
|
99
102
|
# @option options [Boolean] :validate Validate input, if a string or readable object.
|
100
|
-
# @option options [Boolean] :ordered (true)
|
101
|
-
# Order traversal of dictionary members by key when performing algorithms.
|
102
103
|
# @yield [api]
|
103
104
|
# @yieldparam [API]
|
104
105
|
# @raise [JsonLdError]
|
@@ -235,7 +236,7 @@ module JSON::LD
|
|
235
236
|
end
|
236
237
|
|
237
238
|
API.new(expanded_input, context, no_default_base: true, **options) do
|
238
|
-
log_debug(".compact") {"expanded input: #{expanded_input.to_json(JSON_STATE) rescue 'malformed json'}"}
|
239
|
+
# log_debug(".compact") {"expanded input: #{expanded_input.to_json(JSON_STATE) rescue 'malformed json'}"}
|
239
240
|
result = compact(value)
|
240
241
|
|
241
242
|
# xxx) Add the given context to the output
|
@@ -289,7 +290,7 @@ module JSON::LD
|
|
289
290
|
|
290
291
|
# Initialize input using
|
291
292
|
API.new(expanded_input, context, no_default_base: true, **options) do
|
292
|
-
log_debug(".flatten") {"expanded input: #{value.to_json(JSON_STATE) rescue 'malformed json'}"}
|
293
|
+
# log_debug(".flatten") {"expanded input: #{value.to_json(JSON_STATE) rescue 'malformed json'}"}
|
293
294
|
|
294
295
|
# Rename blank nodes recusively. Note that this does not create new blank node identifiers where none exist, which is performed in the node map generation algorithm.
|
295
296
|
@value = rename_bnodes(@value) if @options[:rename_bnodes]
|
@@ -410,8 +411,8 @@ module JSON::LD
|
|
410
411
|
|
411
412
|
# Initialize input using frame as context
|
412
413
|
API.new(expanded_input, frame['@context'], no_default_base: true, **options) do
|
413
|
-
log_debug(".frame") {"expanded input: #{expanded_input.to_json(JSON_STATE) rescue 'malformed json'}"}
|
414
|
-
log_debug(".frame") {"expanded frame: #{expanded_frame.to_json(JSON_STATE) rescue 'malformed json'}"}
|
414
|
+
# log_debug(".frame") {"expanded input: #{expanded_input.to_json(JSON_STATE) rescue 'malformed json'}"}
|
415
|
+
# log_debug(".frame") {"expanded frame: #{expanded_frame.to_json(JSON_STATE) rescue 'malformed json'}"}
|
415
416
|
|
416
417
|
if %w(@first @last).include?(options[:embed]) && context.processingMode('json-ld-1.1')
|
417
418
|
raise JSON::LD::JsonLdError::InvalidEmbedValue, "#{options[:embed]} is not a valid value of @embed in 1.1 mode" if @options[:validate]
|
@@ -458,7 +459,7 @@ module JSON::LD
|
|
458
459
|
|
459
460
|
# Replace values with `@preserve` with the content of its entry.
|
460
461
|
result = cleanup_preserve(result)
|
461
|
-
log_debug(".frame") {"expanded result: #{result.to_json(JSON_STATE) rescue 'malformed json'}"}
|
462
|
+
# log_debug(".frame") {"expanded result: #{result.to_json(JSON_STATE) rescue 'malformed json'}"}
|
462
463
|
|
463
464
|
# Compact result
|
464
465
|
compacted = compact(result)
|
@@ -477,7 +478,7 @@ module JSON::LD
|
|
477
478
|
# Only add context if one was provided
|
478
479
|
result = context.serialize(provided_context: frame).merge(result) if frame['@context']
|
479
480
|
|
480
|
-
log_debug(".frame") {"after compact: #{result.to_json(JSON_STATE) rescue 'malformed json'}"}
|
481
|
+
# log_debug(".frame") {"after compact: #{result.to_json(JSON_STATE) rescue 'malformed json'}"}
|
481
482
|
result
|
482
483
|
end
|
483
484
|
|
@@ -518,7 +519,7 @@ module JSON::LD
|
|
518
519
|
API.new(flattened_input, nil, **options) do
|
519
520
|
# 1) Perform the Expansion Algorithm on the JSON-LD input.
|
520
521
|
# This removes any existing context to allow the given context to be cleanly applied.
|
521
|
-
log_debug(".toRdf") {"flattened input: #{flattened_input.to_json(JSON_STATE) rescue 'malformed json'}"}
|
522
|
+
# log_debug(".toRdf") {"flattened input: #{flattened_input.to_json(JSON_STATE) rescue 'malformed json'}"}
|
522
523
|
|
523
524
|
# Recurse through input
|
524
525
|
flattened_input.each do |node|
|
@@ -527,7 +528,7 @@ module JSON::LD
|
|
527
528
|
|
528
529
|
# Drop invalid statements (other than IRIs)
|
529
530
|
unless statement.valid_extended?
|
530
|
-
log_debug(".toRdf") {"drop invalid statement: #{statement.to_nquads}"}
|
531
|
+
# log_debug(".toRdf") {"drop invalid statement: #{statement.to_nquads}"}
|
531
532
|
next
|
532
533
|
end
|
533
534
|
|
@@ -562,6 +563,7 @@ module JSON::LD
|
|
562
563
|
|
563
564
|
API.new(nil, nil, **options) do
|
564
565
|
result = from_statements(input,
|
566
|
+
extendedRepresentation: options[:extendedRepresentation],
|
565
567
|
useRdfType: useRdfType,
|
566
568
|
useNativeTypes: useNativeTypes)
|
567
569
|
end
|
@@ -574,6 +576,9 @@ module JSON::LD
|
|
574
576
|
# Uses built-in or provided documentLoader to retrieve a parsed document.
|
575
577
|
#
|
576
578
|
# @param [RDF::URI, String] url
|
579
|
+
# @param [Regexp] allowed_content_types
|
580
|
+
# A regular expression matching other content types allowed
|
581
|
+
# beyond types for JSON and HTML.
|
577
582
|
# @param [String, RDF::URI] base
|
578
583
|
# Location to use as documentUrl instead of `url`.
|
579
584
|
# @option options [Proc] :documentLoader
|
@@ -594,6 +599,7 @@ module JSON::LD
|
|
594
599
|
# If a block is given, the result of evaluating the block is returned, otherwise, the retrieved remote document and context information unless block given
|
595
600
|
# @raise [JsonLdError]
|
596
601
|
def self.loadRemoteDocument(url,
|
602
|
+
allowed_content_types: nil,
|
597
603
|
base: nil,
|
598
604
|
documentLoader: nil,
|
599
605
|
extractAllScripts: false,
|
@@ -674,7 +680,8 @@ module JSON::LD
|
|
674
680
|
|
675
681
|
if remote_doc.contentType && validate
|
676
682
|
raise IOError, "url: #{url}, contentType: #{remote_doc.contentType}" unless
|
677
|
-
remote_doc.contentType.match?(/application\/(.+\+)?json|text\/html|application\/xhtml\+xml/)
|
683
|
+
remote_doc.contentType.match?(/application\/(.+\+)?json|text\/html|application\/xhtml\+xml/) ||
|
684
|
+
(allowed_content_types && remote_doc.contentType.match?(allowed_content_types))
|
678
685
|
end
|
679
686
|
block_given? ? yield(remote_doc) : remote_doc
|
680
687
|
end
|
data/lib/json/ld/compact.rb
CHANGED
@@ -21,14 +21,14 @@ module JSON::LD
|
|
21
21
|
base: nil,
|
22
22
|
property: nil,
|
23
23
|
log_depth: nil)
|
24
|
-
log_debug("compact", depth: log_depth.to_i) {"element: #{element.inspect}, ec: #{context.inspect}"}
|
24
|
+
# log_debug("compact", depth: log_depth.to_i) {"element: #{element.inspect}, ec: #{context.inspect}"}
|
25
25
|
|
26
26
|
# If the term definition for active property itself contains a context, use that for compacting values.
|
27
27
|
input_context = self.context
|
28
28
|
|
29
29
|
case element
|
30
30
|
when Array
|
31
|
-
#log_debug("") {"Array #{element.inspect}"}
|
31
|
+
# log_debug("") {"Array #{element.inspect}"}
|
32
32
|
result = element.map do |item|
|
33
33
|
compact(item, base: base, property: property, log_depth: log_depth.to_i + 1)
|
34
34
|
end.compact
|
@@ -38,10 +38,10 @@ module JSON::LD
|
|
38
38
|
# member; otherwise the compacted value is element
|
39
39
|
if result.length == 1 &&
|
40
40
|
!context.as_array?(property) && @options[:compactArrays]
|
41
|
-
log_debug("=> extract single element", depth: log_depth.to_i) {result.first.inspect}
|
41
|
+
# log_debug("=> extract single element", depth: log_depth.to_i) {result.first.inspect}
|
42
42
|
result.first
|
43
43
|
else
|
44
|
-
log_debug("=> array result", depth: log_depth.to_i) {result.inspect}
|
44
|
+
# log_debug("=> array result", depth: log_depth.to_i) {result.inspect}
|
45
45
|
result
|
46
46
|
end
|
47
47
|
when Hash
|
@@ -52,7 +52,7 @@ module JSON::LD
|
|
52
52
|
|
53
53
|
# Revert any previously type-scoped (non-preserved) context
|
54
54
|
if context.previous_context && !element.key?('@value') && element.keys != %w(@id)
|
55
|
-
log_debug("revert ec", depth: log_depth.to_i) {"previous context: #{context.previous_context.inspect}"}
|
55
|
+
# log_debug("revert ec", depth: log_depth.to_i) {"previous context: #{context.previous_context.inspect}"}
|
56
56
|
self.context = context.previous_context
|
57
57
|
end
|
58
58
|
|
@@ -61,13 +61,13 @@ module JSON::LD
|
|
61
61
|
if td && !td.context.nil?
|
62
62
|
self.context = context.parse(td.context,
|
63
63
|
override_protected: true)
|
64
|
-
log_debug("prop-scoped", depth: log_depth.to_i) {"context: #{self.context.inspect}"}
|
64
|
+
# log_debug("prop-scoped", depth: log_depth.to_i) {"context: #{self.context.inspect}"}
|
65
65
|
end
|
66
66
|
|
67
67
|
if (element.key?('@id') || element.key?('@value')) && !element.key?('@annotation')
|
68
68
|
result = context.compact_value(property, element, base: @options[:base])
|
69
69
|
if !result.is_a?(Hash) || context.coerce(property) == '@json'
|
70
|
-
log_debug("", depth: log_depth.to_i) {"=> scalar result: #{result.inspect}"}
|
70
|
+
# log_debug("", depth: log_depth.to_i) {"=> scalar result: #{result.inspect}"}
|
71
71
|
return result
|
72
72
|
end
|
73
73
|
end
|
@@ -90,12 +90,12 @@ module JSON::LD
|
|
90
90
|
each do |term|
|
91
91
|
term_context = input_context.term_definitions[term].context if input_context.term_definitions[term]
|
92
92
|
self.context = context.parse(term_context, propagate: false) unless term_context.nil?
|
93
|
-
log_debug("type-scoped", depth: log_depth.to_i) {"context: #{self.context.inspect}"}
|
93
|
+
# log_debug("type-scoped", depth: log_depth.to_i) {"context: #{self.context.inspect}"}
|
94
94
|
end
|
95
95
|
|
96
96
|
element.keys.opt_sort(ordered: @options[:ordered]).each do |expanded_property|
|
97
97
|
expanded_value = element[expanded_property]
|
98
|
-
log_debug("", depth: log_depth.to_i) {"#{expanded_property}: #{expanded_value.inspect}"}
|
98
|
+
# log_debug("", depth: log_depth.to_i) {"#{expanded_property}: #{expanded_value.inspect}"}
|
99
99
|
|
100
100
|
if expanded_property == '@id'
|
101
101
|
compacted_value = as_array(expanded_value).map do |expanded_id|
|
@@ -134,7 +134,7 @@ module JSON::LD
|
|
134
134
|
compacted_value = compact(expanded_value, base: base,
|
135
135
|
property: '@reverse',
|
136
136
|
log_depth: log_depth.to_i + 1)
|
137
|
-
log_debug("@reverse", depth: log_depth.to_i) {"compacted_value: #{compacted_value.inspect}"}
|
137
|
+
# log_debug("@reverse", depth: log_depth.to_i) {"compacted_value: #{compacted_value.inspect}"}
|
138
138
|
# handle double-reversed properties
|
139
139
|
compacted_value.each do |prop, value|
|
140
140
|
if context.reverse?(prop)
|
@@ -146,7 +146,7 @@ module JSON::LD
|
|
146
146
|
|
147
147
|
unless compacted_value.empty?
|
148
148
|
al = context.compact_iri('@reverse', vocab: true)
|
149
|
-
log_debug("", depth: log_depth.to_i) {"remainder: #{al} => #{compacted_value.inspect}"}
|
149
|
+
# log_debug("", depth: log_depth.to_i) {"remainder: #{al} => #{compacted_value.inspect}"}
|
150
150
|
result[al] = compacted_value
|
151
151
|
end
|
152
152
|
next
|
@@ -157,7 +157,7 @@ module JSON::LD
|
|
157
157
|
compacted_value = compact(expanded_value, base: base,
|
158
158
|
property: property,
|
159
159
|
log_depth: log_depth.to_i + 1)
|
160
|
-
log_debug("@preserve", depth: log_depth.to_i) {"compacted_value: #{compacted_value.inspect}"}
|
160
|
+
# log_debug("@preserve", depth: log_depth.to_i) {"compacted_value: #{compacted_value.inspect}"}
|
161
161
|
|
162
162
|
unless compacted_value.is_a?(Array) && compacted_value.empty?
|
163
163
|
result['@preserve'] = compacted_value
|
@@ -166,14 +166,14 @@ module JSON::LD
|
|
166
166
|
end
|
167
167
|
|
168
168
|
if expanded_property == '@index' && context.container(property).include?('@index')
|
169
|
-
log_debug("@index", depth: log_depth.to_i) {"drop @index"}
|
169
|
+
# log_debug("@index", depth: log_depth.to_i) {"drop @index"}
|
170
170
|
next
|
171
171
|
end
|
172
172
|
|
173
173
|
# Otherwise, if expanded property is @direction, @index, @value, or @language:
|
174
174
|
if EXPANDED_PROPERTY_DIRECTION_INDEX_LANGUAGE_VALUE.include?(expanded_property)
|
175
175
|
al = context.compact_iri(expanded_property, vocab: true)
|
176
|
-
log_debug(expanded_property, depth: log_depth.to_i) {"#{al} => #{expanded_value.inspect}"}
|
176
|
+
# log_debug(expanded_property, depth: log_depth.to_i) {"#{al} => #{expanded_value.inspect}"}
|
177
177
|
result[al] = expanded_value
|
178
178
|
next
|
179
179
|
end
|
@@ -223,7 +223,7 @@ module JSON::LD
|
|
223
223
|
compacted_item = compact(value, base: base,
|
224
224
|
property: item_active_property,
|
225
225
|
log_depth: log_depth.to_i + 1)
|
226
|
-
log_debug("", depth: log_depth.to_i) {" => compacted key: #{item_active_property.inspect} for #{compacted_item.inspect}"}
|
226
|
+
# log_debug("", depth: log_depth.to_i) {" => compacted key: #{item_active_property.inspect} for #{compacted_item.inspect}"}
|
227
227
|
|
228
228
|
# handle @list
|
229
229
|
if list?(expanded_item)
|
@@ -345,7 +345,7 @@ module JSON::LD
|
|
345
345
|
result
|
346
346
|
else
|
347
347
|
# For other types, the compacted value is the element value
|
348
|
-
log_debug("compact", depth: log_depth.to_i) {element.class.to_s}
|
348
|
+
# log_debug("compact", depth: log_depth.to_i) {element.class.to_s}
|
349
349
|
element
|
350
350
|
end
|
351
351
|
|
data/lib/json/ld/context.rb
CHANGED
@@ -212,7 +212,7 @@ module JSON::LD
|
|
212
212
|
self.default_language = options[:language] if options[:language] =~ /^[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*$/
|
213
213
|
@term_definitions = options[:term_definitions] if options[:term_definitions]
|
214
214
|
|
215
|
-
#log_debug("init") {"iri_to_term: #{iri_to_term.inspect}"}
|
215
|
+
# log_debug("init") {"iri_to_term: #{iri_to_term.inspect}"}
|
216
216
|
|
217
217
|
yield(self) if block_given?
|
218
218
|
end
|
@@ -267,13 +267,13 @@ module JSON::LD
|
|
267
267
|
"Attempt to clear a context with protected terms"
|
268
268
|
end
|
269
269
|
when Context
|
270
|
-
log_debug("parse") {"context: #{context.inspect}"}
|
270
|
+
# log_debug("parse") {"context: #{context.inspect}"}
|
271
271
|
result = result.merge(context)
|
272
272
|
when IO, StringIO
|
273
|
-
log_debug("parse") {"io: #{context}"}
|
273
|
+
# log_debug("parse") {"io: #{context}"}
|
274
274
|
# Load context document, if it is an open file
|
275
275
|
begin
|
276
|
-
ctx =
|
276
|
+
ctx = load_context(context, **@options)
|
277
277
|
raise JSON::LD::JsonLdError::InvalidRemoteContext, "Context missing @context key" if @options[:validate] && ctx['@context'].nil?
|
278
278
|
result = result.parse(ctx["@context"] ? ctx["@context"] : {})
|
279
279
|
rescue JSON::ParserError => e
|
@@ -282,7 +282,7 @@ module JSON::LD
|
|
282
282
|
self
|
283
283
|
end
|
284
284
|
when String, RDF::URI
|
285
|
-
log_debug("parse") {"remote: #{context}, base: #{result.context_base || result.base}"}
|
285
|
+
# log_debug("parse") {"remote: #{context}, base: #{result.context_base || result.base}"}
|
286
286
|
|
287
287
|
# 3.2.1) Set context to the result of resolving value against the base IRI which is established as specified in section 5.1 Establishing a Base URI of [RFC3986]. Only the basic algorithm in section 5.2 of [RFC3986] is used; neither Syntax-Based Normalization nor Scheme-Based Normalization are performed. Characters additionally allowed in IRI references are treated in the same way that unreserved characters are treated in URI references, per section 6.5 of [RFC3987].
|
288
288
|
context = RDF::URI(result.context_base || base).join(context)
|
@@ -297,13 +297,14 @@ module JSON::LD
|
|
297
297
|
|
298
298
|
cached_context = if PRELOADED[context_canon.to_s]
|
299
299
|
# If we have a cached context, merge it into the current context (result) and use as the new context
|
300
|
-
log_debug("parse") {"=> cached_context: #{context_canon.to_s.inspect}"}
|
300
|
+
# log_debug("parse") {"=> cached_context: #{context_canon.to_s.inspect}"}
|
301
301
|
|
302
302
|
# If this is a Proc, then replace the entry with the result of running the Proc
|
303
303
|
if PRELOADED[context_canon.to_s].respond_to?(:call)
|
304
|
-
log_debug("parse") {"=> (call)"}
|
304
|
+
# log_debug("parse") {"=> (call)"}
|
305
305
|
PRELOADED[context_canon.to_s] = PRELOADED[context_canon.to_s].call
|
306
306
|
end
|
307
|
+
PRELOADED[context_canon.to_s].context_base ||= context_canon.to_s
|
307
308
|
PRELOADED[context_canon.to_s]
|
308
309
|
else
|
309
310
|
# Load context document, if it is a string
|
@@ -478,7 +479,7 @@ module JSON::LD
|
|
478
479
|
remote_contexts: [],
|
479
480
|
validate_scoped: true)
|
480
481
|
# Expand a string value, unless it matches a keyword
|
481
|
-
log_debug("create_term_definition") {"term = #{term.inspect}"}
|
482
|
+
# log_debug("create_term_definition") {"term = #{term.inspect}"}
|
482
483
|
|
483
484
|
# If defined contains the key term, then the associated value must be true, indicating that the term definition has already been created, so return. Otherwise, a cyclical term definition has been detected, which is an error.
|
484
485
|
case defined[term]
|
@@ -523,7 +524,7 @@ module JSON::LD
|
|
523
524
|
|
524
525
|
raise JsonLdError::InvalidTermDefinition, "Term definition for #{term.inspect} is an #{value.class} on term #{term.inspect}" unless value.is_a?(Hash)
|
525
526
|
|
526
|
-
#log_debug("") {"Hash[#{term.inspect}] = #{value.inspect}"}
|
527
|
+
# log_debug("") {"Hash[#{term.inspect}] = #{value.inspect}"}
|
527
528
|
definition = TermDefinition.new(term)
|
528
529
|
definition.simple = simple_term
|
529
530
|
|
@@ -565,7 +566,7 @@ module JSON::LD
|
|
565
566
|
elsif !JSON_LD_10_TYPE_VALUES.include?(type) && !(type.is_a?(RDF::URI) && type.absolute?)
|
566
567
|
raise JsonLdError::InvalidTypeMapping, "unknown mapping for '@type': #{type.inspect} on term #{term.inspect}"
|
567
568
|
end
|
568
|
-
#log_debug("") {"type_mapping: #{type.inspect}"}
|
569
|
+
# log_debug("") {"type_mapping: #{type.inspect}"}
|
569
570
|
definition.type_mapping = type
|
570
571
|
end
|
571
572
|
|
@@ -649,7 +650,7 @@ module JSON::LD
|
|
649
650
|
# Otherwise, term is an absolute IRI. Set the IRI mapping for definition to term
|
650
651
|
term
|
651
652
|
end
|
652
|
-
log_debug("") {"=> #{definition.id}"}
|
653
|
+
# log_debug("") {"=> #{definition.id}"}
|
653
654
|
elsif term.include?('/')
|
654
655
|
# If term is a relative IRI
|
655
656
|
definition.id = expand_iri(term, vocab: true)
|
@@ -662,13 +663,13 @@ module JSON::LD
|
|
662
663
|
# Otherwise, active context must have a vocabulary mapping, otherwise an invalid value has been detected, which is an error. Set the IRI mapping for definition to the result of concatenating the value associated with the vocabulary mapping and term.
|
663
664
|
raise JsonLdError::InvalidIRIMapping, "relative term definition without vocab: #{term} on term #{term.inspect}" unless vocab
|
664
665
|
definition.id = vocab + term
|
665
|
-
log_debug("") {"=> #{definition.id}"}
|
666
|
+
# log_debug("") {"=> #{definition.id}"}
|
666
667
|
end
|
667
668
|
|
668
669
|
@iri_to_term[definition.id] = term if simple_term && definition.id
|
669
670
|
|
670
671
|
if value.key?('@container')
|
671
|
-
#log_debug("") {"container_mapping: #{value['@container'].inspect}"}
|
672
|
+
# log_debug("") {"container_mapping: #{value['@container'].inspect}"}
|
672
673
|
definition.container_mapping = check_container(value['@container'], local_context, defined, term)
|
673
674
|
|
674
675
|
# If @container includes @type
|
@@ -702,7 +703,7 @@ module JSON::LD
|
|
702
703
|
when nil then [nil]
|
703
704
|
else value['@context']
|
704
705
|
end
|
705
|
-
log_debug("") {"context: #{definition.context.inspect}"}
|
706
|
+
# log_debug("") {"context: #{definition.context.inspect}"}
|
706
707
|
rescue JsonLdError => e
|
707
708
|
raise JsonLdError::InvalidScopedContext, "Term definition for #{term.inspect} contains illegal value for @context: #{e.message}"
|
708
709
|
end
|
@@ -722,14 +723,14 @@ module JSON::LD
|
|
722
723
|
else
|
723
724
|
raise JsonLdError::InvalidLanguageMapping, "language must be null or a string, was #{value['@language'].inspect}} on term #{term.inspect}"
|
724
725
|
end
|
725
|
-
#log_debug("") {"language_mapping: #{language.inspect}"}
|
726
|
+
# log_debug("") {"language_mapping: #{language.inspect}"}
|
726
727
|
definition.language_mapping = language || false
|
727
728
|
end
|
728
729
|
|
729
730
|
if value.key?('@direction')
|
730
731
|
direction = value['@direction']
|
731
732
|
raise JsonLdError::InvalidBaseDirection, "direction must be null, 'ltr', or 'rtl', was #{language.inspect}} on term #{term.inspect}" unless direction.nil? || %w(ltr rtl).include?(direction)
|
732
|
-
#log_debug("") {"direction_mapping: #{direction.inspect}"}
|
733
|
+
# log_debug("") {"direction_mapping: #{direction.inspect}"}
|
733
734
|
definition.direction_mapping = direction || false
|
734
735
|
end
|
735
736
|
|
@@ -737,7 +738,7 @@ module JSON::LD
|
|
737
738
|
nest = value['@nest']
|
738
739
|
raise JsonLdError::InvalidNestValue, "nest must be a string, was #{nest.inspect}} on term #{term.inspect}" unless nest.is_a?(String)
|
739
740
|
raise JsonLdError::InvalidNestValue, "nest must not be a keyword other than @nest, was #{nest.inspect}} on term #{term.inspect}" if nest.match?(/^@[a-zA-Z]+$/) && nest != '@nest'
|
740
|
-
#log_debug("") {"nest: #{nest.inspect}"}
|
741
|
+
# log_debug("") {"nest: #{nest.inspect}"}
|
741
742
|
definition.nest = nest
|
742
743
|
end
|
743
744
|
|
@@ -897,22 +898,21 @@ module JSON::LD
|
|
897
898
|
# @param [Hash{Symbol => Object}] options ({})
|
898
899
|
# @return [Hash]
|
899
900
|
def serialize(provided_context: nil, **options)
|
900
|
-
#log_debug("serlialize: generate context")
|
901
|
-
#log_debug("") {"=> context: #{inspect}"}
|
901
|
+
# log_debug("serlialize: generate context")
|
902
|
+
# log_debug("") {"=> context: #{inspect}"}
|
902
903
|
use_context = case provided_context
|
903
904
|
when String, RDF::URI
|
904
|
-
#log_debug "serlialize: reuse context: #{provided_context.inspect}"
|
905
|
+
# log_debug "serlialize: reuse context: #{provided_context.inspect}"
|
905
906
|
provided_context.to_s
|
906
907
|
when Hash
|
907
|
-
#log_debug "serlialize: reuse context: #{provided_context.inspect}"
|
908
|
+
# log_debug "serlialize: reuse context: #{provided_context.inspect}"
|
908
909
|
# If it has an @context entry use it, otherwise it is assumed to be the body of a context
|
909
910
|
provided_context.fetch('@context', provided_context)
|
910
911
|
when Array
|
911
|
-
#log_debug "serlialize: reuse context: #{provided_context.inspect}"
|
912
|
+
# log_debug "serlialize: reuse context: #{provided_context.inspect}"
|
912
913
|
provided_context
|
913
914
|
when IO, StringIO
|
914
|
-
provided_context.
|
915
|
-
JSON.load(provided_context).fetch('@context', {})
|
915
|
+
load_context(provided_context, **@options).fetch('@context', {})
|
916
916
|
else
|
917
917
|
ctx = {}
|
918
918
|
ctx['@version'] = 1.1 if @processingMode == 'json-ld-1.1'
|
@@ -1015,7 +1015,7 @@ module JSON::LD
|
|
1015
1015
|
#
|
1016
1016
|
# @return [TermDefinition]
|
1017
1017
|
def set_mapping(term, value)
|
1018
|
-
#log_debug("") {"map #{term.inspect} to #{value.inspect}"}
|
1018
|
+
# log_debug("") {"map #{term.inspect} to #{value.inspect}"}
|
1019
1019
|
term = term.to_s
|
1020
1020
|
term_definitions[term] = TermDefinition.new(term, id: value, simple: true, prefix: (value.to_s.end_with?(*PREFIX_URI_ENDINGS)))
|
1021
1021
|
term_definitions[term].simple = true
|
@@ -1467,8 +1467,6 @@ module JSON::LD
|
|
1467
1467
|
end
|
1468
1468
|
end
|
1469
1469
|
|
1470
|
-
RDF_LITERAL_NATIVE_TYPES = Set.new([RDF::XSD.boolean, RDF::XSD.integer, RDF::XSD.double]).freeze
|
1471
|
-
|
1472
1470
|
##
|
1473
1471
|
# If active property has a type mapping in the active context set to @id or @vocab, a JSON object with a single member @id whose value is the result of using the IRI Expansion algorithm on value is returned.
|
1474
1472
|
#
|
@@ -1491,7 +1489,7 @@ module JSON::LD
|
|
1491
1489
|
|
1492
1490
|
# If the active property has a type mapping in active context that is @id, return a new JSON object containing a single key-value pair where the key is @id and the value is the result of using the IRI Expansion algorithm, passing active context, value, and true for document relative.
|
1493
1491
|
if value.is_a?(String) && td.type_mapping == '@id'
|
1494
|
-
#log_debug("") {"as relative IRI: #{value.inspect}"}
|
1492
|
+
# log_debug("") {"as relative IRI: #{value.inspect}"}
|
1495
1493
|
return {'@id' => expand_iri(value, documentRelative: true, base: base).to_s}
|
1496
1494
|
end
|
1497
1495
|
|
@@ -1500,50 +1498,12 @@ module JSON::LD
|
|
1500
1498
|
return {'@id' => expand_iri(value, vocab: true, documentRelative: true, base: base).to_s}
|
1501
1499
|
end
|
1502
1500
|
|
1503
|
-
value = RDF::Literal(value) if
|
1504
|
-
value.is_a?(Date) ||
|
1505
|
-
value.is_a?(DateTime) ||
|
1506
|
-
value.is_a?(Time)
|
1507
|
-
|
1508
1501
|
result = case value
|
1509
1502
|
when RDF::URI, RDF::Node
|
1510
1503
|
{'@id' => value.to_s}
|
1511
|
-
when
|
1512
|
-
|
1513
|
-
|
1514
|
-
# Value parsed as JSON
|
1515
|
-
# FIXME: MultiJson
|
1516
|
-
res['@type'] = '@json'
|
1517
|
-
res['@value'] = ::JSON.parse(value.object)
|
1518
|
-
elsif value.datatype.start_with?("https://www.w3.org/ns/i18n#") && rdfDirection == 'i18n-datatype' && processingMode('json-ld-1.1')
|
1519
|
-
lang, dir = value.datatype.fragment.split('_')
|
1520
|
-
res['@value'] = value.to_s
|
1521
|
-
unless lang.empty?
|
1522
|
-
if lang !~ /^[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*$/
|
1523
|
-
if options[:validate]
|
1524
|
-
raise JsonLdError::InvalidLanguageMapping, "rdf:language must be valid BCP47: #{lang.inspect}"
|
1525
|
-
else
|
1526
|
-
warn "rdf:language must be valid BCP47: #{lang.inspect}"
|
1527
|
-
end
|
1528
|
-
end
|
1529
|
-
res['@language'] = lang
|
1530
|
-
end
|
1531
|
-
res['@direction'] = dir
|
1532
|
-
elsif useNativeTypes && RDF_LITERAL_NATIVE_TYPES.include?(value.datatype) && value.valid?
|
1533
|
-
res['@type'] = uri(coerce(property)) if coerce(property)
|
1534
|
-
res['@value'] = value.object
|
1535
|
-
else
|
1536
|
-
value.canonicalize! if value.valid? && value.datatype == RDF::XSD.double
|
1537
|
-
if coerce(property)
|
1538
|
-
res['@type'] = uri(coerce(property)).to_s
|
1539
|
-
elsif value.datatype?
|
1540
|
-
res['@type'] = uri(value.datatype).to_s
|
1541
|
-
elsif value.language? || language(property)
|
1542
|
-
res['@language'] = (value.language || language(property)).to_s
|
1543
|
-
end
|
1544
|
-
res['@value'] = value.to_s
|
1545
|
-
end
|
1546
|
-
res
|
1504
|
+
when Date, DateTime, Time
|
1505
|
+
lit = RDF::Literal.new(value)
|
1506
|
+
{'@value' => lit.to_s, '@type' => lit.datatype.to_s}
|
1547
1507
|
else
|
1548
1508
|
# Otherwise, initialize result to a JSON object with an @value member whose value is set to value.
|
1549
1509
|
res = {}
|
@@ -1561,8 +1521,6 @@ module JSON::LD
|
|
1561
1521
|
end
|
1562
1522
|
|
1563
1523
|
result
|
1564
|
-
rescue ::JSON::ParserError => e
|
1565
|
-
raise JSON::LD::JsonLdError::InvalidJsonLiteral, e.message
|
1566
1524
|
end
|
1567
1525
|
|
1568
1526
|
##
|
@@ -1579,7 +1537,7 @@ module JSON::LD
|
|
1579
1537
|
# @see https://www.w3.org/TR/json-ld11-api/#value-compaction
|
1580
1538
|
# FIXME: revisit the specification version of this.
|
1581
1539
|
def compact_value(property, value, base: nil)
|
1582
|
-
#log_debug("compact_value") {"property: #{property.inspect}, value: #{value.inspect}"}
|
1540
|
+
# log_debug("compact_value") {"property: #{property.inspect}, value: #{value.inspect}"}
|
1583
1541
|
|
1584
1542
|
indexing = index?(value) && container(property).include?('@index')
|
1585
1543
|
language = language(property)
|
@@ -1588,25 +1546,25 @@ module JSON::LD
|
|
1588
1546
|
result = case
|
1589
1547
|
when coerce(property) == '@id' && value.key?('@id') && (value.keys - %w(@id @index)).empty?
|
1590
1548
|
# Compact an @id coercion
|
1591
|
-
#log_debug("") {" (@id & coerce)"}
|
1549
|
+
# log_debug("") {" (@id & coerce)"}
|
1592
1550
|
compact_iri(value['@id'], base: base)
|
1593
1551
|
when coerce(property) == '@vocab' && value.key?('@id') && (value.keys - %w(@id @index)).empty?
|
1594
1552
|
# Compact an @id coercion
|
1595
|
-
#log_debug("") {" (@id & coerce & vocab)"}
|
1553
|
+
# log_debug("") {" (@id & coerce & vocab)"}
|
1596
1554
|
compact_iri(value['@id'], vocab: true)
|
1597
1555
|
when value.key?('@id')
|
1598
|
-
#log_debug("") {" (@id)"}
|
1556
|
+
# log_debug("") {" (@id)"}
|
1599
1557
|
# return value as is
|
1600
1558
|
value
|
1601
1559
|
when value['@type'] && value['@type'] == coerce(property)
|
1602
1560
|
# Compact common datatype
|
1603
|
-
#log_debug("") {" (@type & coerce) == #{coerce(property)}"}
|
1561
|
+
# log_debug("") {" (@type & coerce) == #{coerce(property)}"}
|
1604
1562
|
value['@value']
|
1605
1563
|
when coerce(property) == '@none' || value['@type']
|
1606
1564
|
# use original expanded value
|
1607
1565
|
value
|
1608
1566
|
when !value['@value'].is_a?(String)
|
1609
|
-
#log_debug("") {" (native)"}
|
1567
|
+
# log_debug("") {" (native)"}
|
1610
1568
|
indexing || !index?(value) ? value['@value'] : value
|
1611
1569
|
when value['@language'].to_s.downcase == language.to_s.downcase && value['@direction'] == direction
|
1612
1570
|
# Compact language and direction
|
@@ -1627,7 +1585,7 @@ module JSON::LD
|
|
1627
1585
|
|
1628
1586
|
# If the result is an object, tranform keys using any term keyword aliases
|
1629
1587
|
if result.is_a?(Hash) && result.keys.any? {|k| self.alias(k) != k}
|
1630
|
-
#log_debug("") {" (map to key aliases)"}
|
1588
|
+
# log_debug("") {" (map to key aliases)"}
|
1631
1589
|
new_element = {}
|
1632
1590
|
result.each do |k, v|
|
1633
1591
|
new_element[self.alias(k)] = v
|
@@ -1635,7 +1593,7 @@ module JSON::LD
|
|
1635
1593
|
result = new_element
|
1636
1594
|
end
|
1637
1595
|
|
1638
|
-
#log_debug("") {"=> #{result.inspect}"}
|
1596
|
+
# log_debug("") {"=> #{result.inspect}"}
|
1639
1597
|
result
|
1640
1598
|
end
|
1641
1599
|
|
@@ -1731,11 +1689,21 @@ module JSON::LD
|
|
1731
1689
|
CONTEXT_BASE_FRAG_OR_QUERY = %w(? #).freeze
|
1732
1690
|
CONTEXT_TYPE_ID_VOCAB = %w(@id @vocab).freeze
|
1733
1691
|
|
1692
|
+
##
|
1693
|
+
# Reads the `@context` from an IO
|
1694
|
+
def load_context(io, **options)
|
1695
|
+
io.rewind
|
1696
|
+
remote_doc = API.loadRemoteDocument(io, **options)
|
1697
|
+
remote_doc.document.is_a?(String) ?
|
1698
|
+
MultiJson.load(remote_doc.document) :
|
1699
|
+
remote_doc.document
|
1700
|
+
end
|
1701
|
+
|
1734
1702
|
def uri(value)
|
1735
1703
|
case value.to_s
|
1736
1704
|
when /^_:(.*)$/
|
1737
1705
|
# Map BlankNodes if a namer is given
|
1738
|
-
#log_debug "uri(bnode)#{value}: #{$1}"
|
1706
|
+
# log_debug "uri(bnode)#{value}: #{$1}"
|
1739
1707
|
bnode(namer.get_sym($1))
|
1740
1708
|
else
|
1741
1709
|
value = RDF::URI(value)
|
@@ -1854,25 +1822,25 @@ module JSON::LD
|
|
1854
1822
|
# for the type mapping or language mapping
|
1855
1823
|
# @return [String]
|
1856
1824
|
def select_term(iri, containers, type_language, preferred_values)
|
1857
|
-
#log_debug("select_term") {
|
1825
|
+
# log_debug("select_term") {
|
1858
1826
|
# "iri: #{iri.inspect}, " +
|
1859
1827
|
# "containers: #{containers.inspect}, " +
|
1860
1828
|
# "type_language: #{type_language.inspect}, " +
|
1861
1829
|
# "preferred_values: #{preferred_values.inspect}"
|
1862
1830
|
#}
|
1863
1831
|
container_map = inverse_context[iri]
|
1864
|
-
#log_debug(" ") {"container_map: #{container_map.inspect}"}
|
1832
|
+
# log_debug(" ") {"container_map: #{container_map.inspect}"}
|
1865
1833
|
containers.each do |container|
|
1866
1834
|
next unless container_map.key?(container)
|
1867
1835
|
tl_map = container_map[container]
|
1868
1836
|
value_map = tl_map[type_language]
|
1869
1837
|
preferred_values.each do |item|
|
1870
1838
|
next unless value_map.key?(item)
|
1871
|
-
#log_debug("=>") {value_map[item].inspect}
|
1839
|
+
# log_debug("=>") {value_map[item].inspect}
|
1872
1840
|
return value_map[item]
|
1873
1841
|
end
|
1874
1842
|
end
|
1875
|
-
#log_debug("=>") {"nil"}
|
1843
|
+
# log_debug("=>") {"nil"}
|
1876
1844
|
nil
|
1877
1845
|
end
|
1878
1846
|
|