Add default_base_iri configuration and use it for serialization readers

This commit is contained in:
Marcel Otto 2018-08-17 01:31:08 +02:00
parent 87b34f8464
commit 81cfcff5d7
4 changed files with 39 additions and 5 deletions

View file

@ -19,7 +19,9 @@ This project adheres to [Semantic Versioning](http://semver.org/) and
- the logical operators and the Effective Boolean Value (EBV) coercion algorithm
from the XPath and SPARQL specs on `RDF.Boolean`
- `RDF.Term.equal?/2` and `RDF.Term.equal_value?/2`
- `RDF.LangString.match_language?/2`
- `RDF.LangString.match_language?/2`
- possibility to configure an application-specific default base IRI; for now it
is used only on reading of RDF serializations (when no `base` specified)
### Changed

View file

@ -716,6 +716,14 @@ RDF.read_file!("/path/to/some_file.ttl")
|> RDF.write_file!("/path/to/some_file.jsonld")
```
For serialization formats which support it, you can provide a base IRI on the read functions with the `base` option. You can also provide a default base IRI in your application configuration, which will be used when no `base` option is given.
```elixir
config :rdf,
default_base_iri: "http://my_app.example/"
```
## Getting help

View file

@ -25,6 +25,19 @@ defmodule RDF.IRI do
# see https://tools.ietf.org/html/rfc3986#appendix-B
@scheme_regex Regex.recompile!(~r/^([a-z][a-z0-9\+\-\.]*):/i)
@doc """
The default base IRI to be used when reading a serialization and no `base` option is provided.
The value can be set via the `default_base_iri` configuration. For example:
config :rdf,
default_base_iri: "http://my_app.example/"
See [section 5.1.4 of RFC 3987](https://tools.ietf.org/html/rfc3986#page-29)
"""
@default_base Application.get_env(:rdf, :default_base_iri)
def default_base, do: @default_base
@doc """
Creates a `RDF.IRI`.

View file

@ -2,6 +2,9 @@ defmodule RDF.Serialization.Reader do
@moduledoc """
General functions for reading a `RDF.Graph` or `RDF.Dataset` from a serialization file or encoded-string.
If no base IRI is provided with the `base` option on any of these functions,
the `RDF.IRI.default_base/0` is used.
You probably won't use these functions directly, but instead use the automatically
generated functions with same name on a `RDF.Serialization.Format`, which implicitly
use the proper `RDF.Serialization.Decoder` module.
@ -15,7 +18,7 @@ defmodule RDF.Serialization.Reader do
dataset, or `{:error, reason}` if an error occurs.
"""
def read_string(decoder, content, opts \\ []) do
decoder.decode(content, opts)
decoder.decode(content, with_base(opts))
end
@doc """
@ -24,7 +27,7 @@ defmodule RDF.Serialization.Reader do
As opposed to `read_string`, it raises an exception if an error occurs.
"""
def read_string!(decoder, content, opts \\ []) do
decoder.decode!(content, opts)
decoder.decode!(content, with_base(opts))
end
@doc """
@ -35,7 +38,7 @@ defmodule RDF.Serialization.Reader do
"""
def read_file(decoder, file, opts \\ []) do
case File.read(file) do
{:ok, content} -> read_string(decoder, content, opts)
{:ok, content} -> read_string(decoder, content, with_base(opts))
{:error, reason} -> {:error, reason}
end
end
@ -47,7 +50,15 @@ defmodule RDF.Serialization.Reader do
"""
def read_file!(decoder, file, opts \\ []) do
with content = File.read!(file) do
read_string!(decoder, content, opts)
read_string!(decoder, content, with_base(opts))
end
end
defp with_base(opts) do
cond do
Keyword.has_key?(opts, :base) -> opts
base = RDF.IRI.default_base() -> Keyword.put(opts, :base, base)
true -> opts
end
end