2016-10-15 16:26:56 +00:00
|
|
|
defmodule RDF do
|
2017-06-11 20:54:41 +00:00
|
|
|
alias RDF.{Namespace, Literal, BlankNode, Triple, Quad}
|
2016-10-15 16:26:56 +00:00
|
|
|
|
|
|
|
@doc """
|
2017-03-12 13:27:52 +00:00
|
|
|
Generator function for URIs from strings or term atoms of a `RDF.Namespace`.
|
2016-10-15 16:26:56 +00:00
|
|
|
|
2017-04-10 01:06:20 +00:00
|
|
|
This function is used for the `~I` sigil.
|
|
|
|
|
2016-10-15 16:26:56 +00:00
|
|
|
## Examples
|
|
|
|
|
|
|
|
iex> RDF.uri("http://www.example.com/foo")
|
|
|
|
%URI{authority: "www.example.com", fragment: nil, host: "www.example.com",
|
|
|
|
path: "/foo", port: 80, query: nil, scheme: "http", userinfo: nil}
|
|
|
|
|
2017-03-12 13:27:52 +00:00
|
|
|
iex> RDF.uri(RDF.NS.RDFS.Class)
|
2016-10-15 16:26:56 +00:00
|
|
|
%URI{authority: "www.w3.org", fragment: "Class", host: "www.w3.org",
|
|
|
|
path: "/2000/01/rdf-schema", port: 80, query: nil, scheme: "http",
|
|
|
|
userinfo: nil}
|
|
|
|
|
|
|
|
iex> RDF.uri("not a uri")
|
|
|
|
** (RDF.InvalidURIError) string "not a uri" is not a valid URI
|
|
|
|
"""
|
|
|
|
@spec uri(URI.t | binary | atom) :: URI.t
|
2017-03-12 13:27:52 +00:00
|
|
|
def uri(atom) when is_atom(atom), do: Namespace.resolve_term(atom)
|
|
|
|
|
2016-10-15 16:26:56 +00:00
|
|
|
def uri(string) do
|
|
|
|
parsed_uri = URI.parse(string)
|
|
|
|
if uri?(parsed_uri) do
|
|
|
|
parsed_uri
|
|
|
|
else
|
2016-11-04 21:13:06 +00:00
|
|
|
raise RDF.InvalidURIError, ~s(string "#{string}" is not a valid URI)
|
2016-10-15 16:26:56 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
@doc """
|
|
|
|
Checks if the given value is an URI.
|
|
|
|
|
|
|
|
## Examples
|
|
|
|
|
|
|
|
iex> RDF.uri?("http://www.example.com/foo")
|
|
|
|
true
|
|
|
|
iex> RDF.uri?("not a uri")
|
|
|
|
false
|
|
|
|
"""
|
|
|
|
def uri?(some_uri = %URI{}) do
|
|
|
|
# The following was a suggested at http://stackoverflow.com/questions/30696761/check-if-a-url-is-valid-in-elixir
|
|
|
|
# TODO: Find a better way! Maybe https://github.com/marcelog/ex_rfc3986 ?
|
|
|
|
case some_uri do
|
|
|
|
%URI{scheme: nil} -> false
|
|
|
|
_uri -> true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
def uri?(value) when is_binary(value), do: uri?(URI.parse(value))
|
|
|
|
def uri?(_), do: false
|
|
|
|
|
|
|
|
|
|
|
|
@doc """
|
|
|
|
Generator function for `RDF.Literal` values.
|
|
|
|
|
|
|
|
## Examples
|
|
|
|
|
|
|
|
iex> RDF.literal(42)
|
2017-04-23 21:41:29 +00:00
|
|
|
%RDF.Literal{value: 42, datatype: XSD.integer}
|
2016-10-15 16:26:56 +00:00
|
|
|
"""
|
|
|
|
def literal(value)
|
|
|
|
|
|
|
|
def literal(lit = %Literal{}), do: lit
|
|
|
|
def literal(value), do: Literal.new(value)
|
2017-04-16 21:13:39 +00:00
|
|
|
def literal(value, opts), do: Literal.new(value, opts)
|
2016-10-15 16:26:56 +00:00
|
|
|
|
|
|
|
@doc """
|
|
|
|
Generator function for `RDF.Triple`s.
|
|
|
|
|
|
|
|
## Examples
|
|
|
|
|
|
|
|
iex> RDF.triple("http://example.com/S", "http://example.com/p", 42)
|
|
|
|
{RDF.uri("http://example.com/S"), RDF.uri("http://example.com/p"), RDF.literal(42)}
|
2017-06-11 20:54:41 +00:00
|
|
|
iex> RDF.triple(EX.S, EX.p, 42)
|
|
|
|
{RDF.uri("http://example.com/S"), RDF.uri("http://example.com/p"), RDF.literal(42)}
|
2016-10-15 16:26:56 +00:00
|
|
|
"""
|
|
|
|
def triple(subject, predicate, object), do: Triple.new(subject, predicate, object)
|
|
|
|
def triple(tuple), do: Triple.new(tuple)
|
|
|
|
|
2017-06-11 20:54:41 +00:00
|
|
|
@doc """
|
|
|
|
Generator function for `RDF.quad`s.
|
|
|
|
|
|
|
|
## Examples
|
|
|
|
|
|
|
|
iex> RDF.quad("http://example.com/S", "http://example.com/p", 42, "http://example.com/Graph")
|
|
|
|
{RDF.uri("http://example.com/S"), RDF.uri("http://example.com/p"), RDF.literal(42), RDF.uri("http://example.com/Graph")}
|
|
|
|
iex> RDF.quad(EX.S, EX.p, 42, EX.Graph)
|
|
|
|
{RDF.uri("http://example.com/S"), RDF.uri("http://example.com/p"), RDF.literal(42), RDF.uri("http://example.com/Graph")}
|
|
|
|
"""
|
|
|
|
def quad(subject, predicate, object, graph_context),
|
|
|
|
do: Quad.new(subject, predicate, object, graph_context)
|
|
|
|
def quad(tuple), do: Quad.new(tuple)
|
|
|
|
|
2016-10-15 16:26:56 +00:00
|
|
|
|
|
|
|
@doc """
|
2017-02-12 14:42:27 +00:00
|
|
|
Generator function for `RDF.BlankNode`s.
|
2016-10-15 16:26:56 +00:00
|
|
|
"""
|
|
|
|
def bnode, do: BlankNode.new
|
|
|
|
|
|
|
|
@doc """
|
2017-02-12 14:42:27 +00:00
|
|
|
Generator function for `RDF.BlankNode`s with a user-defined identity.
|
2016-10-15 16:26:56 +00:00
|
|
|
|
|
|
|
## Examples
|
|
|
|
|
|
|
|
iex> RDF.bnode(:foo)
|
2017-05-19 16:08:59 +00:00
|
|
|
%RDF.BlankNode{id: "foo"}
|
2016-10-15 16:26:56 +00:00
|
|
|
"""
|
2016-10-30 18:36:46 +00:00
|
|
|
def bnode(id), do: BlankNode.new(id)
|
|
|
|
|
|
|
|
|
2016-11-02 02:19:19 +00:00
|
|
|
@doc """
|
|
|
|
Checks if the given value is a RDF resource.
|
|
|
|
|
|
|
|
## Examples
|
|
|
|
|
|
|
|
iex> RDF.resource?(RDF.uri("http://example.com/resource"))
|
|
|
|
true
|
|
|
|
iex> RDF.resource?(EX.resource)
|
|
|
|
true
|
|
|
|
iex> RDF.resource?(RDF.bnode)
|
|
|
|
true
|
|
|
|
iex> RDF.resource?(42)
|
|
|
|
false
|
|
|
|
"""
|
|
|
|
def resource?(value)
|
|
|
|
def resource?(%URI{}), do: true
|
2017-03-12 13:27:52 +00:00
|
|
|
def resource?(atom) when is_atom(atom), do: resource?(Namespace.resolve_term(atom))
|
2016-11-02 02:19:19 +00:00
|
|
|
def resource?(%BlankNode{}), do: true
|
|
|
|
def resource?(_), do: false
|
|
|
|
|
|
|
|
|
2017-06-10 21:08:49 +00:00
|
|
|
for term <- ~w[type subject predicate object first rest value]a do
|
|
|
|
defdelegate unquote(term)(), to: RDF.NS.RDF
|
|
|
|
defdelegate unquote(term)(s, o), to: RDF.NS.RDF
|
|
|
|
defdelegate unquote(term)(s, o1, o2), to: RDF.NS.RDF
|
|
|
|
defdelegate unquote(term)(s, o1, o2, o3), to: RDF.NS.RDF
|
|
|
|
defdelegate unquote(term)(s, o1, o2, o3, o4), to: RDF.NS.RDF
|
|
|
|
defdelegate unquote(term)(s, o1, o2, o3, o4, o5), to: RDF.NS.RDF
|
|
|
|
end
|
2017-05-29 21:12:50 +00:00
|
|
|
|
2017-06-10 21:08:49 +00:00
|
|
|
defdelegate langString(), to: RDF.NS.RDF
|
|
|
|
defdelegate unquote(nil)(), to: RDF.NS.RDF
|
2016-10-15 16:26:56 +00:00
|
|
|
|
|
|
|
end
|