json-ld 3.1.7 → 3.1.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b9345f0853c9ee6d7e1bb91817ca7d9effc1ce5d591f98fa92a11c396c1f0fbb
4
- data.tar.gz: 7a84d8f7b4dd0fe379dd8b915d6e899f610807959d9ea4ef66c0ab4c22657807
3
+ metadata.gz: 8fab787ba5efd37b20576d65d5dfe524923f14c7dac53a1d9ed32cb88bd689c8
4
+ data.tar.gz: 3b8ce473fe9e05302dabedb9a631ca2212aeb03479cc2d282abf8603daeedce2
5
5
  SHA512:
6
- metadata.gz: d2ff1429edeea61f1655e445862140b5477dfa978cfaeaa3a417417fff24adfc17b6adea77cb24041c8c3daafaf7661d05023a3f1e2e4c161194be7dc4c96dd7
7
- data.tar.gz: e04b64a78d9bfdc88d808219440b758540a3e6bd2f7dae4ee73831b093ab8ada77641acfc2c4c079b413f17b0d88a0149058fa3959c2fbdd6e0d421c8885fa5a
6
+ metadata.gz: 47ec226ef3c0d79702d61a7fa81ce2ed3368f64744e2fb29f1b98fdaae2aba7e6af7ed493395031eb43d89e4469c04a24ea38ad836baffb50a46854cf33a75c8
7
+ data.tar.gz: 579b1794485469d832b29a2f5f5bbf36819627d93289595da6f46e2197829e4e6365a5bbb4c88193f904ad07a21a643821195d22cb3750543e6954e986d809f4
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  [![Gem Version](https://badge.fury.io/rb/json-ld.png)](https://rubygems.org/gems/json-ld)
6
6
  [![Build Status](https://secure.travis-ci.org/ruby-rdf/json-ld.png?branch=develop)](https://github.com/ruby-rdf/json-ld/actions?query=workflow%3ACI)
7
- [![Coverage Status](https://coveralls.io/repos/ruby-rdf/json-ld/badge.svg)](https://coveralls.io/github/ruby-rdf/json-ld)
7
+ [![Coverage Status](https://coveralls.io/repos/ruby-rdf/json-ld/badge.svg?branch=develop)](https://coveralls.io/github/ruby-rdf/json-ld?branch=develop)
8
8
  [![Gitter chat](https://badges.gitter.im/ruby-rdf.png)](https://gitter.im/gitterHQ/gitter)
9
9
 
10
10
  ## Features
@@ -17,7 +17,7 @@ JSON::LD can now be used to create a _context_ from an RDFS/OWL definition, and
17
17
  * If available, uses [Nokogiri][] and/or [Nokogumbo][] for parsing HTML, falls back to REXML otherwise.
18
18
  * Provisional support for [JSON-LD*][JSON-LD*].
19
19
 
20
- [Implementation Report](file.earl.html)
20
+ [Implementation Report](https://ruby-rdf.github.io/json-ld/etc/earl.html)
21
21
 
22
22
  Install with `gem install json-ld`
23
23
 
@@ -39,7 +39,7 @@ The [MultiJson](https://rubygems.org/gems/multi_json) gem is used for parsing JS
39
39
 
40
40
  ### JSON-LD* (RDFStar)
41
41
 
42
- The {JSON::LD::API.toRdf} and {JSON::LD::API.fromRdf} API methods, along with the {JSON::LD::Reader} and {JSON::LD::Writer}, include provisional support for [JSON-LD*][JSON-LD*].
42
+ The {JSON::LD::API.expand}, {JSON::LD::API.compact}, {JSON::LD::API.toRdf}, and {JSON::LD::API.fromRdf} API methods, along with the {JSON::LD::Reader} and {JSON::LD::Writer}, include provisional support for [JSON-LD*][JSON-LD*].
43
43
 
44
44
  Internally, an `RDF::Statement` is treated as another resource, along with `RDF::URI` and `RDF::Node`, which allows an `RDF::Statement` to have a `#subject` or `#object` which is also an `RDF::Statement`.
45
45
 
@@ -55,6 +55,19 @@ In JSON-LD, with the `rdfstar` option set, the value of `@id`, in addition to an
55
55
  "ex:certainty": 0.9
56
56
  }
57
57
 
58
+ Additionally, the `@annotation` property (or alias) may be used on a node object or value object to annotate the statement for which the associated node is the object of a triple.
59
+
60
+ {
61
+ "@context": {"foaf": "http://xmlns.com/foaf/0.1/"},
62
+ "@id": "bob",
63
+ "foaf:age" 23,
64
+ "@annotation": {
65
+ "ex:certainty": 0.9
66
+ }
67
+ }
68
+
69
+ In the first case, the embedded node is not asserted, and only appears as the subject of a triple. In the second case, the triple is asserted and used as the subject in another statement which annotates it.
70
+
58
71
  **Note: This feature is subject to change or elimination as the standards process progresses.**
59
72
 
60
73
  #### Serializing a Graph containing embedded statements
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.1.7
1
+ 3.1.8
data/bin/jsonld CHANGED
@@ -24,7 +24,7 @@ def run(input, options, parser_options)
24
24
 
25
25
  start = Time.new
26
26
  if options[:expand]
27
- parser_options = parser_options.merge(expandContext: parser_options.delete(:context)) if parser_options.has_key?(:context)
27
+ parser_options = parser_options.merge(expandContext: parser_options.delete(:context)) if parser_options.key?(:context)
28
28
  input = JSON::LD::API.fromRdf(reader) if reader
29
29
  output = JSON::LD::API.expand(input, parser_options)
30
30
  secs = Time.new - start
@@ -49,7 +49,7 @@ def run(input, options, parser_options)
49
49
  options[:output].puts output.to_json(JSON::LD::JSON_STATE)
50
50
  STDERR.puts "Framed in #{secs} seconds." unless options[:quiet]
51
51
  else
52
- parser_options = parser_options.merge(expandContext: parser_options.delete(:context)) if parser_options.has_key?(:context)
52
+ parser_options = parser_options.merge(expandContext: parser_options.delete(:context)) if parser_options.key?(:context)
53
53
  parser_options[:standard_prefixes] = true
54
54
  reader ||= JSON::LD::Reader.new(input, parser_options)
55
55
  num = 0
@@ -181,7 +181,7 @@ opts.each do |opt, arg|
181
181
  end
182
182
 
183
183
  # Hack
184
- if !(options.keys & [:expand, :compact, :flatten, :frame]).empty? &&
184
+ if !(options.keys & %i{expand compact flatten frame}).empty? &&
185
185
  (parser_options[:stream] || options[:output_format] != :jsonld)
186
186
  STDERR.puts "Incompatible options"
187
187
  exit(1)
data/lib/json/ld.rb CHANGED
@@ -47,6 +47,7 @@ module JSON
47
47
  DEFAULT_CONTEXT = "http://schema.org"
48
48
 
49
49
  KEYWORDS = Set.new(%w(
50
+ @annotation
50
51
  @base
51
52
  @container
52
53
  @context
@@ -116,6 +117,7 @@ module JSON
116
117
  class CollidingKeywords < JsonLdError; @code = "colliding keywords"; end
117
118
  class ConflictingIndexes < JsonLdError; @code = "conflicting indexes"; end
118
119
  class CyclicIRIMapping < JsonLdError; @code = "cyclic IRI mapping"; end
120
+ class InvalidAnnotation < JsonLdError; @code = "invalid annotation"; end
119
121
  class InvalidBaseIRI < JsonLdError; @code = "invalid base IRI"; end
120
122
  class InvalidContainerMapping < JsonLdError; @code = "invalid container mapping"; end
121
123
  class InvalidContextEntry < JsonLdError; @code = "invalid context entry"; end
@@ -137,7 +139,7 @@ module JSON
137
139
  class InvalidNestValue < JsonLdError; @code = "invalid @nest value"; end
138
140
  class InvalidPrefixValue < JsonLdError; @code = "invalid @prefix value"; end
139
141
  class InvalidPropagateValue < JsonLdError; @code = "invalid @propagate value"; end
140
- class InvalidEmbeddedNode < JsonLdError; @code = "invalid reified node"; end
142
+ class InvalidEmbeddedNode < JsonLdError; @code = "invalid embedded node"; end
141
143
  class InvalidRemoteContext < JsonLdError; @code = "invalid remote context"; end
142
144
  class InvalidReverseProperty < JsonLdError; @code = "invalid reverse property"; end
143
145
  class InvalidReversePropertyMap < JsonLdError; @code = "invalid reverse property map"; end
data/lib/json/ld/api.rb CHANGED
@@ -102,13 +102,15 @@ module JSON::LD
102
102
  # @yield [api]
103
103
  # @yieldparam [API]
104
104
  # @raise [JsonLdError]
105
- def initialize(input, context, rename_bnodes: true, unique_bnodes: false, **options, &block)
105
+ def initialize(input, context, **options, &block)
106
106
  @options = {
107
107
  compactArrays: true,
108
108
  ordered: false,
109
109
  extractAllScripts: false,
110
+ rename_bnodes: true,
111
+ unique_bnodes: false,
110
112
  }.merge(options)
111
- @namer = unique_bnodes ? BlankNodeUniqer.new : (rename_bnodes ? BlankNodeNamer.new("b") : BlankNodeMapper.new)
113
+ @namer = @options[:unique_bnodes] ? BlankNodeUniqer.new : (@options[:rename_bnodes] ? BlankNodeNamer.new("b") : BlankNodeMapper.new)
112
114
 
113
115
  @options[:base] = RDF::URI(@options[:base]) if @options[:base] && !@options[:base].is_a?(RDF::URI)
114
116
  # For context via Link header
@@ -202,9 +204,9 @@ module JSON::LD
202
204
  # The JSON-LD object to copy and perform the compaction upon.
203
205
  # @param [String, #read, Hash, Array, JSON::LD::Context] context
204
206
  # The base context to use when compacting the input.
207
+ # @param [Boolean] expanded (false) Input is already expanded
205
208
  # @param [Hash{Symbol => Object}] options
206
209
  # @option options (see #initialize)
207
- # @option options [Boolean] :expanded Input is already expanded
208
210
  # @yield jsonld
209
211
  # @yieldparam [Hash] jsonld
210
212
  # The compacted JSON-LD document
@@ -248,9 +250,9 @@ module JSON::LD
248
250
  # The JSON-LD object or array of JSON-LD objects to flatten or an IRI referencing the JSON-LD document to flatten.
249
251
  # @param [String, #read, Hash, Array, JSON::LD::EvaluationContext] context
250
252
  # An optional external context to use additionally to the context embedded in input when expanding the input.
253
+ # @param [Boolean] expanded (false) Input is already expanded
251
254
  # @param [Hash{Symbol => Object}] options
252
255
  # @option options (see #initialize)
253
- # @option options [Boolean] :expanded Input is already expanded
254
256
  # @yield jsonld
255
257
  # @yieldparam [Hash] jsonld
256
258
  # The flattened JSON-LD document
@@ -275,6 +277,9 @@ module JSON::LD
275
277
  API.new(expanded_input, context, no_default_base: true, **options) do
276
278
  log_debug(".flatten") {"expanded input: #{value.to_json(JSON_STATE) rescue 'malformed json'}"}
277
279
 
280
+ # 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.
281
+ @value = rename_bnodes(@value) if @options[:rename_bnodes]
282
+
278
283
  # Initialize node map to a JSON object consisting of a single member whose key is @default and whose value is an empty JSON object.
279
284
  graph_maps = {'@default' => {}}
280
285
  create_node_map(value, graph_maps)
@@ -316,6 +321,7 @@ module JSON::LD
316
321
  # The JSON-LD object to copy and perform the framing on.
317
322
  # @param [String, #read, Hash, Array] frame
318
323
  # The frame to use when re-arranging the data.
324
+ # @param [Boolean] expanded (false) Input is already expanded
319
325
  # @option options (see #initialize)
320
326
  # @option options ['@always', '@link', '@once', '@never'] :embed ('@once')
321
327
  # a flag specifying that objects should be directly embedded in the output, instead of being referred to by their IRI.
@@ -325,7 +331,6 @@ module JSON::LD
325
331
  # A flag specifying that all properties present in the input frame must either have a default value or be present in the JSON-LD input for the frame to match.
326
332
  # @option options [Boolean] :omitDefault (false)
327
333
  # a flag specifying that properties that are missing from the JSON-LD input should be omitted from the output.
328
- # @option options [Boolean] :expanded Input is already expanded
329
334
  # @option options [Boolean] :pruneBlankNodeIdentifiers (true) removes blank node identifiers that are only used once.
330
335
  # @option options [Boolean] :omitGraph does not use `@graph` at top level unless necessary to describe multiple objects, defaults to `true` if processingMode is 1.1, otherwise `false`.
331
336
  # @yield jsonld
@@ -391,10 +396,13 @@ module JSON::LD
391
396
  end
392
397
 
393
398
  # Set omitGraph option, if not present, based on processingMode
394
- unless options.has_key?(:omitGraph)
399
+ unless options.key?(:omitGraph)
395
400
  options[:omitGraph] = context.processingMode('json-ld-1.1')
396
401
  end
397
402
 
403
+ # 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.
404
+ @value = rename_bnodes(@value)
405
+
398
406
  # Get framing nodes from expanded input, replacing Blank Node identifiers as necessary
399
407
  create_node_map(value, framing_state[:graphMap], active_graph: '@default')
400
408
 
@@ -415,7 +423,7 @@ module JSON::LD
415
423
  frame(framing_state, framing_state[:subjects].keys.opt_sort(ordered: @options[:ordered]), (expanded_frame.first || {}), parent: result, **options)
416
424
 
417
425
  # Default to based on processinMode
418
- if !options.has_key?(:pruneBlankNodeIdentifiers)
426
+ if !options.key?(:pruneBlankNodeIdentifiers)
419
427
  options[:pruneBlankNodeIdentifiers] = context.processingMode('json-ld-1.1')
420
428
  end
421
429
 
@@ -458,10 +466,10 @@ module JSON::LD
458
466
  #
459
467
  # @param [String, #read, Hash, Array] input
460
468
  # The JSON-LD object to process when outputting statements.
469
+ # @param [Boolean] expanded (false) Input is already expanded
461
470
  # @option options (see #initialize)
462
471
  # @option options [Boolean] :produceGeneralizedRdf (false)
463
472
  # If true, output will include statements having blank node predicates, otherwise they are dropped.
464
- # @option options [Boolean] :expanded Input is already expanded
465
473
  # @raise [JsonLdError]
466
474
  # @yield statement
467
475
  # @yieldparam [RDF::Statement] statement
@@ -470,7 +478,7 @@ module JSON::LD
470
478
  unless block_given?
471
479
  results = []
472
480
  results.extend(RDF::Enumerable)
473
- self.toRdf(input, **options) do |stmt|
481
+ self.toRdf(input, expanded: expanded, **options) do |stmt|
474
482
  results << stmt
475
483
  end
476
484
  return results
@@ -480,16 +488,16 @@ module JSON::LD
480
488
  extractAllScripts: true,
481
489
  }.merge(options)
482
490
 
483
- # Expand input to simplify processing
484
- expanded_input = expanded ? input : API.expand(input, ordered: false, **options)
491
+ # Flatten input to simplify processing
492
+ flattened_input = API.flatten(input, nil, expanded: expanded, ordered: false, **options)
485
493
 
486
- API.new(expanded_input, nil, **options) do
494
+ API.new(flattened_input, nil, **options) do
487
495
  # 1) Perform the Expansion Algorithm on the JSON-LD input.
488
496
  # This removes any existing context to allow the given context to be cleanly applied.
489
- log_debug(".toRdf") {"expanded input: #{expanded_input.to_json(JSON_STATE) rescue 'malformed json'}"}
497
+ log_debug(".toRdf") {"flattened input: #{flattened_input.to_json(JSON_STATE) rescue 'malformed json'}"}
490
498
 
491
499
  # Recurse through input
492
- expanded_input.each do |node|
500
+ flattened_input.each do |node|
493
501
  item_to_rdf(node) do |statement|
494
502
  next if statement.predicate.node? && !options[:produceGeneralizedRdf]
495
503
 
@@ -64,7 +64,7 @@ module JSON::LD
64
64
  log_debug("prop-scoped", depth: log_depth.to_i) {"context: #{self.context.inspect}"}
65
65
  end
66
66
 
67
- if element.key?('@id') || element.key?('@value')
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
70
  log_debug("", depth: log_depth.to_i) {"=> scalar result: #{result.inspect}"}
@@ -231,7 +231,7 @@ module JSON::LD
231
231
  unless container.include?('@list')
232
232
  al = context.compact_iri('@list', vocab: true)
233
233
  compacted_item = {al => compacted_item}
234
- if expanded_item.has_key?('@index')
234
+ if expanded_item.key?('@index')
235
235
  key = context.compact_iri('@index', vocab: true)
236
236
  compacted_item[key] = expanded_item['@index']
237
237
  end
@@ -276,7 +276,7 @@ module JSON::LD
276
276
  al = context.compact_iri('@id', vocab: true)
277
277
  compacted_item[al] = context.compact_iri(expanded_item['@id'], vocab: false)
278
278
  end
279
- if expanded_item.has_key?('@index')
279
+ if expanded_item.key?('@index')
280
280
  key = context.compact_iri('@index', vocab: true)
281
281
  compacted_item[key] = expanded_item['@index']
282
282
  end
@@ -314,7 +314,7 @@ module JSON::LD
314
314
  #context_opts.delete(:headers)
315
315
  JSON::LD::API.loadRemoteDocument(context.to_s, **context_opts) do |remote_doc|
316
316
  # 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.
317
- raise JsonLdError::InvalidRemoteContext, "#{context}" unless remote_doc.document.is_a?(Hash) && remote_doc.document.has_key?('@context')
317
+ raise JsonLdError::InvalidRemoteContext, "#{context}" unless remote_doc.document.is_a?(Hash) && remote_doc.document.key?('@context')
318
318
 
319
319
  # Parse stand-alone
320
320
  ctx = Context.new(unfrozen: true, **options).dup
@@ -352,7 +352,7 @@ module JSON::LD
352
352
  '@propagate' => :propagate=,
353
353
  '@vocab' => :vocab=,
354
354
  }.each do |key, setter|
355
- next unless context.has_key?(key)
355
+ next unless context.key?(key)
356
356
  if key == '@import'
357
357
  # Retrieve remote context and merge the remaining context object into the result.
358
358
  raise JsonLdError::InvalidContextEntry, "@import may only be used in 1.1 mode}" if result.processingMode("json-ld-1.0")
@@ -367,11 +367,11 @@ module JSON::LD
367
367
  # FIXME: should cache this, but ContextCache is for parsed contexts
368
368
  JSON::LD::API.loadRemoteDocument(import_loc, **context_opts) do |remote_doc|
369
369
  # Dereference import_loc. 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.
370
- raise JsonLdError::InvalidRemoteContext, "#{import_loc}" unless remote_doc.document.is_a?(Hash) && remote_doc.document.has_key?('@context')
370
+ raise JsonLdError::InvalidRemoteContext, "#{import_loc}" unless remote_doc.document.is_a?(Hash) && remote_doc.document.key?('@context')
371
371
  import_context = remote_doc.document['@context']
372
372
  import_context.delete('@base')
373
373
  raise JsonLdError::InvalidRemoteContext, "#{import_context.to_json} must be an object" unless import_context.is_a?(Hash)
374
- raise JsonLdError::InvalidContextEntry, "#{import_context.to_json} must not include @import entry" if import_context.has_key?('@import')
374
+ raise JsonLdError::InvalidContextEntry, "#{import_context.to_json} must not include @import entry" if import_context.key?('@import')
375
375
  context.delete(key)
376
376
  context = import_context.merge(context)
377
377
  end
@@ -542,7 +542,7 @@ module JSON::LD
542
542
  # Potentially note that the term is protected
543
543
  definition.protected = value.fetch('@protected', protected)
544
544
 
545
- if value.has_key?('@type')
545
+ if value.key?('@type')
546
546
  type = value['@type']
547
547
  # SPEC FIXME: @type may be nil
548
548
  type = case type
@@ -566,7 +566,7 @@ module JSON::LD
566
566
  definition.type_mapping = type
567
567
  end
568
568
 
569
- if value.has_key?('@reverse')
569
+ if value.key?('@reverse')
570
570
  raise JsonLdError::InvalidReverseProperty, "unexpected key in #{value.inspect} on term #{term.inspect}" if
571
571
  value.key?('@id') || value.key?('@nest')
572
572
  raise JsonLdError::InvalidIRIMapping, "expected value of @reverse to be a string: #{value['@reverse'].inspect} on term #{term.inspect}" unless
@@ -592,7 +592,7 @@ module JSON::LD
592
592
  warn "[DEPRECATION] Blank Node terms deprecated in JSON-LD 1.1." if @options[:validate] && processingMode('json-ld-1.1') && definition.id.to_s.start_with?("_:")
593
593
 
594
594
  # If value contains an @container member, set the container mapping of definition to its value; if its value is neither @set, @index, @type, @id, an absolute IRI nor null, an invalid reverse property error has been detected (reverse properties only support set- and index-containers) and processing is aborted.
595
- if value.has_key?('@container')
595
+ if value.key?('@container')
596
596
  container = value['@container']
597
597
  raise JsonLdError::InvalidReverseProperty,
598
598
  "unknown mapping for '@container' to #{container.inspect} on term #{term.inspect}" unless
@@ -600,9 +600,9 @@ module JSON::LD
600
600
  definition.container_mapping = check_container(container, local_context, defined, term)
601
601
  end
602
602
  definition.reverse_property = true
603
- elsif value.has_key?('@id') && value['@id'].nil?
603
+ elsif value.key?('@id') && value['@id'].nil?
604
604
  # Allowed to reserve a null term, which may be protected
605
- elsif value.has_key?('@id') && value['@id'] != term
605
+ elsif value.key?('@id') && value['@id'] != term
606
606
  raise JsonLdError::InvalidIRIMapping, "expected value of @id to be a string: #{value['@id'].inspect} on term #{term.inspect}" unless
607
607
  value['@id'].is_a?(String)
608
608
 
@@ -637,7 +637,7 @@ module JSON::LD
637
637
  elsif term[1..-1].include?(':')
638
638
  # 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.
639
639
  prefix, suffix = term.split(':', 2)
640
- create_term_definition(local_context, prefix, defined, protected: protected) if local_context.has_key?(prefix)
640
+ create_term_definition(local_context, prefix, defined, protected: protected) if local_context.key?(prefix)
641
641
 
642
642
  definition.id = if td = term_definitions[prefix]
643
643
  # If term's prefix has a term definition in active context, set the IRI mapping for definition to the result of concatenating the value associated with the prefix's IRI mapping and the term's suffix.
@@ -664,7 +664,7 @@ module JSON::LD
664
664
 
665
665
  @iri_to_term[definition.id] = term if simple_term && definition.id
666
666
 
667
- if value.has_key?('@container')
667
+ if value.key?('@container')
668
668
  #log_debug("") {"container_mapping: #{value['@container'].inspect}"}
669
669
  definition.container_mapping = check_container(value['@container'], local_context, defined, term)
670
670
 
@@ -679,14 +679,14 @@ module JSON::LD
679
679
  end
680
680
  end
681
681
 
682
- if value.has_key?('@index')
682
+ if value.key?('@index')
683
683
  # property-based indexing
684
684
  raise JsonLdError::InvalidTermDefinition, "@index without @index in @container: #{value['@index']} on term #{term.inspect}" unless definition.container_mapping.include?('@index')
685
685
  raise JsonLdError::InvalidTermDefinition, "@index must expand to an IRI: #{value['@index']} on term #{term.inspect}" unless value['@index'].is_a?(String) && !value['@index'].start_with?('@')
686
686
  definition.index = value['@index'].to_s
687
687
  end
688
688
 
689
- if value.has_key?('@context')
689
+ if value.key?('@context')
690
690
  begin
691
691
  new_ctx = self.parse(value['@context'],
692
692
  base: base,
@@ -704,7 +704,7 @@ module JSON::LD
704
704
  end
705
705
  end
706
706
 
707
- if value.has_key?('@language')
707
+ if value.key?('@language')
708
708
  language = value['@language']
709
709
  language = case value['@language']
710
710
  when String
@@ -722,14 +722,14 @@ module JSON::LD
722
722
  definition.language_mapping = language || false
723
723
  end
724
724
 
725
- if value.has_key?('@direction')
725
+ if value.key?('@direction')
726
726
  direction = value['@direction']
727
727
  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)
728
728
  #log_debug("") {"direction_mapping: #{direction.inspect}"}
729
729
  definition.direction_mapping = direction || false
730
730
  end
731
731
 
732
- if value.has_key?('@nest')
732
+ if value.key?('@nest')
733
733
  nest = value['@nest']
734
734
  raise JsonLdError::InvalidNestValue, "nest must be a string, was #{nest.inspect}} on term #{term.inspect}" unless nest.is_a?(String)
735
735
  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'
@@ -737,7 +737,7 @@ module JSON::LD
737
737
  definition.nest = nest
738
738
  end
739
739
 
740
- if value.has_key?('@prefix')
740
+ if value.key?('@prefix')
741
741
  raise JsonLdError::InvalidTermDefinition, "@prefix used on compact or relative IRI term #{term.inspect}" if term.match?(%r{:|/})
742
742
  case pfx = value['@prefix']
743
743
  when TrueClass, FalseClass
@@ -1018,7 +1018,7 @@ module JSON::LD
1018
1018
 
1019
1019
  term_sym = term.empty? ? "" : term.to_sym
1020
1020
  iri_to_term.delete(term_definitions[term].id.to_s) if term_definitions[term].id.is_a?(String)
1021
- @options[:prefixes][term_sym] = value if @options.has_key?(:prefixes)
1021
+ @options[:prefixes][term_sym] = value if @options.key?(:prefixes)
1022
1022
  iri_to_term[value.to_s] = term
1023
1023
  term_definitions[term]
1024
1024
  end
@@ -1134,7 +1134,7 @@ module JSON::LD
1134
1134
  # @return [Term] related term definition
1135
1135
  def reverse_term(term)
1136
1136
  # Direct lookup of term
1137
- term = term_definitions[term.to_s] if term_definitions.has_key?(term.to_s) && !term.is_a?(TermDefinition)
1137
+ term = term_definitions[term.to_s] if term_definitions.key?(term.to_s) && !term.is_a?(TermDefinition)
1138
1138
 
1139
1139
  # Lookup term, assuming term is an IRI
1140
1140
  unless term.is_a?(TermDefinition)
@@ -1182,7 +1182,7 @@ module JSON::LD
1182
1182
  defined = defined || {} # if we initialized in the keyword arg we would allocate {} at each invokation, even in the 2 (common) early returns above.
1183
1183
 
1184
1184
  # If local context is not null, it contains a key that equals value, and the value associated with the key that equals value in defined is not true, then invoke the Create Term Definition subalgorithm, passing active context, local context, value as term, and defined. This will ensure that a term definition is created for value in active context during Context Processing.
1185
- if local_context && local_context.has_key?(value) && !defined[value]
1185
+ if local_context && local_context.key?(value) && !defined[value]
1186
1186
  create_term_definition(local_context, value, defined)
1187
1187
  end
1188
1188
 
@@ -1212,7 +1212,7 @@ module JSON::LD
1212
1212
  end
1213
1213
 
1214
1214
  # If local context is not null, it contains a key that equals prefix, and the value associated with the key that equals prefix in defined is not true, invoke the Create Term Definition algorithm, passing active context, local context, prefix as term, and defined. This will ensure that a term definition is created for prefix in active context during Context Processing.
1215
- if local_context && local_context.has_key?(prefix) && !defined[prefix]
1215
+ if local_context && local_context.key?(prefix) && !defined[prefix]
1216
1216
  create_term_definition(local_context, prefix, defined)
1217
1217
  end
1218
1218
 
@@ -1287,7 +1287,7 @@ module JSON::LD
1287
1287
  return if iri.nil?
1288
1288
  iri = iri.to_s
1289
1289
 
1290
- if vocab && inverse_context.has_key?(iri)
1290
+ if vocab && inverse_context.key?(iri)
1291
1291
  default_language = if self.default_direction
1292
1292
  "#{self.default_language}_#{self.default_direction}".downcase
1293
1293
  else
@@ -1298,7 +1298,7 @@ module JSON::LD
1298
1298
  containers.concat(CONTAINERS_INDEX_SET) if index?(value) && !graph?(value)
1299
1299
 
1300
1300
  # If the value is a JSON Object with the key @preserve, use the value of @preserve.
1301
- value = value['@preserve'].first if value.is_a?(Hash) && value.has_key?('@preserve')
1301
+ value = value['@preserve'].first if value.is_a?(Hash) && value.key?('@preserve')
1302
1302
 
1303
1303
  if reverse
1304
1304
  tl, tl_value = "@type", "@reverse"
@@ -1312,11 +1312,11 @@ module JSON::LD
1312
1312
  list.each do |item|
1313
1313
  item_language, item_type = "@none", "@none"
1314
1314
  if value?(item)
1315
- if item.has_key?('@direction')
1315
+ if item.key?('@direction')
1316
1316
  item_language = "#{item['@language']}_#{item['@direction']}".downcase
1317
- elsif item.has_key?('@language')
1317
+ elsif item.key?('@language')
1318
1318
  item_language = item['@language'].downcase
1319
- elsif item.has_key?('@type')
1319
+ elsif item.key?('@type')
1320
1320
  item_type = item['@type']
1321
1321
  else
1322
1322
  item_language = "@null"
@@ -1344,14 +1344,14 @@ module JSON::LD
1344
1344
  elsif graph?(value)
1345
1345
  # Prefer @index and @id containers, then @graph, then @index
1346
1346
  containers.concat(CONTAINERS_GRAPH_INDEX_INDEX) if index?(value)
1347
- containers.concat(CONTAINERS_GRAPH) if value.has_key?('@id')
1347
+ containers.concat(CONTAINERS_GRAPH) if value.key?('@id')
1348
1348
 
1349
1349
  # Prefer an @graph container next
1350
1350
  containers.concat(CONTAINERS_GRAPH_SET)
1351
1351
 
1352
1352
  # Lastly, in 1.1, any graph can be indexed on @index or @id, so add if we haven't already
1353
1353
  containers.concat(CONTAINERS_GRAPH_INDEX) unless index?(value)
1354
- containers.concat(CONTAINERS_GRAPH) unless value.has_key?('@id')
1354
+ containers.concat(CONTAINERS_GRAPH) unless value.key?('@id')
1355
1355
  containers.concat(CONTAINERS_INDEX_SET) unless index?(value)
1356
1356
  containers << '@set'
1357
1357
 
@@ -1359,13 +1359,13 @@ module JSON::LD
1359
1359
  else
1360
1360
  if value?(value)
1361
1361
  # In 1.1, an language map can be used to index values using @none
1362
- if value.has_key?('@language') && !index?(value)
1362
+ if value.key?('@language') && !index?(value)
1363
1363
  tl_value = value['@language'].downcase
1364
1364
  tl_value += "_#{value['@direction']}" if value['@direction']
1365
1365
  containers.concat(CONTAINERS_LANGUAGE)
1366
- elsif value.has_key?('@direction') && !index?(value)
1366
+ elsif value.key?('@direction') && !index?(value)
1367
1367
  tl_value = "_#{value['@direction']}"
1368
- elsif value.has_key?('@type')
1368
+ elsif value.key?('@type')
1369
1369
  tl_value = value['@type']
1370
1370
  tl = '@type'
1371
1371
  end
@@ -1387,7 +1387,7 @@ module JSON::LD
1387
1387
  tl_value ||= '@null'
1388
1388
  preferred_values = []
1389
1389
  preferred_values << '@reverse' if tl_value == '@reverse'
1390
- if (tl_value == '@id' || tl_value == '@reverse') && value.is_a?(Hash) && value.has_key?('@id')
1390
+ if (tl_value == '@id' || tl_value == '@reverse') && value.is_a?(Hash) && value.key?('@id')
1391
1391
  t_iri = compact_iri(value['@id'], vocab: true, base: base)
1392
1392
  if (r_td = term_definitions[t_iri]) && r_td.id == value['@id']
1393
1393
  preferred_values.concat(CONTAINERS_VOCAB_ID)
@@ -1413,7 +1413,7 @@ module JSON::LD
1413
1413
  # At this point, there is no simple term that iri can be compacted to. If vocab is true and active context has a vocabulary mapping:
1414
1414
  if vocab && self.vocab && iri.start_with?(self.vocab) && iri.length > self.vocab.length
1415
1415
  suffix = iri[self.vocab.length..-1]
1416
- return suffix unless term_definitions.has_key?(suffix)
1416
+ return suffix unless term_definitions.key?(suffix)
1417
1417
  end
1418
1418
 
1419
1419
  # The iri could not be compacted using the active context's vocabulary mapping. Try to create a compact IRI, starting by initializing compact IRI to null. This variable will be used to tore the created compact IRI, if any.
@@ -1427,7 +1427,7 @@ module JSON::LD
1427
1427
 
1428
1428
  suffix = iri[td.id.length..-1]
1429
1429
  ciri = "#{term}:#{suffix}"
1430
- candidates << ciri unless value && term_definitions.has_key?(ciri)
1430
+ candidates << ciri unless value && term_definitions.key?(ciri)
1431
1431
  end
1432
1432
 
1433
1433
  return candidates.sort.first if !candidates.empty?
@@ -1523,16 +1523,16 @@ module JSON::LD
1523
1523
  res['@language'] = lang
1524
1524
  end
1525
1525
  res['@direction'] = dir
1526
- elsif useNativeTypes && RDF_LITERAL_NATIVE_TYPES.include?(value.datatype)
1526
+ elsif useNativeTypes && RDF_LITERAL_NATIVE_TYPES.include?(value.datatype) && value.valid?
1527
1527
  res['@type'] = uri(coerce(property)) if coerce(property)
1528
1528
  res['@value'] = value.object
1529
1529
  else
1530
- value.canonicalize! if value.datatype == RDF::XSD.double
1530
+ value.canonicalize! if value.valid? && value.datatype == RDF::XSD.double
1531
1531
  if coerce(property)
1532
1532
  res['@type'] = uri(coerce(property)).to_s
1533
- elsif value.has_datatype?
1533
+ elsif value.datatype?
1534
1534
  res['@type'] = uri(value.datatype).to_s
1535
- elsif value.has_language? || language(property)
1535
+ elsif value.language? || language(property)
1536
1536
  res['@language'] = (value.language || language(property)).to_s
1537
1537
  end
1538
1538
  res['@value'] = value.to_s
@@ -1580,15 +1580,15 @@ module JSON::LD
1580
1580
  direction = direction(property)
1581
1581
 
1582
1582
  result = case
1583
- when coerce(property) == '@id' && value.has_key?('@id') && (value.keys - %w(@id @index)).empty?
1583
+ when coerce(property) == '@id' && value.key?('@id') && (value.keys - %w(@id @index)).empty?
1584
1584
  # Compact an @id coercion
1585
1585
  #log_debug("") {" (@id & coerce)"}
1586
1586
  compact_iri(value['@id'], base: base)
1587
- when coerce(property) == '@vocab' && value.has_key?('@id') && (value.keys - %w(@id @index)).empty?
1587
+ when coerce(property) == '@vocab' && value.key?('@id') && (value.keys - %w(@id @index)).empty?
1588
1588
  # Compact an @id coercion
1589
1589
  #log_debug("") {" (@id & coerce & vocab)"}
1590
1590
  compact_iri(value['@id'], vocab: true)
1591
- when value.has_key?('@id')
1591
+ when value.key?('@id')
1592
1592
  #log_debug("") {" (@id)"}
1593
1593
  # return value as is
1594
1594
  value
@@ -1609,7 +1609,7 @@ module JSON::LD
1609
1609
  value
1610
1610
  end
1611
1611
 
1612
- if result.is_a?(Hash) && result.has_key?('@type') && value['@type'] != '@json'
1612
+ if result.is_a?(Hash) && result.key?('@type') && value['@type'] != '@json'
1613
1613
  # Compact values of @type
1614
1614
  c_type = if result['@type'].is_a?(Array)
1615
1615
  result['@type'].map {|t| compact_iri(t, vocab: true)}
@@ -1857,11 +1857,11 @@ module JSON::LD
1857
1857
  container_map = inverse_context[iri]
1858
1858
  #log_debug(" ") {"container_map: #{container_map.inspect}"}
1859
1859
  containers.each do |container|
1860
- next unless container_map.has_key?(container)
1860
+ next unless container_map.key?(container)
1861
1861
  tl_map = container_map[container]
1862
1862
  value_map = tl_map[type_language]
1863
1863
  preferred_values.each do |item|
1864
- next unless value_map.has_key?(item)
1864
+ next unless value_map.key?(item)
1865
1865
  #log_debug("=>") {value_map[item].inspect}
1866
1866
  return value_map[item]
1867
1867
  end