Skip to content

Commit

Permalink
[mod_ginger_rdf] Make parser more robust against variants of nesting (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
robvandenbogaard authored Jul 8, 2024
1 parent ff03fee commit 1f67d65
Showing 1 changed file with 19 additions and 9 deletions.
28 changes: 19 additions & 9 deletions modules/mod_ginger_rdf/support/ginger_json_ld.erl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
serialize/1,
serialize_to_map/1,
deserialize/1,
deserialize/2,
open/1,
open_file/1,
compact/1
Expand Down Expand Up @@ -238,26 +239,35 @@ compact_predicate(Predicate) ->
%% @doc Deserialize a JSON-LD document into an RDF resource.
-spec deserialize(tuple() | list()) -> #rdf_resource{}.
deserialize(JsonLd) when is_map(JsonLd) ->
Context = maps:get(<<"@context">>, JsonLd, #{}),
deserialize_with_context(undefined, JsonLd, #{});
deserialize(JsonLd) ->
%% Fall back to mochijson {struct, ...} structure
open(JsonLd).

%% Guide the parser; indicate that we are actually looking for a specific id
%% so we don't get confused when we encounter multiple subjects in the jsonld.
deserialize(Id, JsonLd) when is_map(JsonLd) ->
deserialize_with_context(Id, JsonLd, #{}).

deserialize_with_context(Id, JsonLd, Context) ->
LocalContext = maps:get(<<"@context">>, JsonLd, #{}),
TotalContext = maps:merge(Context, LocalContext),
maps:fold(
fun(Key, Value, Acc) ->
deserialize(Key, Value, Acc, Context)
deserialize(Key, Value, Acc, TotalContext)
end,
#rdf_resource{},
#rdf_resource{id = Id},
maps:remove(<<"@context">>, JsonLd)
);
deserialize(JsonLd) ->
%% Fall back to mochijson {struct, ...} structure
open(JsonLd).
).

deserialize(<<"@id">>, Uri, #rdf_resource{} = Acc, _Context) ->
Acc#rdf_resource{id = Uri};
deserialize(Predicate, #{<<"@id">> := Uri}, #rdf_resource{} = Acc, Context) ->
deserialize(Predicate, Uri, Acc, Context);
deserialize(<<"@graph">>, Triples, #rdf_resource{triples = ParentTriples} = Acc, _Context) ->
deserialize(<<"@graph">>, Triples, #rdf_resource{triples = ParentTriples} = Acc, Context) ->
AllTriples = lists:foldl(
fun(#{<<"@id">> := _Subject} = Map, ParentAcc) ->
#rdf_resource{triples = GraphTriples} = deserialize(Map),
#rdf_resource{triples = GraphTriples} = deserialize_with_context(undefined, Map, Context),
lists:merge(GraphTriples, ParentAcc)
end,
ParentTriples,
Expand Down

0 comments on commit 1f67d65

Please sign in to comment.