json-ld 1.0.5 → 1.0.6

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.
@@ -133,7 +133,7 @@ module JSON::LD
133
133
  compacted_item[key] = expanded_item['@index']
134
134
  end
135
135
  else
136
- raise ProcessingError::CompactionToListOfLists,
136
+ raise JsonLdError::CompactionToListOfLists,
137
137
  "key cannot have more than one list value" if result.has_key?(item_active_property)
138
138
  end
139
139
  end
@@ -116,16 +116,19 @@ module JSON::LD
116
116
  # @return [Context] A context provided to us that we can use without re-serializing XXX
117
117
  attr_accessor :provided_context
118
118
 
119
- # @!attribute [r] remote_contexts
120
- # @return [Array<String>] The list of remote contexts already processed
121
- attr_accessor :remote_contexts
122
-
123
119
  # @!attribute [r] namer
124
120
  # @return [BlankNodeNamer]
125
121
  attr_accessor :namer
126
122
 
127
123
  ##
128
124
  # Create new evaluation context
125
+ # @param [Hash] options
126
+ # @option options [String, #to_s] :base
127
+ # 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.
128
+ # @option options [Proc] :documentLoader
129
+ # 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 {API.documentLoader} for the method signature.
130
+ # @option options [Hash{Symbol => String}] :prefixes
131
+ # See `RDF::Reader#initialize`
129
132
  # @yield [ec]
130
133
  # @yieldparam [Context]
131
134
  # @return [Context]
@@ -136,12 +139,12 @@ module JSON::LD
136
139
  @doc_base.fragment = nil
137
140
  @doc_base.query = nil
138
141
  end
142
+ options[:documentLoader] ||= JSON::LD::API.method(:documentLoader)
139
143
  @term_definitions = {}
140
144
  @iri_to_term = {
141
145
  RDF.to_uri.to_s => "rdf",
142
146
  RDF::XSD.to_uri.to_s => "xsd"
143
147
  }
144
- @remote_contexts = []
145
148
  @namer = BlankNodeMapper.new("t")
146
149
 
147
150
  @options = options
@@ -151,7 +154,7 @@ module JSON::LD
151
154
  @iri_to_term[v.to_s] = k unless k.nil?
152
155
  end
153
156
 
154
- debug("init") {"iri_to_term: #{iri_to_term.inspect}"}
157
+ #debug("init") {"iri_to_term: #{iri_to_term.inspect}"}
155
158
 
156
159
  yield(self) if block_given?
157
160
  end
@@ -159,12 +162,12 @@ module JSON::LD
159
162
  # @param [String] value must be an absolute IRI
160
163
  def base=(value)
161
164
  if value
162
- raise InvalidContext::InvalidBaseIRI, "@base must be a string: #{value.inspect}" unless value.is_a?(String) || value.is_a?(RDF::URI)
165
+ raise JsonLdError::InvalidBaseIRI, "@base must be a string: #{value.inspect}" unless value.is_a?(String) || value.is_a?(RDF::URI)
163
166
  @base = RDF::URI(value)
164
167
  @base.canonicalize!
165
168
  @base.fragment = nil
166
169
  @base.query = nil
167
- raise InvalidContext::InvalidBaseIRI, "@base must be an absolute IRI: #{value.inspect}" unless @base.absolute?
170
+ raise JsonLdError::InvalidBaseIRI, "@base must be an absolute IRI: #{value.inspect}" unless @base.absolute?
168
171
  @base
169
172
  else
170
173
  @base = nil
@@ -175,7 +178,7 @@ module JSON::LD
175
178
  # @param [String] value
176
179
  def default_language=(value)
177
180
  @default_language = if value
178
- raise InvalidContext::InvalidDefaultLanguage, "@language must be a string: #{value.inspect}" unless value.is_a?(String)
181
+ raise JsonLdError::InvalidDefaultLanguage, "@language must be a string: #{value.inspect}" unless value.is_a?(String)
179
182
  value.downcase
180
183
  else
181
184
  nil
@@ -189,12 +192,12 @@ module JSON::LD
189
192
  value
190
193
  when String
191
194
  v = as_resource(value)
192
- raise InvalidContext::InvalidVocabMapping, "@value must be an absolute IRI: #{value.inspect}" if v.uri? && v.relative?
195
+ raise JsonLdError::InvalidVocabMapping, "@value must be an absolute IRI: #{value.inspect}" if v.uri? && v.relative?
193
196
  v
194
197
  when nil
195
198
  nil
196
199
  else
197
- raise InvalidContext::InvalidVocabMapping, "@value must be a string: #{value.inspect}"
200
+ raise JsonLdError::InvalidVocabMapping, "@value must be a string: #{value.inspect}"
198
201
  end
199
202
  end
200
203
 
@@ -208,7 +211,7 @@ module JSON::LD
208
211
  #
209
212
  #
210
213
  # @param [String, #read, Array, Hash, Context] local_context
211
- # @raise [InvalidContext]
214
+ # @raise [JsonLdError]
212
215
  # on a remote context load error, syntax error, or a reference to a term which is not defined.
213
216
  # @see http://json-ld.org/spec/latest/json-ld-api/index.html#context-processing-algorithm
214
217
  def parse(local_context, remote_contexts = [])
@@ -229,46 +232,57 @@ module JSON::LD
229
232
  # Load context document, if it is a string
230
233
  begin
231
234
  ctx = JSON.load(context)
232
- raise JSON::LD::InvalidContext::InvalidRemoteContext, "Context missing @context key" if @options[:validate] && ctx['@context'].nil?
235
+ raise JSON::LD::JsonLdError::InvalidRemoteContext, "Context missing @context key" if @options[:validate] && ctx['@context'].nil?
233
236
  result = parse(ctx["@context"] ? ctx["@context"].dup : {})
234
237
  result.provided_context = ctx["@context"]
235
238
  result
236
239
  rescue JSON::ParserError => e
237
240
  debug("parse") {"Failed to parse @context from remote document at #{context}: #{e.message}"}
238
- raise JSON::LD::InvalidContext::InvalidRemoteContext, "Failed to parse remote context at #{context}: #{e.message}" if @options[:validate]
241
+ raise JSON::LD::JsonLdError::InvalidRemoteContext, "Failed to parse remote context at #{context}: #{e.message}" if @options[:validate]
239
242
  self.dup
240
243
  end
241
- when String
244
+ when String, RDF::URI
242
245
  debug("parse") {"remote: #{context}, base: #{result.context_base || result.base}"}
243
246
  # Load context document, if it is a string
244
- begin
245
- # 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].
246
- context = RDF::URI(result.context_base || result.base).join(context)
247
+ # 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].
248
+ context = RDF::URI(result.context_base || result.base).join(context)
247
249
 
248
- raise InvalidContext::RecursiveContextInclusion, "#{context}" if remote_contexts.include?(context)
249
- @remote_contexts = @remote_contexts + [context]
250
+ raise JsonLdError::RecursiveContextInclusion, "#{context}" if remote_contexts.include?(context.to_s)
251
+ remote_contexts << context.to_s
250
252
 
251
- context_no_base = self.dup
252
- context_no_base.base = nil
253
- context_no_base.provided_context = context
254
- context_no_base.context_base = context
253
+ context_no_base = self.dup
254
+ context_no_base.base = nil
255
+ unless @options[:processingMode] == "json-ld-1.0"
256
+ context_no_base.provided_context = context.to_s
257
+ end
258
+ context_no_base.context_base = context.to_s
255
259
 
256
- RDF::Util::File.open_file(context) do |f|
260
+ begin
261
+ @options[:documentLoader].call(context.to_s) do |remote_doc|
257
262
  # 3.2.5) Dereference context. If the dereferenced document has no top-level JSON object with an @context member, an invalid remote context has been detected and processing is aborted; otherwise, set context to the value of that member.
258
- jo = JSON.load(f)
259
- raise InvalidContext::InvalidRemoteContext, "#{context}" unless jo.is_a?(Hash) && jo.has_key?('@context')
263
+ jo = case remote_doc.document
264
+ when String then JSON.parse(remote_doc.document)
265
+ else remote_doc.document
266
+ end
267
+ raise JsonLdError::InvalidRemoteContext, "#{context}" unless jo.is_a?(Hash) && jo.has_key?('@context')
260
268
  context = jo['@context']
269
+ if @options[:processingMode] == "json-ld-1.0"
270
+ context_no_base.provided_context = context.dup
271
+ end
261
272
  end
262
-
263
- # 3.2.6) Set context to the result of recursively calling this algorithm, passing context no base for active context, context for local context, and remote contexts.
264
- context = context_no_base.parse(context, remote_contexts.dup)
265
- context.base = result.base unless result.base.nil?
266
- result = context
267
- debug("parse") {"=> provided_context: #{context.inspect}"}
273
+ rescue JsonLdError
274
+ raise
268
275
  rescue Exception => e
269
276
  debug("parse") {"Failed to retrieve @context from remote document at #{context_no_base.context_base.inspect}: #{e.message}"}
270
- raise InvalidContext::InvalidRemoteContext, "#{context_no_base.context_base}", e.backtrace if @options[:validate]
277
+ raise JsonLdError::LoadingRemoteContextFailed, "#{context_no_base.context_base}", e.backtrace if @options[:validate]
271
278
  end
279
+
280
+ # 3.2.6) Set context to the result of recursively calling this algorithm, passing context no base for active context, context for local context, and remote contexts.
281
+ context = context_no_base.parse(context, remote_contexts.dup)
282
+ context.provided_context = context_no_base.provided_context
283
+ context.base ||= result.base
284
+ result = context
285
+ debug("parse") {"=> provided_context: #{context.inspect}"}
272
286
  when Hash
273
287
  # If context has a @vocab member: if its value is not a valid absolute IRI or null trigger an INVALID_VOCAB_MAPPING error; otherwise set the active context's vocabulary mapping to its value and remove the @vocab member from context.
274
288
  {
@@ -293,7 +307,7 @@ module JSON::LD
293
307
  end
294
308
  else
295
309
  # 3.3) If context is not a JSON object, an invalid local context error has been detected and processing is aborted.
296
- raise InvalidContext::InvalidLocalContext
310
+ raise JsonLdError::InvalidLocalContext
297
311
  end
298
312
  end
299
313
  end
@@ -311,7 +325,7 @@ module JSON::LD
311
325
  # @param [Hash] local_context
312
326
  # @param [String] term
313
327
  # @param [Hash] defined
314
- # @raise [InvalidContext]
328
+ # @raise [JsonLdError]
315
329
  # Represents a cyclical term dependency
316
330
  # @see http://json-ld.org/spec/latest/json-ld-api/index.html#create-term-definition
317
331
  def create_term_definition(local_context, term, defined)
@@ -324,15 +338,15 @@ module JSON::LD
324
338
  when nil
325
339
  defined[term] = false
326
340
  else
327
- raise InvalidContext::CyclicIRIMapping, "Cyclical term dependency found for #{term.inspect}"
341
+ raise JsonLdError::CyclicIRIMapping, "Cyclical term dependency found for #{term.inspect}"
328
342
  end
329
343
 
330
344
  # Since keywords cannot be overridden, term must not be a keyword. Otherwise, an invalid value has been detected, which is an error.
331
345
  if KEYWORDS.include?(term) && !%w(@vocab @language).include?(term)
332
- raise InvalidContext::KeywordRedefinition, "term #{term.inspect} must not be a keyword" if
346
+ raise JsonLdError::KeywordRedefinition, "term #{term.inspect} must not be a keyword" if
333
347
  @options[:validate]
334
348
  elsif !term_valid?(term) && @options[:validate]
335
- raise InvalidContext::InvalidTermDefinition, "term #{term.inspect} is invalid"
349
+ raise JsonLdError::InvalidTermDefinition, "term #{term.inspect} is invalid"
336
350
  end
337
351
 
338
352
  # Remove any existing term definition for term in active context.
@@ -356,16 +370,29 @@ module JSON::LD
356
370
  if value.has_key?('@type')
357
371
  type = value['@type']
358
372
  # SPEC FIXME: @type may be nil
359
- raise InvalidContext::InvalidTypeMapping, "unknown mapping for '@type' to #{type.inspect}" unless type.is_a?(String) || type.nil?
360
- type = expand_iri(type, :vocab => true, :documentRelative => true, :local_context => local_context, :defined => defined) if type.is_a?(String)
373
+ type = case type
374
+ when nil
375
+ type
376
+ when String
377
+ begin
378
+ expand_iri(type, :vocab => true, :documentRelative => false, :local_context => local_context, :defined => defined)
379
+ rescue JsonLdError::InvalidIRIMapping
380
+ raise JsonLdError::InvalidTypeMapping, "invalid mapping for '@type' to #{type.inspect}"
381
+ end
382
+ else
383
+ :error
384
+ end
385
+ unless %w(@id @vocab).include?(type) || type.is_a?(RDF::URI) && type.absolute?
386
+ raise JsonLdError::InvalidTypeMapping, "unknown mapping for '@type' to #{type.inspect}"
387
+ end
361
388
  debug("") {"type_mapping: #{type.inspect}"}
362
389
  definition.type_mapping = type
363
390
  end
364
391
 
365
392
  if value.has_key?('@reverse')
366
- raise InvalidContext::InvalidReverseProperty, "unexpected key in #{value.inspect}" if
393
+ raise JsonLdError::InvalidReverseProperty, "unexpected key in #{value.inspect}" if
367
394
  value.keys.any? {|k| %w(@id).include?(k)}
368
- raise InvalidContext::InvalidIRIMapping, "expected value of @reverse to be a string" unless
395
+ raise JsonLdError::InvalidIRIMapping, "expected value of @reverse to be a string" unless
369
396
  value['@reverse'].is_a?(String)
370
397
 
371
398
  # Otherwise, set the IRI mapping of definition to the result of using the IRI Expansion algorithm, passing active context, the value associated with the @reverse key for value, true for vocab, true for document relative, local context, and defined. If the result is not an absolute IRI, i.e., it contains no colon (:), an invalid IRI mapping error has been detected and processing is aborted.
@@ -374,25 +401,27 @@ module JSON::LD
374
401
  :documentRelative => true,
375
402
  :local_context => local_context,
376
403
  :defined => defined)
377
- raise InvalidContext::InvalidIRImapping, "non-absolute @reverse IRI: #{definition.id}" unless
378
- definition.id.absolute?
404
+ raise JsonLdError::InvalidIRIMapping, "non-absolute @reverse IRI: #{definition.id}" unless
405
+ definition.id.is_a?(RDF::URI) && definition.id.absolute?
379
406
 
380
407
  # If value contains an @container member, set the container mapping of definition to its value; if its value is neither @set, nor @index, nor null, an invalid reverse property error has been detected (reverse properties only support set- and index-containers) and processing is aborted.
381
408
  if (container = value['@container'])
382
- raise InvalidContext::InvalidReverseProperty,
409
+ raise JsonLdError::InvalidReverseProperty,
383
410
  "unknown mapping for '@container' to #{container.inspect}" unless
384
411
  ['@set', '@index', nil].include?(container)
385
412
  definition.container_mapping = container
386
413
  end
387
414
  definition.reverse_property = true
388
415
  elsif value.has_key?('@id') && value['@id'] != term
389
- raise InvalidContext::InvalidIRIMapping, "expected value of @reverse to be a string" unless
416
+ raise JsonLdError::InvalidIRIMapping, "expected value of @id to be a string" unless
390
417
  value['@id'].is_a?(String)
391
418
  definition.id = expand_iri(value['@id'],
392
419
  :vocab => true,
393
420
  :documentRelative => true,
394
421
  :local_context => local_context,
395
422
  :defined => defined)
423
+ raise JsonLdError::InvalidKeywordAlias, "expected value of @id to not be @context" if
424
+ definition.id == '@context'
396
425
  elsif term.include?(':')
397
426
  # If term is a compact IRI with a prefix that is a key in local context then a dependency has been found. Use this algorithm recursively passing active context, local context, the prefix as term, and defined.
398
427
  prefix, suffix = term.split(':')
@@ -408,21 +437,21 @@ module JSON::LD
408
437
  debug("") {"=> #{definition.id}"}
409
438
  else
410
439
  # 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.
411
- raise InvalidContext::InvalidIRIMapping, "relative term definition without vocab" unless vocab
440
+ raise JsonLdError::InvalidIRIMapping, "relative term definition without vocab" unless vocab
412
441
  definition.id = vocab + term
413
442
  debug("") {"=> #{definition.id}"}
414
443
  end
415
444
 
416
445
  if value.has_key?('@container')
417
446
  container = value['@container']
418
- raise InvalidContext::InvalidContainerMapping, "unknown mapping for '@container' to #{container.inspect}" unless %w(@list @set @language @index).include?(container)
447
+ raise JsonLdError::InvalidContainerMapping, "unknown mapping for '@container' to #{container.inspect}" unless %w(@list @set @language @index).include?(container)
419
448
  debug("") {"container_mapping: #{container.inspect}"}
420
449
  definition.container_mapping = container
421
450
  end
422
451
 
423
452
  if value.has_key?('@language')
424
453
  language = value['@language']
425
- raise InvalidContext::InvalidLanguageMapping, "language must be null or a string, was #{language.inspect}}" unless language.nil? || (language || "").is_a?(String)
454
+ raise JsonLdError::InvalidLanguageMapping, "language must be null or a string, was #{language.inspect}}" unless language.nil? || (language || "").is_a?(String)
426
455
  language = language.downcase if language.is_a?(String)
427
456
  debug("") {"language_mapping: #{language.inspect}"}
428
457
  definition.language_mapping = language || false
@@ -431,7 +460,7 @@ module JSON::LD
431
460
  term_definitions[term] = definition
432
461
  defined[term] = true
433
462
  else
434
- raise InvalidContext::InvalidTermDefinition, "Term definition for #{term.inspect} is an #{value.class}"
463
+ raise JsonLdError::InvalidTermDefinition, "Term definition for #{term.inspect} is an #{value.class}"
435
464
  end
436
465
  end
437
466
 
@@ -447,7 +476,7 @@ module JSON::LD
447
476
  depth(options) do
448
477
  # FIXME: not setting provided_context now
449
478
  use_context = case provided_context
450
- when RDF::URI
479
+ when String, RDF::URI
451
480
  debug "serlialize: reuse context: #{provided_context.inspect}"
452
481
  provided_context.to_s
453
482
  when Hash, Array
@@ -462,7 +491,7 @@ module JSON::LD
462
491
  ctx['@vocab'] = vocab.to_s if vocab
463
492
 
464
493
  # Term Definitions
465
- term_definitions.each do |term, definition|
494
+ term_definitions.dup.each do |term, definition|
466
495
  ctx[term] = definition.to_context_definition(self)
467
496
  end
468
497
 
@@ -611,7 +640,7 @@ module JSON::LD
611
640
  # Used during Context Processing.
612
641
  # @return [RDF::URI, String]
613
642
  # IRI or String, if it's a keyword
614
- # @raise [JSON::LD::InvalidContext::InvalidIRIMapping] if the value cannot be expanded
643
+ # @raise [JSON::LD::JsonLdError::InvalidIRIMapping] if the value cannot be expanded
615
644
  # @see http://json-ld.org/spec/latest/json-ld-api/#iri-expansion
616
645
  def expand_iri(value, options = {})
617
646
  return value unless value.is_a?(String)
@@ -668,7 +697,7 @@ module JSON::LD
668
697
  RDF::URI(base).join(value)
669
698
  elsif local_context && RDF::URI(value).relative?
670
699
  # If local context is not null and value is not an absolute IRI, an invalid IRI mapping error has been detected and processing is aborted.
671
- raise JSON::LD::InvalidContext::InvalidIRIMapping, "not an absolute IRI: #{value}"
700
+ raise JSON::LD::JsonLdError::InvalidIRIMapping, "not an absolute IRI: #{value}"
672
701
  else
673
702
  RDF::URI(value)
674
703
  end
@@ -813,7 +842,7 @@ module JSON::LD
813
842
  # try those, and add to mapping
814
843
  if @options[:standard_prefixes]
815
844
  candidates = RDF::Vocabulary.
816
- select {|v| iri.start_with?(v.to_uri.to_s)}.
845
+ select {|v| iri.start_with?(v.to_uri.to_s) && iri != v.to_uri.to_s}.
817
846
  map do |v|
818
847
  prefix = v.__name__.to_s.split('::').last.downcase
819
848
  set_mapping(prefix, v.to_uri.to_s)
@@ -854,7 +883,7 @@ module JSON::LD
854
883
  # @raise [RDF::ReaderError] if the iri cannot be expanded
855
884
  # @see http://json-ld.org/spec/latest/json-ld-api/#value-expansion
856
885
  def expand_value(property, value, options = {})
857
- options = {:useNativeTypes => true}.merge(options)
886
+ options = {:useNativeTypes => false}.merge(options)
858
887
  depth(options) do
859
888
  debug("expand_value") {"property: #{property.inspect}, value: #{value.inspect}"}
860
889
 
@@ -928,7 +957,7 @@ module JSON::LD
928
957
  # @param [Hash{Symbol => Object}] options
929
958
  #
930
959
  # @return [Hash] Object representation of value
931
- # @raise [ProcessingError] if the iri cannot be expanded
960
+ # @raise [JsonLdError] if the iri cannot be expanded
932
961
  # @see http://json-ld.org/spec/latest/json-ld-api/#value-compaction
933
962
  # FIXME: revisit the specification version of this.
934
963
  def compact_value(property, value, options = {})
@@ -994,6 +1023,7 @@ module JSON::LD
994
1023
 
995
1024
  def inspect
996
1025
  v = %w([Context)
1026
+ v << "base=#{base}" if base
997
1027
  v << "vocab=#{vocab}" if vocab
998
1028
  v << "def_language=#{default_language}" if default_language
999
1029
  v << "term_definitions[#{term_definitions.length}]=#{term_definitions}"
@@ -24,7 +24,7 @@ module JSON::LD
24
24
  v = expand(v, active_property, context, options)
25
25
 
26
26
  # If the active property is @list or its container mapping is set to @list, the expanded item must not be an array or a list object, otherwise a list of lists error has been detected and processing is aborted.
27
- raise ProcessingError::ListOfLists,
27
+ raise JsonLdError::ListOfLists,
28
28
  "A list may not contain another list" if
29
29
  is_list && (v.is_a?(Array) || list?(v))
30
30
  v
@@ -60,17 +60,17 @@ module JSON::LD
60
60
 
61
61
  if KEYWORDS.include?(expanded_property)
62
62
  # If active property equals @reverse, an invalid reverse property map error has been detected and processing is aborted.
63
- raise ProcessingError::InvalidReversePropertyMap,
63
+ raise JsonLdError::InvalidReversePropertyMap,
64
64
  "@reverse not appropriate at this point" if active_property == '@reverse'
65
65
 
66
66
  # If result has already an expanded property member, an colliding keywords error has been detected and processing is aborted.
67
- raise ProcessingError::CollidingKeywords,
67
+ raise JsonLdError::CollidingKeywords,
68
68
  "#{expanded_property} already exists in result" if output_object.has_key?(expanded_property)
69
69
 
70
70
  expanded_value = case expanded_property
71
71
  when '@id'
72
72
  # If expanded property is @id and value is not a string, an invalid @id value error has been detected and processing is aborted
73
- raise ProcessingError::InvalidIdValue,
73
+ raise JsonLdError::InvalidIdValue,
74
74
  "value of @id must be a string: #{value.inspect}" unless value.is_a?(String)
75
75
 
76
76
  # Otherwise, set expanded value to the result of using the IRI Expansion algorithm, passing active context, value, and true for document relative.
@@ -82,7 +82,7 @@ module JSON::LD
82
82
  when Array
83
83
  depth do
84
84
  value.map do |v|
85
- raise ProcessingError::InvalidTypeValue,
85
+ raise JsonLdError::InvalidTypeValue,
86
86
  "@type value must be a string or array of strings: #{v.inspect}" unless v.is_a?(String)
87
87
  context.expand_iri(v, :vocab => true, :documentRelative => true, :quiet => true, :depth => @depth).to_s
88
88
  end
@@ -91,11 +91,11 @@ module JSON::LD
91
91
  context.expand_iri(value, :vocab => true, :documentRelative => true, :quiet => true, :depth => @depth).to_s
92
92
  when Hash
93
93
  # For framing
94
- raise ProcessingError::InvalidTypeValue,
94
+ raise JsonLdError::InvalidTypeValue,
95
95
  "@type value must be a an empty object for framing: #{value.inspect}" unless
96
96
  value.empty?
97
97
  else
98
- raise ProcessingError::InvalidTypeValue,
98
+ raise JsonLdError::InvalidTypeValue,
99
99
  "@type value must be a string or array of strings: #{value.inspect}"
100
100
  end
101
101
  when '@graph'
@@ -103,7 +103,7 @@ module JSON::LD
103
103
  depth { expand(value, '@graph', context, options) }
104
104
  when '@value'
105
105
  # If expanded property is @value and value is not a scalar or null, an invalid value object value error has been detected and processing is aborted. Otherwise, set expanded value to value. If expanded value is null, set the @value member of result to null and continue with the next key from element. Null values need to be preserved in this case as the meaning of an @type member depends on the existence of an @value member.
106
- raise ProcessingError::InvalidValueObjectValue,
106
+ raise JsonLdError::InvalidValueObjectValue,
107
107
  "Value of #{expanded_property} must be a scalar or null: #{value.inspect}" if value.is_a?(Hash) || value.is_a?(Array)
108
108
  if value.nil?
109
109
  output_object['@value'] = nil
@@ -112,12 +112,12 @@ module JSON::LD
112
112
  value
113
113
  when '@language'
114
114
  # If expanded property is @language and value is not a string, an invalid language-tagged string error has been detected and processing is aborted. Otherwise, set expanded value to lowercased value.
115
- raise ProcessingError::InvalidLanguageTaggedString,
115
+ raise JsonLdError::InvalidLanguageTaggedString,
116
116
  "Value of #{expanded_property} must be a string: #{value.inspect}" unless value.is_a?(String)
117
117
  value.downcase
118
118
  when '@index'
119
119
  # If expanded property is @index and value is not a string, an invalid @index value error has been detected and processing is aborted. Otherwise, set expanded value to value.
120
- raise ProcessingError::InvalidIndexValue,
120
+ raise JsonLdError::InvalidIndexValue,
121
121
  "Value of @index is not a string: #{value.inspect}" unless value.is_a?(String)
122
122
  value
123
123
  when '@list'
@@ -134,7 +134,7 @@ module JSON::LD
134
134
 
135
135
  # If expanded value is a list object, a list of lists error has been detected and processing is aborted.
136
136
  # Spec FIXME: Also look at each object if result is an array
137
- raise ProcessingError::ListOfLists,
137
+ raise JsonLdError::ListOfLists,
138
138
  "A list may not contain another list" if value.any? {|v| list?(v)}
139
139
 
140
140
  value
@@ -143,7 +143,7 @@ module JSON::LD
143
143
  depth { expand(value, active_property, context, options) }
144
144
  when '@reverse'
145
145
  # If expanded property is @reverse and value is not a JSON object, an invalid @reverse value error has been detected and processing is aborted.
146
- raise ProcessingError::InvalidReverseValueError,
146
+ raise JsonLdError::InvalidReverseValue,
147
147
  "@reverse value must be an object: #{value.inspect}" unless value.is_a?(Hash)
148
148
 
149
149
  # Otherwise
@@ -168,8 +168,8 @@ module JSON::LD
168
168
  next if property == '@reverse'
169
169
  items.each do |item|
170
170
  if value?(item) || list?(item)
171
- raise ProcessingError::InvalidReversePropertyValue,
172
- "invalid reverse property value: #{item.inspect}"
171
+ raise JsonLdError::InvalidReversePropertyValue,
172
+ item.inspect
173
173
  end
174
174
  merge_value(reverse_map, property, item)
175
175
  end
@@ -202,7 +202,7 @@ module JSON::LD
202
202
  value.keys.sort.each do |k|
203
203
  [value[k]].flatten.each do |item|
204
204
  # item must be a string, otherwise an invalid language map value error has been detected and processing is aborted.
205
- raise ProcessingError::InvalidLanguageMapValue,
205
+ raise JsonLdError::InvalidLanguageMapValue,
206
206
  "Expected #{item.inspect} to be a string" unless item.is_a?(String)
207
207
 
208
208
  # Append a JSON object to expanded value that consists of two key-value pairs: (@value-item) and (@language-lowercased language).
@@ -256,8 +256,8 @@ module JSON::LD
256
256
  reverse_map = output_object['@reverse'] ||= {}
257
257
  [expanded_value].flatten.each do |item|
258
258
  # If item is a value object or list object, an invalid reverse property value has been detected and processing is aborted.
259
- raise ProcessingError::InvalidReversePropertyValue,
260
- "invalid reverse property value: #{item.inspect}" if value?(item) || list?(item)
259
+ raise JsonLdError::InvalidReversePropertyValue,
260
+ item.inspect if value?(item) || list?(item)
261
261
 
262
262
  # If reverse map has no expanded property member, create one and initialize its value to an empty array.
263
263
  # Append item to the value of the expanded property member of reverse map.
@@ -274,9 +274,10 @@ module JSON::LD
274
274
 
275
275
  # If result contains the key @value:
276
276
  if value?(output_object)
277
- unless (output_object.keys - %w(@value @language @type @index)).empty?
277
+ unless (output_object.keys - %w(@value @language @type @index)).empty? &&
278
+ (output_object.keys & %w(@language @type)).length < 2
278
279
  # The result must not contain any keys other than @value, @language, @type, and @index. It must not contain both the @language key and the @type key. Otherwise, an invalid value object error has been detected and processing is aborted.
279
- raise ProcessingError::InvalidValueObjectError,
280
+ raise JsonLdError::InvalidValueObject,
280
281
  "value object has unknown keys: #{output_object.inspect}"
281
282
  end
282
283
 
@@ -288,12 +289,13 @@ module JSON::LD
288
289
 
289
290
  if !output_object['@value'].is_a?(String) && output_object.has_key?('@language')
290
291
  # Otherwise, if the value of result's @value member is not a string and result contains the key @language, an invalid language-tagged value error has been detected (only strings can be language-tagged) and processing is aborted.
291
- raise ProcessingError::InvalidLanguageTaggedValue,
292
+ raise JsonLdError::InvalidLanguageTaggedValue,
292
293
  "when @language is used, @value must be a string: #{@value.inspect}"
293
- elsif !output_object.fetch('@type', "").is_a?(String)
294
- # Otherwise, if the result has a @type member and its value is not a string, an invalid typed value error has been detected and processing is aborted.
295
- raise ProcessingError::InvalidTypedValue,
296
- "value of @type must be a string: #{output_object['@type'].inspect}"
294
+ elsif !output_object.fetch('@type', "").is_a?(String) ||
295
+ !context.expand_iri(output_object.fetch('@type', ""), :vocab => true, :depth => @depth).is_a?(RDF::URI)
296
+ # Otherwise, if the result has a @type member and its value is not an IRI, an invalid typed value error has been detected and processing is aborted.
297
+ raise JsonLdError::InvalidTypedValue,
298
+ "value of @type must be an IRI: #{output_object['@type'].inspect}"
297
299
  end
298
300
  elsif !output_object.fetch('@type', []).is_a?(Array)
299
301
  # Otherwise, if result contains the key @type and its associated value is not an array, set it to an array containing only the associated value.
@@ -301,7 +303,7 @@ module JSON::LD
301
303
  elsif output_object.keys.any? {|k| %w(@set @list).include?(k)}
302
304
  # Otherwise, if result contains the key @set or @list:
303
305
  # The result must contain at most one other key and that key must be @index. Otherwise, an invalid set or list object error has been detected and processing is aborted.
304
- raise ProcessingError::InvalidSetOrListObject,
306
+ raise JsonLdError::InvalidSetOrListObject,
305
307
  "@set or @list may only contain @index: #{output_object.keys.inspect}" unless
306
308
  (output_object.keys - %w(@set @list @index)).empty?
307
309