json-ld 2.1.7 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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}"
|