json-ld 2.1.7 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +80 -0
- data/VERSION +1 -1
- data/lib/json/ld/compact.rb +56 -10
- data/lib/json/ld/context.rb +100 -38
- data/lib/json/ld/expand.rb +35 -16
- data/lib/json/ld/utils.rb +22 -0
- data/spec/api_spec.rb +1 -2
- data/spec/compact_spec.rb +296 -2
- data/spec/context_spec.rb +101 -29
- data/spec/expand_spec.rb +491 -189
- data/spec/flatten_spec.rb +1 -2
- data/spec/format_spec.rb +1 -2
- data/spec/frame_spec.rb +1 -2
- data/spec/from_rdf_spec.rb +1 -2
- data/spec/reader_spec.rb +1 -2
- data/spec/resource_spec.rb +1 -2
- data/spec/spec_helper.rb +1 -1
- data/spec/streaming_writer_spec.rb +1 -2
- data/spec/suite_compact_spec.rb +2 -3
- data/spec/suite_error_spec.rb +2 -3
- data/spec/suite_expand_spec.rb +2 -3
- data/spec/suite_flatten_spec.rb +2 -4
- data/spec/suite_frame_spec.rb +2 -4
- data/spec/suite_from_rdf_spec.rb +2 -3
- data/spec/suite_helper.rb +1 -2
- data/spec/suite_remote_doc_spec.rb +2 -3
- data/spec/suite_to_rdf_spec.rb +2 -3
- data/spec/to_rdf_spec.rb +1 -2
- data/spec/writer_spec.rb +1 -2
- metadata +131 -89
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 93516bb49f7999bcda524b639c817eb197acc412
|
4
|
+
data.tar.gz: 3f3a0ce771608fb40714dd05a45c9fcdec5cf21a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 80be800ae35b9906c8f289eff34b7eaa84a4d637e883f1c8d1452a4516f98daa7a63b77bddacc8791e9caf4131018ea0994f4a023557e9e9cc0587234ad85d3e
|
7
|
+
data.tar.gz: 2234dbcec6f4701da4adb9fd3b90bbf6cb3c2918c9be1394756a2ddfd10c28931d44a911e6f1a5a2fbbb7082bf9631e0da100119cccd7a1af8c3463bf9c5be60
|
data/README.md
CHANGED
@@ -298,6 +298,86 @@ The value of `@container` in a term definition can include `@id` or `@type`, in
|
|
298
298
|
}
|
299
299
|
}
|
300
300
|
|
301
|
+
### @graph containers and maps
|
302
|
+
A term can have `@container` set to include `@graph` optionally including `@id` or `@index` and `@set`. In the first form, with `@container` set to `@graph`, the value of a property is treated as a _simple graph object_, meaning that values treated as if they were contained in an object with `@graph`, creating _named graph_ with an anonymous name.
|
303
|
+
|
304
|
+
{
|
305
|
+
"@context": {
|
306
|
+
"@vocab": "http://example.org/",
|
307
|
+
"input": {"@container": "@graph"}
|
308
|
+
},
|
309
|
+
"input": {
|
310
|
+
"value": "x"
|
311
|
+
}
|
312
|
+
}
|
313
|
+
|
314
|
+
which expands to the following:
|
315
|
+
|
316
|
+
[{
|
317
|
+
"http://example.org/input": [{
|
318
|
+
"@graph": [{
|
319
|
+
"http://example.org/value": [{"@value": "x"}]
|
320
|
+
}]
|
321
|
+
}]
|
322
|
+
}]
|
323
|
+
|
324
|
+
Compaction reverses this process, optionally ensuring that a single value is contained within an array of `@container` also includes `@set`:
|
325
|
+
|
326
|
+
{
|
327
|
+
"@context": {
|
328
|
+
"@vocab": "http://example.org/",
|
329
|
+
"input": {"@container": ["@graph", "@set"]}
|
330
|
+
}
|
331
|
+
}
|
332
|
+
|
333
|
+
A graph map uses the map form already existing for `@index`, `@language`, `@type`, and `@id` where the index is either an index value or an id.
|
334
|
+
|
335
|
+
{
|
336
|
+
"@context": {
|
337
|
+
"@vocab": "http://example.org/",
|
338
|
+
"input": {"@container": ["@graph", "@index"]}
|
339
|
+
},
|
340
|
+
"input": {
|
341
|
+
"g1": {"value": "x"}
|
342
|
+
}
|
343
|
+
}
|
344
|
+
|
345
|
+
treats "g1" as an index, and expands to the following:
|
346
|
+
|
347
|
+
[{
|
348
|
+
"http://example.org/input": [{
|
349
|
+
"@index": "g1",
|
350
|
+
"@graph": [{
|
351
|
+
"http://example.org/value": [{"@value": "x"}]
|
352
|
+
}]
|
353
|
+
}]
|
354
|
+
}])
|
355
|
+
|
356
|
+
This can also include `@set` to ensure that, when compacting, a single value of an index will be in array form.
|
357
|
+
|
358
|
+
The _id_ version is similar:
|
359
|
+
|
360
|
+
{
|
361
|
+
"@context": {
|
362
|
+
"@vocab": "http://example.org/",
|
363
|
+
"input": {"@container": ["@graph", "@id"]}
|
364
|
+
},
|
365
|
+
"input": {
|
366
|
+
"http://example.com/g1": {"value": "x"}
|
367
|
+
}
|
368
|
+
}
|
369
|
+
|
370
|
+
which expands to:
|
371
|
+
|
372
|
+
[{
|
373
|
+
"http://example.org/input": [{
|
374
|
+
"@id": "http://example.com/g1",
|
375
|
+
"@graph": [{
|
376
|
+
"http://example.org/value": [{"@value": "x"}]
|
377
|
+
}]
|
378
|
+
}]
|
379
|
+
}])
|
380
|
+
|
301
381
|
### Transparent Nesting
|
302
382
|
Many JSON APIs separate properties from their entities using an intermediate object. For example, a set of possible labels may be grouped under a common property:
|
303
383
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.2.0
|
data/lib/json/ld/compact.rb
CHANGED
@@ -82,6 +82,7 @@ module JSON::LD
|
|
82
82
|
if expanded_property == '@reverse'
|
83
83
|
compacted_value = compact(expanded_value, property: '@reverse')
|
84
84
|
#log_debug("@reverse") {"compacted_value: #{compacted_value.inspect}"}
|
85
|
+
# handle double-reversed properties
|
85
86
|
compacted_value.each do |prop, value|
|
86
87
|
if context.reverse?(prop)
|
87
88
|
value = [value] if !value.is_a?(Array) &&
|
@@ -112,7 +113,7 @@ module JSON::LD
|
|
112
113
|
next
|
113
114
|
end
|
114
115
|
|
115
|
-
if expanded_property == '@index' && context.container(property) ==
|
116
|
+
if expanded_property == '@index' && context.container(property) == %w(@index)
|
116
117
|
#log_debug("@index") {"drop @index"}
|
117
118
|
next
|
118
119
|
end
|
@@ -162,13 +163,20 @@ module JSON::LD
|
|
162
163
|
|
163
164
|
container = context.container(item_active_property)
|
164
165
|
as_array = context.as_array?(item_active_property)
|
165
|
-
|
166
|
+
|
167
|
+
value = case
|
168
|
+
when list?(expanded_item) then expanded_item['@list']
|
169
|
+
when graph?(expanded_item) then expanded_item['@graph']
|
170
|
+
else expanded_item
|
171
|
+
end
|
172
|
+
|
166
173
|
compacted_item = compact(value, property: item_active_property)
|
167
174
|
#log_debug("") {" => compacted key: #{item_active_property.inspect} for #{compacted_item.inspect}"}
|
168
175
|
|
176
|
+
# handle @list
|
169
177
|
if list?(expanded_item)
|
170
178
|
compacted_item = [compacted_item] unless compacted_item.is_a?(Array)
|
171
|
-
unless container ==
|
179
|
+
unless container == %w(@list)
|
172
180
|
al = context.compact_iri('@list', vocab: true, quiet: true)
|
173
181
|
compacted_item = {al => compacted_item}
|
174
182
|
if expanded_item.has_key?('@index')
|
@@ -178,25 +186,63 @@ module JSON::LD
|
|
178
186
|
else
|
179
187
|
raise JsonLdError::CompactionToListOfLists,
|
180
188
|
"key cannot have more than one list value" if nest_result.has_key?(item_active_property)
|
189
|
+
# Falls through to add list value below
|
181
190
|
end
|
182
191
|
end
|
183
192
|
|
184
|
-
|
193
|
+
# Graph object compaction cases:
|
194
|
+
if graph?(expanded_item)
|
195
|
+
if container.include?('@graph') && container.include?('@id')
|
196
|
+
# container includes @graph and @id
|
197
|
+
map_object = nest_result[item_active_property] ||= {}
|
198
|
+
map_key = expanded_item['@id']
|
199
|
+
# If there is no @id, create a blank node identifier to use as an index
|
200
|
+
map_key = map_key ? context.compact_iri(map_key, quiet: true) : namer.get_name
|
201
|
+
merge_compacted_value(map_object, map_key, compacted_item)
|
202
|
+
elsif container.include?('@graph') && container.include?('@index') && simple_graph?(expanded_item)
|
203
|
+
# container includes @graph and @index and value is a simple graph object
|
204
|
+
map_object = nest_result[item_active_property] ||= {}
|
205
|
+
# If there is no @index, use @none
|
206
|
+
map_key = expanded_item['@index'] || '@none'
|
207
|
+
merge_compacted_value(map_object, map_key, compacted_item)
|
208
|
+
elsif container.include?('@graph') && simple_graph?(expanded_item)
|
209
|
+
# container includes @graph but not @id or @index and value is a simple graph object
|
210
|
+
# Drop through, where compacted_value will be added
|
211
|
+
compacted_item = [compacted_item] if
|
212
|
+
!compacted_item.is_a?(Array) && (!@options[:compactArrays] || as_array)
|
213
|
+
merge_compacted_value(nest_result, item_active_property, compacted_item)
|
214
|
+
else
|
215
|
+
# container does not include @graph or otherwise does not match one of the previous cases, redo compacted_item
|
216
|
+
compacted_item = [compacted_item]
|
217
|
+
al = context.compact_iri('@graph', vocab: true, quiet: true)
|
218
|
+
compacted_item = {al => compacted_item}
|
219
|
+
if expanded_item['@id']
|
220
|
+
al = context.compact_iri('@id', vocab: true, quiet: true)
|
221
|
+
compacted_item[al] = context.compact_iri(expanded_item['@id'], vocab: false, quiet: true).to_s
|
222
|
+
end
|
223
|
+
if expanded_item.has_key?('@index')
|
224
|
+
key = context.compact_iri('@index', vocab: true, quiet: true)
|
225
|
+
compacted_item[key] = expanded_item['@index']
|
226
|
+
end
|
227
|
+
compacted_item = [compacted_item] if !@options[:compactArrays] || as_array
|
228
|
+
merge_compacted_value(nest_result, item_active_property, compacted_item)
|
229
|
+
end
|
230
|
+
elsif !(container & %w(@language @index @id @type)).empty? && !container.include?('@graph')
|
185
231
|
map_object = nest_result[item_active_property] ||= {}
|
186
232
|
compacted_item = case container
|
187
|
-
when
|
233
|
+
when %w(@id)
|
188
234
|
id_prop = context.compact_iri('@id', vocab: true, quiet: true)
|
189
235
|
map_key = compacted_item[id_prop]
|
190
236
|
map_key = context.compact_iri(map_key, quiet: true)
|
191
237
|
compacted_item.delete(id_prop)
|
192
238
|
compacted_item
|
193
|
-
when
|
194
|
-
map_key = expanded_item[
|
239
|
+
when %w(@index)
|
240
|
+
map_key = expanded_item['@index']
|
195
241
|
compacted_item
|
196
|
-
when
|
197
|
-
map_key = expanded_item[
|
242
|
+
when %w(@language)
|
243
|
+
map_key = expanded_item['@language']
|
198
244
|
value?(expanded_item) ? expanded_item['@value'] : compacted_item
|
199
|
-
when
|
245
|
+
when %w(@type)
|
200
246
|
type_prop = context.compact_iri('@type', vocab: true, quiet: true)
|
201
247
|
map_key, *types = Array(compacted_item[type_prop])
|
202
248
|
map_key = context.compact_iri(map_key, vocab: true, quiet: true)
|
data/lib/json/ld/context.rb
CHANGED
@@ -38,13 +38,9 @@ module JSON::LD
|
|
38
38
|
attr_accessor :type_mapping
|
39
39
|
|
40
40
|
# Base container mapping, without @set
|
41
|
-
# @return
|
41
|
+
# @return Array<'@index', '@language', '@index', '@set', '@type', '@id', '@graph'> Container mapping
|
42
42
|
attr_reader :container_mapping
|
43
43
|
|
44
|
-
# If container mapping was defined along with @set
|
45
|
-
# @return [Boolean]
|
46
|
-
attr_reader :as_set
|
47
|
-
|
48
44
|
# @return [String] Term used for nest properties
|
49
45
|
attr_accessor :nest
|
50
46
|
|
@@ -78,7 +74,7 @@ module JSON::LD
|
|
78
74
|
# @param [String] term
|
79
75
|
# @param [String] id
|
80
76
|
# @param [String] type_mapping Type mapping
|
81
|
-
# @param ['@index', '@language', '@index', '@set', '@type', '@id'] container_mapping
|
77
|
+
# @param [Array<'@index', '@language', '@index', '@set', '@type', '@id', '@graph'>] container_mapping
|
82
78
|
# @param [String] language_mapping
|
83
79
|
# Language mapping of term, `false` is used if there is explicitly no language mapping for this term
|
84
80
|
# @param [Boolean] reverse_property
|
@@ -100,7 +96,7 @@ module JSON::LD
|
|
100
96
|
@term = term
|
101
97
|
@id = id.to_s unless id.nil?
|
102
98
|
@type_mapping = type_mapping.to_s unless type_mapping.nil?
|
103
|
-
self.container_mapping = container_mapping
|
99
|
+
self.container_mapping = container_mapping
|
104
100
|
@language_mapping = language_mapping unless language_mapping.nil?
|
105
101
|
@reverse_property = reverse_property
|
106
102
|
@nest = nest unless nest.nil?
|
@@ -116,7 +112,7 @@ module JSON::LD
|
|
116
112
|
mapping = mapping.dup
|
117
113
|
mapping.delete('@set')
|
118
114
|
end
|
119
|
-
@container_mapping = mapping.
|
115
|
+
@container_mapping = mapping.sort
|
120
116
|
end
|
121
117
|
|
122
118
|
##
|
@@ -147,7 +143,7 @@ module JSON::LD
|
|
147
143
|
end
|
148
144
|
end
|
149
145
|
|
150
|
-
cm =
|
146
|
+
cm = (Array(container_mapping) + (as_set? ? %w(@set) : [])).compact
|
151
147
|
cm = cm.first if cm.length == 1
|
152
148
|
defn['@container'] = cm unless cm.empty?
|
153
149
|
# Language set as false to be output as null
|
@@ -168,21 +164,26 @@ module JSON::LD
|
|
168
164
|
%w(id type_mapping container_mapping language_mapping reverse_property nest simple prefix context).each do |acc|
|
169
165
|
v = instance_variable_get("@#{acc}".to_sym)
|
170
166
|
v = v.to_s if v.is_a?(RDF::Term)
|
171
|
-
if acc == 'container_mapping'
|
172
|
-
v
|
167
|
+
if acc == 'container_mapping'
|
168
|
+
v.concat(%w(@set)) if as_set?
|
169
|
+
v = v.first if v.length <= 1
|
173
170
|
end
|
174
171
|
defn << "#{acc}: #{v.inspect}" if v
|
175
172
|
end
|
176
173
|
defn.join(', ') + ")"
|
177
174
|
end
|
178
175
|
|
176
|
+
# If container mapping was defined along with @set
|
177
|
+
# @return [Boolean]
|
178
|
+
def as_set?; @as_set || false; end
|
179
|
+
|
179
180
|
def inspect
|
180
181
|
v = %w([TD)
|
181
182
|
v << "id=#{@id}"
|
182
183
|
v << "term=#{@term}"
|
183
184
|
v << "rev" if reverse_property
|
184
185
|
v << "container=#{container_mapping}" if container_mapping
|
185
|
-
v << "as_set=#{as_set
|
186
|
+
v << "as_set=#{as_set?.inspect}"
|
186
187
|
v << "lang=#{language_mapping.inspect}" unless language_mapping.nil?
|
187
188
|
v << "type=#{type_mapping}" unless type_mapping.nil?
|
188
189
|
v << "nest=#{nest.inspect}" unless nest.nil?
|
@@ -874,23 +875,22 @@ module JSON::LD
|
|
874
875
|
# Retrieve container mapping, add it if `value` is provided
|
875
876
|
#
|
876
877
|
# @param [Term, #to_s] term in unexpanded form
|
877
|
-
# @return [
|
878
|
+
# @return [Array<'@index', '@language', '@index', '@set', '@type', '@id', '@graph'>]
|
878
879
|
def container(term)
|
879
|
-
return
|
880
|
-
return term if KEYWORDS.include?(term)
|
880
|
+
return [term] if KEYWORDS.include?(term)
|
881
881
|
term = find_definition(term)
|
882
|
-
term
|
882
|
+
term ? term.container_mapping : []
|
883
883
|
end
|
884
884
|
|
885
885
|
##
|
886
|
-
# Should values be represented
|
886
|
+
# Should values be represented using an array?
|
887
887
|
#
|
888
888
|
# @param [Term, #to_s] term in unexpanded form
|
889
889
|
# @return [Boolean]
|
890
890
|
def as_array?(term)
|
891
|
-
return true if term
|
891
|
+
return true if CONTEXT_CONTAINER_ARRAY_TERMS.include?(term)
|
892
892
|
term = find_definition(term)
|
893
|
-
term && (term.as_set || term.container_mapping
|
893
|
+
term && (term.as_set? || term.container_mapping.include?('@list'))
|
894
894
|
end
|
895
895
|
|
896
896
|
##
|
@@ -1122,6 +1122,11 @@ module JSON::LD
|
|
1122
1122
|
tl_value = common_language
|
1123
1123
|
end
|
1124
1124
|
#log_debug("") {"list: containers: #{containers.inspect}, type/language: #{tl.inspect}, type/language value: #{tl_value.inspect}"} unless quiet
|
1125
|
+
elsif graph?(value)
|
1126
|
+
# TODO: support `@graphId`?
|
1127
|
+
# TODO: "@graph@set"?
|
1128
|
+
containers << '@graph'
|
1129
|
+
containers << '@set'
|
1125
1130
|
else
|
1126
1131
|
if value?(value)
|
1127
1132
|
if value.has_key?('@language') && !index?(value)
|
@@ -1228,14 +1233,16 @@ module JSON::LD
|
|
1228
1233
|
def expand_value(property, value, useNativeTypes: false, **options)
|
1229
1234
|
#log_debug("expand_value") {"property: #{property.inspect}, value: #{value.inspect}"}
|
1230
1235
|
|
1236
|
+
td = term_definitions.fetch(property, TermDefinition.new(property))
|
1237
|
+
|
1231
1238
|
# 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.
|
1232
|
-
if
|
1239
|
+
if value.is_a?(String) && td.type_mapping == '@id'
|
1233
1240
|
#log_debug("") {"as relative IRI: #{value.inspect}"}
|
1234
1241
|
return {'@id' => expand_iri(value, documentRelative: true).to_s}
|
1235
1242
|
end
|
1236
1243
|
|
1237
1244
|
# If active property has a type mapping in active context that is @vocab, 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, true for vocab, and true for document relative.
|
1238
|
-
if td.type_mapping == '@vocab'
|
1245
|
+
if value.is_a?(String) && td.type_mapping == '@vocab'
|
1239
1246
|
#log_debug("") {"as vocab IRI: #{value.inspect}"}
|
1240
1247
|
return {'@id' => expand_iri(value, vocab: true, documentRelative: true).to_s}
|
1241
1248
|
end
|
@@ -1271,15 +1278,14 @@ module JSON::LD
|
|
1271
1278
|
# Otherwise, initialize result to a JSON object with an @value member whose value is set to value.
|
1272
1279
|
res = {'@value' => value}
|
1273
1280
|
|
1274
|
-
if td.type_mapping
|
1281
|
+
if td.type_mapping && !%w(@id @vocab).include?(td.type_mapping.to_s)
|
1275
1282
|
res['@type'] = td.type_mapping.to_s
|
1276
|
-
elsif value.is_a?(String)
|
1277
|
-
|
1278
|
-
|
1279
|
-
|
1280
|
-
res['@language'] = default_language
|
1281
|
-
end
|
1283
|
+
elsif value.is_a?(String) && td.language_mapping
|
1284
|
+
res['@language'] = td.language_mapping
|
1285
|
+
elsif value.is_a?(String) && default_language && td.language_mapping.nil?
|
1286
|
+
res['@language'] = default_language
|
1282
1287
|
end
|
1288
|
+
|
1283
1289
|
res
|
1284
1290
|
end
|
1285
1291
|
|
@@ -1305,7 +1311,7 @@ module JSON::LD
|
|
1305
1311
|
|
1306
1312
|
num_members = value.length
|
1307
1313
|
|
1308
|
-
num_members -= 1 if index?(value) && container(property)
|
1314
|
+
num_members -= 1 if index?(value) && container(property).include?('@index')
|
1309
1315
|
if num_members > 2
|
1310
1316
|
#log_debug("") {"can't compact value with # members > 2"}
|
1311
1317
|
return value
|
@@ -1442,6 +1448,10 @@ module JSON::LD
|
|
1442
1448
|
|
1443
1449
|
private
|
1444
1450
|
|
1451
|
+
CONTEXT_CONTAINER_ARRAY_TERMS = %w(@set @list @graph).freeze
|
1452
|
+
CONTEXT_CONTAINER_ID_GRAPH = %w(@id @graph).freeze
|
1453
|
+
CONTEXT_CONTAINER_INDEX_GRAPH = %w(@index @graph).freeze
|
1454
|
+
|
1445
1455
|
def uri(value)
|
1446
1456
|
case value.to_s
|
1447
1457
|
when /^_:(.*)$/
|
@@ -1482,7 +1492,26 @@ module JSON::LD
|
|
1482
1492
|
#
|
1483
1493
|
# To make use of an inverse context, a list of preferred container mappings and the type mapping or language mapping are gathered for a particular value associated with an IRI. These parameters are then fed to the Term Selection algorithm, which will find the term that most appropriately matches the value's mappings.
|
1484
1494
|
#
|
1495
|
+
# @example Basic structure of resulting inverse context
|
1496
|
+
# {
|
1497
|
+
# "http://example.com/term": {
|
1498
|
+
# "@language": {
|
1499
|
+
# "@null": "term",
|
1500
|
+
# "@none": "term",
|
1501
|
+
# "en": "term"
|
1502
|
+
# },
|
1503
|
+
# "@type": {
|
1504
|
+
# "@reverse": "term",
|
1505
|
+
# "@none": "term",
|
1506
|
+
# "http://datatype": "term"
|
1507
|
+
# },
|
1508
|
+
# "@any": {
|
1509
|
+
# "@none": "term",
|
1510
|
+
# }
|
1511
|
+
# }
|
1512
|
+
# }
|
1485
1513
|
# @return [Hash{String => Hash{String => String}}]
|
1514
|
+
# @todo May want to include @set along with container to allow selecting terms using @set over those without @set. May require adding some notion of value cardinality to compact_iri
|
1486
1515
|
def inverse_context
|
1487
1516
|
@inverse_context ||= begin
|
1488
1517
|
result = {}
|
@@ -1491,7 +1520,15 @@ module JSON::LD
|
|
1491
1520
|
a.length == b.length ? (a <=> b) : (a.length <=> b.length)
|
1492
1521
|
end.each do |term|
|
1493
1522
|
next unless td = term_definitions[term]
|
1494
|
-
|
1523
|
+
|
1524
|
+
container = Array(td.container_mapping).sort.first
|
1525
|
+
container ||= td.as_set? ? %(@set) : %(@none)
|
1526
|
+
# FIXME: Alternative to consider
|
1527
|
+
## Creates "@language", "@language@set", "@set", or "@none"
|
1528
|
+
## for each of "@language", "@index", "@type", "@id", "@list", and "@graph"
|
1529
|
+
#container = td.container_mapping.to_s
|
1530
|
+
#container += '@set' if td.as_set?
|
1531
|
+
#container = '@none' if container.empty?
|
1495
1532
|
container_map = result[td.id.to_s] ||= {}
|
1496
1533
|
tl_map = container_map[container] ||= {'@language' => {}, '@type' => {}, '@any' => {}}
|
1497
1534
|
type_map = tl_map['@type']
|
@@ -1620,20 +1657,45 @@ module JSON::LD
|
|
1620
1657
|
val = Array(container).dup
|
1621
1658
|
val.delete('@set') if has_set = val.include?('@set')
|
1622
1659
|
|
1623
|
-
|
1624
|
-
"'@container' has more than one value other than @set" if val.length > 1
|
1625
|
-
|
1626
|
-
case val.first
|
1627
|
-
when '@list'
|
1660
|
+
if val.include?('@list')
|
1628
1661
|
raise JsonLdError::InvalidContainerMapping,
|
1629
|
-
"'@container' on term #{term.inspect} cannot
|
1662
|
+
"'@container' on term #{term.inspect} using @list cannot have any other values" unless
|
1663
|
+
!has_set && val.length == 1
|
1630
1664
|
# Okay
|
1631
|
-
|
1665
|
+
elsif val.include?('@language')
|
1666
|
+
raise JsonLdError::InvalidContainerMapping,
|
1667
|
+
"unknown mapping for '@container' to #{container.inspect} on term #{term.inspect}" if
|
1668
|
+
has_set && (processingMode || 'json-ld-1.0') < 'json-ld-1.1'
|
1669
|
+
raise JsonLdError::InvalidContainerMapping,
|
1670
|
+
"'@container' on term #{term.inspect} using @language cannot have any values other than @set, found #{container.inspect}" unless
|
1671
|
+
val.length == 1
|
1672
|
+
# Okay
|
1673
|
+
elsif val.include?('@index')
|
1674
|
+
raise JsonLdError::InvalidContainerMapping,
|
1675
|
+
"unknown mapping for '@container' to #{container.inspect} on term #{term.inspect}" if
|
1676
|
+
has_set && (processingMode || 'json-ld-1.0') < 'json-ld-1.1'
|
1677
|
+
raise JsonLdError::InvalidContainerMapping,
|
1678
|
+
"'@container' on term #{term.inspect} using @index cannot have any values other than @set and/or @graph, found #{container.inspect}" unless
|
1679
|
+
(val - CONTEXT_CONTAINER_INDEX_GRAPH).empty?
|
1680
|
+
# Okay
|
1681
|
+
elsif val.include?('@id')
|
1682
|
+
raise JsonLdError::InvalidContainerMapping,
|
1683
|
+
"unknown mapping for '@container' to #{container.inspect} on term #{term.inspect}" if
|
1684
|
+
(processingMode || 'json-ld-1.0') < 'json-ld-1.1'
|
1685
|
+
raise JsonLdError::InvalidContainerMapping,
|
1686
|
+
"'@container' on term #{term.inspect} using @id cannot have any values other than @set and/or @graph, found #{container.inspect}" unless
|
1687
|
+
(val - CONTEXT_CONTAINER_ID_GRAPH).empty?
|
1632
1688
|
# Okay
|
1633
|
-
|
1689
|
+
elsif val.include?('@type') || val.include?('@graph')
|
1634
1690
|
raise JsonLdError::InvalidContainerMapping,
|
1635
1691
|
"unknown mapping for '@container' to #{container.inspect} on term #{term.inspect}" if
|
1636
1692
|
(processingMode || 'json-ld-1.0') < 'json-ld-1.1'
|
1693
|
+
raise JsonLdError::InvalidContainerMapping,
|
1694
|
+
"'@container' on term #{term.inspect} using @language cannot have any values other than @set, found #{container.inspect}" unless
|
1695
|
+
val.length == 1
|
1696
|
+
# Okay
|
1697
|
+
elsif val.empty?
|
1698
|
+
# Okay
|
1637
1699
|
else
|
1638
1700
|
raise JsonLdError::InvalidContainerMapping,
|
1639
1701
|
"unknown mapping for '@container' to #{container.inspect} on term #{term.inspect}"
|