Skip to content

Commit 594306e

Browse files
committed
Allow annotation of triples including a triple term, generating a reification.
1 parent 1d98d69 commit 594306e

File tree

3 files changed

+38
-20
lines changed

3 files changed

+38
-20
lines changed

lib/json/ld/expand.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,8 @@ def expand(input, active_property, context,
191191
return output_object['@set'] if output_object.key?('@set')
192192
elsif triple_term?(output_object)
193193
keys = output_object.keys
194-
unless (keys - %w(@triple)).empty?
195-
# The result must not contain any keys other than @triple. Otherwise, an invalid triplt term error has been detected and processing is aborted.
194+
unless (keys - %w(@triple @annotation)).empty?
195+
# The result must not contain any keys other than @triple or @annotation. Otherwise, an invalid triple term error has been detected and processing is aborted.
196196
raise JsonLdError::InvalidTripleTerm,
197197
"triple term has unknown keys: #{output_object.inspect}"
198198
end
@@ -836,8 +836,8 @@ def expand_object(input, active_property, context, output_object,
836836
end
837837
end
838838

839-
# If result includes @triple, it MUST NOT include any other properties
840-
if output_object.key?('@triple') && output_object.keys.length != 1
839+
# If result includes @triple, it MUST NOT include any properties other than @annotation
840+
if output_object.key?('@triple') && !(output_object.keys - %w(@triple @annotation)).empty?
841841
raise JsonLdError::InvalidTripleTerm,
842842
"Triple Term includes extra properties: #{output_object.keys}"
843843
end

lib/json/ld/flatten.rb

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,12 @@ def create_node_map(element, graph_map,
6060
# note: active_subject will not be nil.
6161
if annotation = element.delete('@annotation')
6262
# rdfstar being true is implicit, as it is checked in expansion
63-
as = if node_reference?(active_subject)
64-
active_subject['@id']
65-
else
66-
active_subject
67-
end
68-
69-
reification = {'@id' => as, active_property => [element]}
63+
reification = {'@id' => active_subject, active_property => [element]}
7064

7165
# Note that annotation is an array, make the reified subject the id of each member of that array.
7266
annotation.each do |a|
73-
# XXX may be zero or more reifiers; use bnode for now.
74-
reifier = namer.get_name
67+
# Use an provided reifier before allocating a fresh blank node
68+
reifier = a.fetch('@id', namer.get_name)
7569
a = a.merge('@id' => reifier, '@reifies' => reification)
7670

7771
# Invoke recursively using annotation.
@@ -97,13 +91,28 @@ def create_node_map(element, graph_map,
9791
list['@list'] << result
9892
end
9993
elsif triple_term?(element)
100-
# Add just the @triple member from element as the value of the property in the subject node.
101-
# FIXME: if a triple term can have other properties, the triple term would need to be its own entry in the node mode.
102-
add_value(subject_node, active_property, element.dup.delete_if {|k,v| k != '@triple'}, allow_duplicate: false)
103-
if element.keys.length != 1
94+
unless (element.keys - %w(@triple @annotation)).empty?
10495
raise "Expected triple term to not have other properties, got #{element.inspect}"
10596
end
106-
else
97+
98+
if annotation = element.delete('@annotation')
99+
# rdfstar being true is implicit, as it is checked in expansion
100+
reification = {'@id' => active_subject, active_property => [element]}
101+
102+
# Note that annotation is an array, make the reified subject the id of each member of that array.
103+
annotation.each do |a|
104+
# Use an provided reifier before allocating a fresh blank node
105+
reifier = a.fetch('@id', namer.get_name)
106+
a = a.merge('@id' => reifier, '@reifies' => reification)
107+
108+
# Invoke recursively using annotation.
109+
create_node_map(a, graph_map, active_graph: active_graph, active_subject: reifier)
110+
end
111+
end
112+
113+
# Add just the @triple member from element as the value of the property in the subject node.
114+
add_value(subject_node, active_property, element.dup.delete_if {|k,v| k != '@triple'}, allow_duplicate: false)
115+
else
107116
# Element is a node object
108117
id = element.delete('@id')
109118
id = namer.get_name(id) if blank_node?(id)
@@ -127,7 +136,7 @@ def create_node_map(element, graph_map,
127136
if annotation = element.delete('@annotation')
128137
# rdfstar being true is implicit, as it is checked in expansion
129138
if node_reference?(active_subject)
130-
# If this is a node reference, then we're processing a revers relationship
139+
# If this is a node reference, then we're processing a reverse relationship
131140
as = active_subject['@id']
132141
reification = {'@id' => node['@id'], active_property => [{ '@id' => as }]}
133142
else

spec/expand_spec.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3871,7 +3871,16 @@
38713871
"@annotation": {"ex:certainty": 0.8}
38723872
}
38733873
}),
3874-
exception: JSON::LD::JsonLdError::InvalidTripleTerm
3874+
output: %([{
3875+
"@id": "ex:subj",
3876+
"ex:value": [{
3877+
"@triple": {
3878+
"@id": "ex:rei",
3879+
"ex:prop": [{"@value": "value"}]
3880+
},
3881+
"@annotation": [{"ex:certainty": [{"@value": 0.8}]}]
3882+
}]
3883+
}])
38753884
},
38763885
'triple term with reverse relationship': {
38773886
input: %({

0 commit comments

Comments
 (0)