json_ld: fix base iri handling

This commit is contained in:
Marcel Otto 2017-03-29 23:32:59 +02:00
parent b2eb8aaa07
commit efcdccd735
3 changed files with 17 additions and 10 deletions

View file

@ -7,7 +7,7 @@ defmodule JSON.LD.Compaction do
def compact(input, context, options \\ %JSON.LD.Options{}) do
with options = JSON.LD.Options.new(options),
active_context = JSON.LD.context(context),
active_context = JSON.LD.context(context, options),
inverse_context = Context.inverse(active_context),
expanded = JSON.LD.expand(input, options)
do
@ -432,7 +432,7 @@ defmodule JSON.LD.Compaction do
compact_iri
# 7) If vocab is false then transform iri to a relative IRI using the document's base IRI.
not vocab ->
remove_base(iri, active_context.base_iri)
remove_base(iri, Context.base(active_context))
# 8) Finally, return iri as is.
true ->
iri

View file

@ -1,8 +1,9 @@
defmodule JSON.LD.Context do
defstruct term_defs: %{},
default_language: nil,
vocab: nil,
base_iri: nil,
default_language: nil
base_iri: false,
api_base_iri: nil
import JSON.LD.IRIExpansion
import JSON.LD.Utils
@ -10,10 +11,15 @@ defmodule JSON.LD.Context do
alias JSON.LD.Context.TermDefinition
def new(options \\ %JSON.LD.Options{}),
do: %JSON.LD.Context{base_iri: JSON.LD.Options.new(options).base}
def base(%JSON.LD.Context{base_iri: false, api_base_iri: api_base_iri}),
do: api_base_iri
def base(%JSON.LD.Context{base_iri: base_iri}),
do: base_iri
def new(options \\ %JSON.LD.Options{}),
do: %JSON.LD.Context{api_base_iri: JSON.LD.Options.new(options).base}
def create(%{"@context" => json_ld_context}, options),
do: new(options) |> update(json_ld_context, [], options)
@ -31,9 +37,10 @@ defmodule JSON.LD.Context do
update(active, [local], remote, options)
end
# 3.1) If context is null, set result to a newly-initialized active context and continue with the next context. The base IRI of the active context is set to the IRI of the currently being processed document (which might be different from the currently being processed context), if available; otherwise to null. If set, the base option of a JSON-LD API Implementation overrides the base IRI.
defp do_update(%JSON.LD.Context{} = active, nil, remote, options) do
JSON.LD.Context.new(base: JSON.LD.Options.new(options).base || active.base_iri)
defp do_update(%JSON.LD.Context{}, nil, remote, options) do
new(options)
end
# 3.2) If context is a string, [it's interpreted as a remote context]
@ -368,7 +375,7 @@ defmodule JSON.LD.Context do
end)
end
def empty?(%JSON.LD.Context{term_defs: term_defs, vocab: nil, base_iri: nil, default_language: nil})
def empty?(%JSON.LD.Context{term_defs: term_defs, vocab: nil, base_iri: false, default_language: nil})
when map_size(term_defs) == 0,
do: true
def empty?(_),

View file

@ -55,7 +55,7 @@ defmodule JSON.LD.IRIExpansion do
vocabulary_mapping <> value
# 6) Otherwise, if document relative is true, set value to the result of resolving value against the base IRI. 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].
doc_relative ->
absolute_iri(value, active_context.base_iri)
absolute_iri(value, JSON.LD.Context.base(active_context))
# TODO: RDF.rb's implementation differs from the spec here, by checking if base_iri is actually present in the previous clause and adding the following additional clause. Another Spec error?
# if local_context && RDF::URI(value).relative?
# # 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.