Skip to content

Commit

Permalink
Allow @set coercion on @type or an alias to affect compaction res…
Browse files Browse the repository at this point in the history
…ults.
  • Loading branch information
gkellogg committed Oct 1, 2018
1 parent f0dfb93 commit 9f64b38
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 7 deletions.
5 changes: 4 additions & 1 deletion lib/json/ld/compact.rb
Expand Up @@ -85,7 +85,10 @@ def compact(element, property: nil, ordered: false)
context.compact_iri(expanded_type, vocab: (expanded_property == '@type'), log_depth: @options[:log_depth])
end

compacted_value = compacted_value.first if compacted_value.length == 1
kw_alias = context.compact_iri(expanded_property, vocab: true)
as_array = (context.as_array?(kw_alias) && !value?(element)) ||
compacted_value.length > 1
compacted_value = compacted_value.first unless as_array

al = context.compact_iri(expanded_property, vocab: true, quiet: true)
#log_debug(expanded_property) {"result[#{al}] = #{compacted_value.inspect}"}
Expand Down
20 changes: 14 additions & 6 deletions lib/json/ld/context.rb
Expand Up @@ -489,7 +489,8 @@ def parse(local_context, remote_contexts = [])

# For each key-value pair in context invoke the Create Term Definition subalgorithm, passing result for active context, context for local context, key, and defined
context.each_key do |key|
result.create_term_definition(context, key, defined)
# ... where key is not @base, @vocab, @language, or @version
result.create_term_definition(context, key, defined) unless NON_TERMDEF_KEYS.include?(key)
end
else
# 3.3) If context is not a JSON object, an invalid local context error has been detected and processing is aborted.
Expand Down Expand Up @@ -529,6 +530,7 @@ def merge!(context)

# The following constants are used to reduce object allocations in #create_term_definition below
ID_NULL_OBJECT = { '@id' => nil }.freeze
NON_TERMDEF_KEYS = Set.new(%w(@base @vocab @language @version)).freeze
JSON_LD_10_EXPECTED_KEYS = Set.new(%w(@container @id @language @reverse @type)).freeze
JSON_LD_EXPECTED_KEYS = Set.new(%w(@container @context @id @language @nest @prefix @reverse @type)).freeze

Expand Down Expand Up @@ -558,8 +560,14 @@ def create_term_definition(local_context, term, defined)
raise JsonLdError::CyclicIRIMapping, "Cyclical term dependency found: #{term.inspect}"
end

# Initialize value to a the value associated with the key term in local context.
value = local_context.fetch(term, false)
simple_term = value.is_a?(String)

# Since keywords cannot be overridden, term must not be a keyword. Otherwise, an invalid value has been detected, which is an error.
if KEYWORDS.include?(term) && (term != '@vocab' && term != '@language' && term != '@version')
if term == '@type' && value == {'@container' => '@set'}
# this is the only case were redefining a keyword is allowed
elsif KEYWORDS.include?(term)
raise JsonLdError::KeywordRedefinition, "term must not be a keyword: #{term.inspect}" if
@options[:validate]
elsif !term_valid?(term) && @options[:validate]
Expand All @@ -569,9 +577,6 @@ def create_term_definition(local_context, term, defined)
# Remove any existing term definition for term in active context.
term_definitions.delete(term)

# Initialize value to a the value associated with the key term in local context.
value = local_context.fetch(term, false)
simple_term = value.is_a?(String)
value = {'@id' => value} if simple_term

case value
Expand Down Expand Up @@ -672,6 +677,9 @@ def create_term_definition(local_context, term, defined)
term
end
#log_debug("") {"=> #{definition.id}"}
elsif KEYWORDS.include?(term)
# This should only happen for @type when @container is @set
definition.id = term
else
# 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.
raise JsonLdError::InvalidIRIMapping, "relative term definition without vocab: #{term} on term #{term.inspect}" unless vocab
Expand Down Expand Up @@ -881,7 +889,7 @@ def find_definition(term)
# @param [Term, #to_s] term in unexpanded form
# @return [Array<'@index', '@language', '@index', '@set', '@type', '@id', '@graph'>]
def container(term)
return [term] if KEYWORDS.include?(term)
return [term] if term == '@list'
term = find_definition(term)
term ? term.container_mapping : []
end
Expand Down
24 changes: 24 additions & 0 deletions spec/compact_spec.rb
Expand Up @@ -125,6 +125,18 @@
"b": ["c"]
})
},
"@set coercion on @type" => {
input: %({
"@type": "http://www.w3.org/2000/01/rdf-schema#Resource",
"http://example.org/foo": {"@value": "bar", "@type": "http://example.com/type"}
}),
context: %({"@type": {"@container": "@set"}}),
output: %({
"@context": {"@type": {"@container": "@set"}},
"@type": ["http://www.w3.org/2000/01/rdf-schema#Resource"],
"http://example.org/foo": {"@value": "bar", "@type": "http://example.com/type"}
})
},
"empty @set coercion" => {
input: %({
"http://example.com/b": []
Expand Down Expand Up @@ -206,6 +218,18 @@
"http://example.org/foo": {"@value": "bar", "type": "http://example.com/type"}
})
},
"@type with @container: @set": {
input: %({
"@type": "http://www.w3.org/2000/01/rdf-schema#Resource",
"http://example.org/foo": {"@value": "bar", "@type": "http://example.com/type"}
}),
context: %({"type": {"@id": "@type", "@container": "@set"}}),
output: %({
"@context": {"type": {"@id": "@type", "@container": "@set"}},
"type": ["http://www.w3.org/2000/01/rdf-schema#Resource"],
"http://example.org/foo": {"@value": "bar", "type": "http://example.com/type"}
})
},
"@language" => {
input: %({
"http://example.org/foo": {"@value": "bar", "@language": "baz"}
Expand Down

0 comments on commit 9f64b38

Please sign in to comment.