Skip to content

Commit be7a179

Browse files
committed
Separate RDF::Literal handling from Context#expand_value directly into FromRDF#resource_representation.
1 parent 85174af commit be7a179

File tree

3 files changed

+43
-58
lines changed

3 files changed

+43
-58
lines changed

lib/json/ld/context.rb

Lines changed: 3 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1467,8 +1467,6 @@ def compact_iri(iri, base: nil, reverse: false, value: nil, vocab: nil)
14671467
end
14681468
end
14691469

1470-
RDF_LITERAL_NATIVE_TYPES = Set.new([RDF::XSD.boolean, RDF::XSD.integer, RDF::XSD.double]).freeze
1471-
14721470
##
14731471
# If active property has a type mapping in the active context set to @id or @vocab, a JSON object with a single member @id whose value is the result of using the IRI Expansion algorithm on value is returned.
14741472
#
@@ -1500,50 +1498,12 @@ def expand_value(property, value, useNativeTypes: false, rdfDirection: nil, base
15001498
return {'@id' => expand_iri(value, vocab: true, documentRelative: true, base: base).to_s}
15011499
end
15021500

1503-
value = RDF::Literal(value) if
1504-
value.is_a?(Date) ||
1505-
value.is_a?(DateTime) ||
1506-
value.is_a?(Time)
1507-
15081501
result = case value
15091502
when RDF::URI, RDF::Node
15101503
{'@id' => value.to_s}
1511-
when RDF::Literal
1512-
res = {}
1513-
if value.datatype == RDF::URI(RDF.to_uri + "JSON") && processingMode('json-ld-1.1')
1514-
# Value parsed as JSON
1515-
# FIXME: MultiJson
1516-
res['@type'] = '@json'
1517-
res['@value'] = ::JSON.parse(value.object)
1518-
elsif value.datatype.start_with?("https://www.w3.org/ns/i18n#") && rdfDirection == 'i18n-datatype' && processingMode('json-ld-1.1')
1519-
lang, dir = value.datatype.fragment.split('_')
1520-
res['@value'] = value.to_s
1521-
unless lang.empty?
1522-
if lang !~ /^[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*$/
1523-
if options[:validate]
1524-
raise JsonLdError::InvalidLanguageMapping, "rdf:language must be valid BCP47: #{lang.inspect}"
1525-
else
1526-
warn "rdf:language must be valid BCP47: #{lang.inspect}"
1527-
end
1528-
end
1529-
res['@language'] = lang
1530-
end
1531-
res['@direction'] = dir
1532-
elsif useNativeTypes && RDF_LITERAL_NATIVE_TYPES.include?(value.datatype) && value.valid?
1533-
res['@type'] = uri(coerce(property)) if coerce(property)
1534-
res['@value'] = value.object
1535-
else
1536-
value.canonicalize! if value.valid? && value.datatype == RDF::XSD.double
1537-
if coerce(property)
1538-
res['@type'] = uri(coerce(property)).to_s
1539-
elsif value.datatype?
1540-
res['@type'] = uri(value.datatype).to_s
1541-
elsif value.language? || language(property)
1542-
res['@language'] = (value.language || language(property)).to_s
1543-
end
1544-
res['@value'] = value.to_s
1545-
end
1546-
res
1504+
when Date, DateTime, Time
1505+
lit = RDF::Literal.new(value)
1506+
{'@value' => lit.to_s, '@type' => lit.datatype.to_s}
15471507
else
15481508
# Otherwise, initialize result to a JSON object with an @value member whose value is set to value.
15491509
res = {}
@@ -1561,8 +1521,6 @@ def expand_value(property, value, useNativeTypes: false, rdfDirection: nil, base
15611521
end
15621522

15631523
result
1564-
rescue ::JSON::ParserError => e
1565-
raise JSON::LD::JsonLdError::InvalidJsonLiteral, e.message
15661524
end
15671525

15681526
##

lib/json/ld/from_rdf.rb

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ def from_statements(dataset, useRdfType: false, useNativeTypes: false)
168168
end
169169

170170
private
171+
172+
RDF_LITERAL_NATIVE_TYPES = Set.new([RDF::XSD.boolean, RDF::XSD.integer, RDF::XSD.double]).freeze
173+
171174
def resource_representation(resource, useNativeTypes)
172175
case resource
173176
when RDF::Statement
@@ -183,11 +186,43 @@ def resource_representation(resource, useNativeTypes)
183186
end
184187
rep
185188
when RDF::Literal
186-
@context.expand_value(nil,
187-
resource,
188-
rdfDirection: @options[:rdfDirection],
189-
useNativeTypes: useNativeTypes,
190-
base: @options[:base])
189+
base = @options[:base]
190+
rdfDirection = @options[:rdfDirection]
191+
res = {}
192+
193+
if resource.datatype == RDF::URI(RDF.to_uri + "JSON") && @context.processingMode('json-ld-1.1')
194+
res['@type'] = '@json'
195+
res['@value'] = begin
196+
::JSON.parse(resource.object)
197+
rescue ::JSON::ParserError => e
198+
raise JSON::LD::JsonLdError::InvalidJsonLiteral, e.message
199+
end
200+
elsif resource.datatype.start_with?("https://www.w3.org/ns/i18n#") && rdfDirection == 'i18n-datatype' && @context.processingMode('json-ld-1.1')
201+
lang, dir = resource.datatype.fragment.split('_')
202+
res['@value'] = resource.to_s
203+
unless lang.empty?
204+
if lang !~ /^[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*$/
205+
if options[:validate]
206+
raise JsonLdError::InvalidLanguageMapping, "rdf:language must be valid BCP47: #{lang.inspect}"
207+
else
208+
warn "rdf:language must be valid BCP47: #{lang.inspect}"
209+
end
210+
end
211+
res['@language'] = lang
212+
end
213+
res['@direction'] = dir
214+
elsif useNativeTypes && RDF_LITERAL_NATIVE_TYPES.include?(resource.datatype) && resource.valid?
215+
res['@value'] = resource.object
216+
else
217+
resource.canonicalize! if resource.valid? && resource.datatype == RDF::XSD.double
218+
if resource.datatype?
219+
res['@type'] = resource.datatype.to_s
220+
elsif resource.language?
221+
res['@language'] = resource.language.to_s
222+
end
223+
res['@value'] = resource.to_s
224+
end
225+
res
191226
else
192227
{'@id' => resource.to_s}
193228
end

spec/context_spec.rb

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1553,14 +1553,6 @@ def containers
15531553
"native double" => ["foo", 1.1e1, {"@value" => 1.1E1}],
15541554
"native date" => ["foo", Date.parse("2011-12-27"), {"@value" => "2011-12-27", "@type" => RDF::XSD.date.to_s}],
15551555
"native dateTime" =>["foo", DateTime.parse("2011-12-27T10:11:12Z"), {"@value" => "2011-12-27T10:11:12Z", "@type" => RDF::XSD.dateTime.to_s}],
1556-
"rdf boolean" => ["foo", RDF::Literal(true), {"@value" => "true", "@type" => RDF::XSD.boolean.to_s}],
1557-
"rdf integer" => ["foo", RDF::Literal(1), {"@value" => "1", "@type" => RDF::XSD.integer.to_s}],
1558-
"rdf decimal" => ["foo", RDF::Literal::Decimal.new(1.1), {"@value" => "1.1", "@type" => RDF::XSD.decimal.to_s}],
1559-
"rdf double" => ["foo", RDF::Literal::Double.new(1.1), {"@value" => "1.1E0", "@type" => RDF::XSD.double.to_s}],
1560-
"rdf URI" => ["foo", RDF::URI("foo"), {"@id" => "foo"}],
1561-
"rdf date " => ["foo", RDF::Literal(Date.parse("2011-12-27")), {"@value" => "2011-12-27", "@type" => RDF::XSD.date.to_s}],
1562-
"rdf nonNeg" => ["foo", RDF::Literal::NonNegativeInteger.new(1), {"@value" => "1", "@type" => RDF::XSD.nonNegativeInteger}],
1563-
"rdf float" => ["foo", RDF::Literal::Float.new(1.0), {"@value" => "1.0", "@type" => RDF::XSD.float}],
15641556
"ex:none string" => ["ex:none", "foo", {"@value" => "foo"}],
15651557
"ex:none boolean" =>["ex:none", true, {"@value" => true}],
15661558
"ex:none integer" =>["ex:none", 1, {"@value" => 1}],

0 commit comments

Comments
 (0)