rdf 0.2.0.1 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CONTRIBUTORS +1 -0
- data/README +1 -0
- data/VERSION +1 -1
- data/lib/rdf.rb +10 -1
- data/lib/rdf/model/literal.rb +134 -60
- data/lib/rdf/model/literal/boolean.rb +63 -0
- data/lib/rdf/model/literal/date.rb +43 -0
- data/lib/rdf/model/literal/datetime.rb +43 -0
- data/lib/rdf/model/literal/decimal.rb +90 -0
- data/lib/rdf/model/literal/double.rb +92 -0
- data/lib/rdf/model/literal/integer.rb +76 -0
- data/lib/rdf/model/literal/time.rb +55 -0
- data/lib/rdf/model/literal/xml.rb +39 -0
- data/lib/rdf/model/node.rb +1 -1
- data/lib/rdf/model/value.rb +1 -1
- data/lib/rdf/ntriples.rb +16 -0
- data/lib/rdf/query/solution.rb +1 -1
- data/lib/rdf/reader.rb +1 -1
- data/lib/rdf/repository.rb +2 -2
- data/lib/rdf/util/cache.rb +3 -3
- data/lib/rdf/version.rb +2 -2
- metadata +14 -7
data/CONTRIBUTORS
CHANGED
data/README
CHANGED
@@ -189,6 +189,7 @@ Authors
|
|
189
189
|
Contributors
|
190
190
|
------------
|
191
191
|
|
192
|
+
* [Gregg Kellogg](mailto:gregg@kellogg-assoc.com) - <http://kellogg-assoc.com/>
|
192
193
|
* [Hellekin O. Wolf](mailto:hellekin@cepheide.org) - <http://hellekin.cepheide.org/>
|
193
194
|
* [John Fieber](mailto:jrf@ursamaris.org) - <http://github.com/jfieber>
|
194
195
|
* [Pius Uzamere](mailto:pius@alum.mit.edu) - <http://pius.me/>
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.1
|
data/lib/rdf.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
require 'enumerator'
|
2
2
|
require 'open-uri'
|
3
|
+
require 'bigdecimal'
|
4
|
+
require 'date'
|
5
|
+
require 'time'
|
3
6
|
|
4
7
|
if RUBY_VERSION < '1.8.7'
|
5
8
|
# @see http://rubygems.org/gems/backports
|
@@ -92,7 +95,13 @@ module RDF
|
|
92
95
|
#
|
93
96
|
# @return [RDF::URI]
|
94
97
|
def self.URI(*args, &block)
|
95
|
-
|
98
|
+
case uri = args.first
|
99
|
+
when RDF::URI then uri
|
100
|
+
else case
|
101
|
+
when uri.respond_to?(:to_uri) then uri.to_uri
|
102
|
+
else URI.new(*args, &block)
|
103
|
+
end
|
104
|
+
end
|
96
105
|
end
|
97
106
|
|
98
107
|
##
|
data/lib/rdf/model/literal.rb
CHANGED
@@ -39,10 +39,67 @@ module RDF
|
|
39
39
|
# @see http://www.w3.org/TR/rdf-concepts/#section-Literals
|
40
40
|
# @see http://www.w3.org/TR/rdf-concepts/#section-Datatypes-intro
|
41
41
|
class Literal
|
42
|
+
autoload :Boolean, 'rdf/model/literal/boolean'
|
43
|
+
autoload :Integer, 'rdf/model/literal/integer'
|
44
|
+
autoload :Double, 'rdf/model/literal/double'
|
45
|
+
autoload :Decimal, 'rdf/model/literal/decimal'
|
46
|
+
autoload :Date, 'rdf/model/literal/date'
|
47
|
+
autoload :DateTime, 'rdf/model/literal/datetime'
|
48
|
+
autoload :Time, 'rdf/model/literal/time'
|
49
|
+
autoload :XML, 'rdf/model/literal/xml'
|
50
|
+
|
42
51
|
include RDF::Value
|
43
52
|
|
44
|
-
|
45
|
-
|
53
|
+
##
|
54
|
+
# @private
|
55
|
+
def self.new(value, options = {})
|
56
|
+
klass = case
|
57
|
+
when !self.equal?(RDF::Literal)
|
58
|
+
self # subclasses can be directly constructed without type dispatch
|
59
|
+
when datatype = options[:datatype]
|
60
|
+
case RDF::URI(datatype)
|
61
|
+
when XSD.boolean
|
62
|
+
RDF::Literal::Boolean
|
63
|
+
when XSD.integer, XSD.long, XSD.int, XSD.short, XSD.byte
|
64
|
+
RDF::Literal::Integer
|
65
|
+
when XSD.double, XSD.float
|
66
|
+
RDF::Literal::Double
|
67
|
+
when XSD.decimal
|
68
|
+
RDF::Literal::Decimal
|
69
|
+
when XSD.date
|
70
|
+
RDF::Literal::Date
|
71
|
+
when XSD.dateTime
|
72
|
+
RDF::Literal::DateTime
|
73
|
+
when XSD.time
|
74
|
+
RDF::Literal::Time
|
75
|
+
when XSD.nonPositiveInteger, XSD.negativeInteger
|
76
|
+
RDF::Literal::Integer
|
77
|
+
when XSD.nonNegativeInteger, XSD.positiveInteger
|
78
|
+
RDF::Literal::Integer
|
79
|
+
when XSD.unsignedLong, XSD.unsignedInt, XSD.unsignedShort, XSD.unsignedByte
|
80
|
+
RDF::Literal::Integer
|
81
|
+
when RDF.XMLLiteral
|
82
|
+
RDF::Literal::XML
|
83
|
+
else self
|
84
|
+
end
|
85
|
+
else case value
|
86
|
+
when ::TrueClass then RDF::Literal::Boolean
|
87
|
+
when ::FalseClass then RDF::Literal::Boolean
|
88
|
+
when ::Integer then RDF::Literal::Integer
|
89
|
+
when ::Float then RDF::Literal::Double
|
90
|
+
when ::BigDecimal then RDF::Literal::Decimal
|
91
|
+
when ::DateTime then RDF::Literal::DateTime
|
92
|
+
when ::Date then RDF::Literal::Date
|
93
|
+
when ::Time then RDF::Literal::Time
|
94
|
+
else self
|
95
|
+
end
|
96
|
+
end
|
97
|
+
literal = klass.allocate
|
98
|
+
literal.send(:initialize, value, options)
|
99
|
+
literal.validate if options[:validate]
|
100
|
+
literal.canonicalize if options[:canonicalize]
|
101
|
+
literal
|
102
|
+
end
|
46
103
|
|
47
104
|
# @return [Symbol] The language tag (optional).
|
48
105
|
attr_accessor :language
|
@@ -51,77 +108,44 @@ module RDF
|
|
51
108
|
attr_accessor :datatype
|
52
109
|
|
53
110
|
##
|
54
|
-
# @param [Object]
|
111
|
+
# @param [Object] value
|
55
112
|
# @option options [Symbol] :language (nil)
|
56
113
|
# @option options [URI] :datatype (nil)
|
57
114
|
def initialize(value, options = {})
|
58
|
-
@
|
59
|
-
@
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
else
|
64
|
-
@datatype = case value
|
65
|
-
when String then nil # implicit XSD.string
|
66
|
-
when TrueClass then XSD.boolean
|
67
|
-
when FalseClass then XSD.boolean
|
68
|
-
when Fixnum then XSD.integer
|
69
|
-
when Integer then XSD.integer
|
70
|
-
when Float
|
71
|
-
@value = case
|
72
|
-
when value.nan? then 'NaN'
|
73
|
-
when value.infinite? then value.to_s[0...-'inity'.length].upcase
|
74
|
-
else value.to_f
|
75
|
-
end
|
76
|
-
XSD.double
|
77
|
-
when Time, Date, DateTime
|
78
|
-
require 'time'
|
79
|
-
@value = value.respond_to?(:xmlschema) ? value.xmlschema : value.to_s
|
80
|
-
case value
|
81
|
-
when DateTime then XSD.dateTime
|
82
|
-
when Date then XSD.date
|
83
|
-
when Time then XSD.dateTime
|
84
|
-
end
|
85
|
-
else
|
86
|
-
require 'bigdecimal' unless defined?(BigDecimal)
|
87
|
-
case value
|
88
|
-
when BigDecimal
|
89
|
-
case
|
90
|
-
when value.nan? then 'NaN'
|
91
|
-
when value.infinite? then value.to_s[0...-'inity'.length].upcase
|
92
|
-
when value.finite? then value.to_s('F')
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
115
|
+
@object = value
|
116
|
+
@string = options[:lexical] if options.has_key?(:lexical)
|
117
|
+
@language = options[:language].to_s.to_sym if options[:language]
|
118
|
+
@datatype = RDF::URI(options[:datatype]) if options[:datatype]
|
119
|
+
end
|
97
120
|
|
98
|
-
|
121
|
+
##
|
122
|
+
# Returns the value as a string.
|
123
|
+
#
|
124
|
+
# @return [String]
|
125
|
+
def value
|
126
|
+
@string || to_s
|
99
127
|
end
|
100
128
|
|
101
129
|
##
|
102
130
|
# @return [Object]
|
103
131
|
def object
|
104
|
-
case datatype
|
132
|
+
@object || case datatype
|
105
133
|
when XSD.string, nil
|
106
134
|
value
|
107
135
|
when XSD.boolean
|
108
136
|
%w(true 1).include?(value)
|
109
|
-
when XSD.double, XSD.float
|
110
|
-
value.to_f
|
111
137
|
when XSD.integer, XSD.long, XSD.int, XSD.short, XSD.byte
|
112
138
|
value.to_i
|
139
|
+
when XSD.double, XSD.float
|
140
|
+
value.to_f
|
113
141
|
when XSD.decimal
|
114
|
-
|
115
|
-
BigDecimal.new(value)
|
142
|
+
::BigDecimal.new(value)
|
116
143
|
when XSD.date
|
117
|
-
|
118
|
-
Date.parse(value)
|
144
|
+
::Date.parse(value)
|
119
145
|
when XSD.dateTime
|
120
|
-
|
121
|
-
DateTime.parse(value)
|
146
|
+
::DateTime.parse(value)
|
122
147
|
when XSD.time
|
123
|
-
|
124
|
-
Time.parse(value)
|
148
|
+
::Time.parse(value)
|
125
149
|
when XSD.nonPositiveInteger, XSD.negativeInteger
|
126
150
|
value.to_i
|
127
151
|
when XSD.nonNegativeInteger, XSD.positiveInteger
|
@@ -203,15 +227,65 @@ module RDF
|
|
203
227
|
alias_method :datatyped?, :has_datatype?
|
204
228
|
|
205
229
|
##
|
206
|
-
# Returns
|
230
|
+
# Returns `true` if the value adheres to the defined grammar of the
|
231
|
+
# datatype.
|
232
|
+
#
|
233
|
+
# @return [Boolean]
|
234
|
+
# @since 0.2.1
|
235
|
+
def valid?
|
236
|
+
grammar = self.class.const_get(:GRAMMAR) rescue nil
|
237
|
+
grammar.nil? || !!(value =~ grammar)
|
238
|
+
end
|
239
|
+
|
240
|
+
##
|
241
|
+
# Returns `true` if the value does not adhere to the defined grammar of
|
242
|
+
# the datatype.
|
243
|
+
#
|
244
|
+
# @return [Boolean]
|
245
|
+
# @since 0.2.1
|
246
|
+
def invalid?
|
247
|
+
!valid?
|
248
|
+
end
|
249
|
+
|
250
|
+
##
|
251
|
+
# Validates the value using {#valid?}, raising an error if the value is
|
252
|
+
# invalid.
|
253
|
+
#
|
254
|
+
# @raise [ArgumentError] if the value is invalid
|
255
|
+
# @return [Literal]
|
256
|
+
# @since 0.2.1
|
257
|
+
def validate
|
258
|
+
raise ArgumentError.new("#{to_s.inspect} is not a valid <#{datatype.to_s}> literal") if invalid?
|
259
|
+
self
|
260
|
+
end
|
261
|
+
alias_method :validate!, :validate
|
262
|
+
|
263
|
+
##
|
264
|
+
# Converts the literal into its canonical lexical representation.
|
265
|
+
#
|
266
|
+
# Subclasses should override this as needed and appropriate.
|
267
|
+
#
|
268
|
+
# @return [Literal]
|
269
|
+
# @since 0.2.1
|
270
|
+
def canonicalize
|
271
|
+
@language = @language.to_s.downcase.to_sym if @language
|
272
|
+
self
|
273
|
+
end
|
274
|
+
|
275
|
+
##
|
276
|
+
# Returns the value as a string.
|
207
277
|
#
|
208
278
|
# @return [String]
|
209
279
|
def to_s
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
280
|
+
@object.to_s
|
281
|
+
end
|
282
|
+
|
283
|
+
##
|
284
|
+
# Returns a developer-friendly representation of `self`.
|
285
|
+
#
|
286
|
+
# @return [String]
|
287
|
+
def inspect
|
288
|
+
sprintf("#<%s:%#0x(%s)>", self.class.name, __id__, RDF::NTriples.serialize(self))
|
215
289
|
end
|
216
290
|
end
|
217
291
|
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module RDF; class Literal
|
2
|
+
##
|
3
|
+
# A boolean literal.
|
4
|
+
#
|
5
|
+
# @see http://www.w3.org/TR/xmlschema-2/#boolean
|
6
|
+
# @since 0.2.1
|
7
|
+
class Boolean < Literal
|
8
|
+
DATATYPE = XSD.boolean
|
9
|
+
GRAMMAR = /^(true|false|1|0)$/i.freeze
|
10
|
+
TRUES = %w(true 1).freeze
|
11
|
+
FALSES = %w(false 0).freeze
|
12
|
+
|
13
|
+
##
|
14
|
+
# @param [Boolean] value
|
15
|
+
# @option options [String] :lexical (nil)
|
16
|
+
def initialize(value, options = {})
|
17
|
+
@datatype = options[:datatype] || DATATYPE
|
18
|
+
@string = options[:lexical] if options.has_key?(:lexical)
|
19
|
+
@string = value if !defined?(@string) && value.is_a?(String)
|
20
|
+
@object = case
|
21
|
+
when true.equal?(value) then true
|
22
|
+
when false.equal?(value) then false
|
23
|
+
when TRUES.include?(value.to_s.downcase) then true
|
24
|
+
when FALSES.include?(value.to_s.downcase) then false
|
25
|
+
else value
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# Converts the literal into its canonical lexical representation.
|
31
|
+
#
|
32
|
+
# @return [Literal]
|
33
|
+
# @see http://www.w3.org/TR/xmlschema-2/#boolean
|
34
|
+
def canonicalize
|
35
|
+
@string = (@object ? :true : :false).to_s
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# Returns the value as a string.
|
41
|
+
#
|
42
|
+
# @return [String]
|
43
|
+
def to_s
|
44
|
+
@string || @object.to_s
|
45
|
+
end
|
46
|
+
|
47
|
+
##
|
48
|
+
# Returns `true` if this value is `true`.
|
49
|
+
#
|
50
|
+
# @return [Boolean]
|
51
|
+
def true?
|
52
|
+
@object.equal?(true)
|
53
|
+
end
|
54
|
+
|
55
|
+
##
|
56
|
+
# Returns `true` if this value is `false`.
|
57
|
+
#
|
58
|
+
# @return [Boolean]
|
59
|
+
def false?
|
60
|
+
@object.equal?(false)
|
61
|
+
end
|
62
|
+
end # class Boolean
|
63
|
+
end; end # class RDF::Literal
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module RDF; class Literal
|
2
|
+
##
|
3
|
+
# A date literal.
|
4
|
+
#
|
5
|
+
# @see http://www.w3.org/TR/xmlschema-2/#date
|
6
|
+
# @since 0.2.1
|
7
|
+
class Date < Literal
|
8
|
+
DATATYPE = XSD.date
|
9
|
+
GRAMMAR = %r(\A-?\d{4}-\d{2}-\d{2}(([\+\-]\d{2}:\d{2})|UTC|Z)?\Z).freeze
|
10
|
+
|
11
|
+
##
|
12
|
+
# @param [Date] value
|
13
|
+
# @option options [String] :lexical (nil)
|
14
|
+
def initialize(value, options = {})
|
15
|
+
@datatype = options[:datatype] || DATATYPE
|
16
|
+
@string = options[:lexical] if options.has_key?(:lexical)
|
17
|
+
@string = value if !defined?(@string) && value.is_a?(String)
|
18
|
+
@object = case
|
19
|
+
when value.is_a?(::Date) then value
|
20
|
+
when value.respond_to?(:to_date) then value.to_date # Ruby 1.9+
|
21
|
+
else ::Date.parse(value.to_s)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Converts the literal into its canonical lexical representation.
|
27
|
+
#
|
28
|
+
# @return [Literal]
|
29
|
+
# @see http://www.w3.org/TR/xmlschema-2/#date
|
30
|
+
def canonicalize
|
31
|
+
@string = @object.strftime('%Y-%m-%d%Z').sub(/\+00:00|UTC/, 'Z')
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# Returns the value as a string.
|
37
|
+
#
|
38
|
+
# @return [String]
|
39
|
+
def to_s
|
40
|
+
@string || @object.strftime('%Y-%m-%d%Z').sub(/\+00:00|UTC/, 'Z')
|
41
|
+
end
|
42
|
+
end # class Date
|
43
|
+
end; end # class RDF::Literal
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module RDF; class Literal
|
2
|
+
##
|
3
|
+
# A date/time literal.
|
4
|
+
#
|
5
|
+
# @see http://www.w3.org/TR/xmlschema-2/#dateTime
|
6
|
+
# @since 0.2.1
|
7
|
+
class DateTime < Literal
|
8
|
+
DATATYPE = XSD.dateTime
|
9
|
+
GRAMMAR = %r(\A-?\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(([\+\-]\d{2}:\d{2})|UTC|Z)?\Z).freeze
|
10
|
+
|
11
|
+
##
|
12
|
+
# @param [DateTime] value
|
13
|
+
# @option options [String] :lexical (nil)
|
14
|
+
def initialize(value, options = {})
|
15
|
+
@datatype = options[:datatype] || DATATYPE
|
16
|
+
@string = options[:lexical] if options.has_key?(:lexical)
|
17
|
+
@string = value if !defined?(@string) && value.is_a?(String)
|
18
|
+
@object = case
|
19
|
+
when value.is_a?(::DateTime) then value
|
20
|
+
when value.respond_to?(:to_datetime) then value.to_datetime # Ruby 1.9+
|
21
|
+
else ::DateTime.parse(value.to_s)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Converts the literal into its canonical lexical representation.
|
27
|
+
#
|
28
|
+
# @return [Literal]
|
29
|
+
# @see http://www.w3.org/TR/xmlschema-2/#dateTime
|
30
|
+
def canonicalize
|
31
|
+
@string = @object.strftime('%Y-%m-%dT%H:%M:%S%Z').sub(/\+00:00|UTC/, 'Z')
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# Returns the value as a string.
|
37
|
+
#
|
38
|
+
# @return [String]
|
39
|
+
def to_s
|
40
|
+
@string || @object.strftime('%Y-%m-%dT%H:%M:%S%Z').sub(/\+00:00|UTC/, 'Z')
|
41
|
+
end
|
42
|
+
end # class DateTime
|
43
|
+
end; end # class RDF::Literal
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module RDF; class Literal
|
2
|
+
##
|
3
|
+
# A decimal literal.
|
4
|
+
#
|
5
|
+
# @see http://www.w3.org/TR/xmlschema-2/#decimal
|
6
|
+
# @since 0.2.1
|
7
|
+
class Decimal < Literal
|
8
|
+
DATATYPE = XSD.decimal
|
9
|
+
GRAMMAR = /^[\+\-]?\d+(\.\d*)?$/.freeze
|
10
|
+
|
11
|
+
##
|
12
|
+
# @param [BigDecimal] value
|
13
|
+
# @option options [String] :lexical (nil)
|
14
|
+
def initialize(value, options = {})
|
15
|
+
@datatype = options[:datatype] || DATATYPE
|
16
|
+
@string = options[:lexical] if options.has_key?(:lexical)
|
17
|
+
@string = value if !defined?(@string) && value.is_a?(String)
|
18
|
+
@object = case
|
19
|
+
when value.is_a?(BigDecimal) then value
|
20
|
+
else BigDecimal(value.to_s)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
##
|
25
|
+
# Converts the literal into its canonical lexical representation.
|
26
|
+
#
|
27
|
+
# @return [Literal]
|
28
|
+
# @see http://www.w3.org/TR/xmlschema-2/#decimal
|
29
|
+
def canonicalize
|
30
|
+
# Can't use simple %f transformation due to special requirements from
|
31
|
+
# N3 tests in representation
|
32
|
+
@string = begin
|
33
|
+
i, f = @object.to_s('F').split('.')
|
34
|
+
i.sub!(/^\+?0+(\d)$/, '\1') # remove the optional leading '+' sign and any extra leading zeroes
|
35
|
+
f = f[0, 16] # truncate the fractional part after 15 decimal places
|
36
|
+
f.sub!(/0*$/, '') # remove any trailing zeroes
|
37
|
+
f = '0' if f.empty? # ...but there must be a digit to the right of the decimal point
|
38
|
+
"#{i}.#{f}"
|
39
|
+
end
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
# Returns the value as a string.
|
45
|
+
#
|
46
|
+
# @return [String]
|
47
|
+
# @see BigDecimal#to_s
|
48
|
+
def to_s
|
49
|
+
@string || @object.to_s('F')
|
50
|
+
end
|
51
|
+
|
52
|
+
##
|
53
|
+
# Returns the value as an integer.
|
54
|
+
#
|
55
|
+
# @return [Integer]
|
56
|
+
# @see BigDecimal#to_i
|
57
|
+
def to_i
|
58
|
+
@object.to_i
|
59
|
+
end
|
60
|
+
|
61
|
+
##
|
62
|
+
# Returns the value as a floating point number.
|
63
|
+
#
|
64
|
+
# The usual accuracy limits and errors of binary float arithmetic apply.
|
65
|
+
#
|
66
|
+
# @return [Float]
|
67
|
+
# @see BigDecimal#to_f
|
68
|
+
def to_f
|
69
|
+
@object.to_f
|
70
|
+
end
|
71
|
+
|
72
|
+
##
|
73
|
+
# Returns the value as a decimal number.
|
74
|
+
#
|
75
|
+
# @return [BigDecimal]
|
76
|
+
# @see BigDecimal#to_d
|
77
|
+
def to_d
|
78
|
+
@object.respond_to?(:to_d) ? @object.to_d : BigDecimal(@object.to_s)
|
79
|
+
end
|
80
|
+
|
81
|
+
##
|
82
|
+
# Returns the value as a rational number.
|
83
|
+
#
|
84
|
+
# @return [Rational]
|
85
|
+
# @see BigDecimal#to_r
|
86
|
+
def to_r
|
87
|
+
@object.to_r # only available on Ruby 1.9+
|
88
|
+
end
|
89
|
+
end # class Decimal
|
90
|
+
end; end # class RDF::Literal
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module RDF; class Literal
|
2
|
+
##
|
3
|
+
# An floating point number literal.
|
4
|
+
#
|
5
|
+
# @see http://www.w3.org/TR/xmlschema-2/#double
|
6
|
+
# @since 0.2.1
|
7
|
+
class Double < Literal
|
8
|
+
DATATYPE = XSD.double
|
9
|
+
GRAMMAR = /^[\+\-]?\d+(\.\d*([eE][\+\-]?\d+)?)?$/.freeze # FIXME: support 'INF', '-INF' and 'NaN'
|
10
|
+
|
11
|
+
##
|
12
|
+
# @param [Float, #to_f] value
|
13
|
+
# @option options [String] :lexical (nil)
|
14
|
+
def initialize(value, options = {})
|
15
|
+
@datatype = options[:datatype] || DATATYPE
|
16
|
+
@string = options[:lexical] if options.has_key?(:lexical)
|
17
|
+
@string = value if !defined?(@string) && value.is_a?(String)
|
18
|
+
@object = case
|
19
|
+
when value.is_a?(::String) then Float(value) rescue nil
|
20
|
+
when value.is_a?(::Float) then value
|
21
|
+
when value.respond_to?(:to_f) then value.to_f
|
22
|
+
else Float(value.to_s) rescue nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
##
|
27
|
+
# Converts the literal into its canonical lexical representation.
|
28
|
+
#
|
29
|
+
# @return [Literal]
|
30
|
+
# @see http://www.w3.org/TR/xmlschema-2/#double
|
31
|
+
def canonicalize
|
32
|
+
# Can't use simple %f transformation due to special requirements from
|
33
|
+
# N3 tests in representation
|
34
|
+
@string = case
|
35
|
+
when @object.nan? then 'NaN'
|
36
|
+
when @object.infinite? then @object.to_s[0...-'inity'.length].upcase
|
37
|
+
when @object.zero? then '0.0E0'
|
38
|
+
else
|
39
|
+
i, f, e = ('%.16E' % @object.to_f).split(/[\.E]/)
|
40
|
+
f.sub!(/0*$/, '') # remove any trailing zeroes
|
41
|
+
f = '0' if f.empty? # ...but there must be a digit to the right of the decimal point
|
42
|
+
e.sub!(/^\+?0+(\d)$/, '\1') # remove the optional leading '+' sign and any extra leading zeroes
|
43
|
+
"#{i}.#{f}E#{e}"
|
44
|
+
end unless @object.nil?
|
45
|
+
self
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Returns the value as a string.
|
50
|
+
#
|
51
|
+
# @return [String]
|
52
|
+
def to_s
|
53
|
+
@string || case
|
54
|
+
when @object.nan? then 'NaN'
|
55
|
+
when @object.infinite? then @object.to_s[0...-'inity'.length].upcase
|
56
|
+
else @object.to_s
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# Returns the value as an integer.
|
62
|
+
#
|
63
|
+
# @return [Integer]
|
64
|
+
def to_i
|
65
|
+
@object.to_i
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# Returns the value as a floating point number.
|
70
|
+
#
|
71
|
+
# @return [Float]
|
72
|
+
def to_f
|
73
|
+
@object.to_f
|
74
|
+
end
|
75
|
+
|
76
|
+
##
|
77
|
+
# Returns the value as a decimal number.
|
78
|
+
#
|
79
|
+
# @return [BigDecimal]
|
80
|
+
def to_d
|
81
|
+
@object.respond_to?(:to_d) ? @object.to_d : BigDecimal(@object.to_s)
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
# Returns the value as a rational number.
|
86
|
+
#
|
87
|
+
# @return [Rational]
|
88
|
+
def to_r
|
89
|
+
@object.to_r # only available on Ruby 1.9+
|
90
|
+
end
|
91
|
+
end # class Double
|
92
|
+
end; end # class RDF::Literal
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module RDF; class Literal
|
2
|
+
##
|
3
|
+
# An integer literal.
|
4
|
+
#
|
5
|
+
# @see http://www.w3.org/TR/xmlschema-2/#integer
|
6
|
+
# @since 0.2.1
|
7
|
+
class Integer < Decimal
|
8
|
+
DATATYPE = XSD.integer
|
9
|
+
GRAMMAR = /^[\+\-]?\d+$/.freeze
|
10
|
+
|
11
|
+
##
|
12
|
+
# @param [Integer, #to_i] value
|
13
|
+
# @option options [String] :lexical (nil)
|
14
|
+
def initialize(value, options = {})
|
15
|
+
@datatype = options[:datatype] || DATATYPE
|
16
|
+
@string = options[:lexical] if options.has_key?(:lexical)
|
17
|
+
@string = value if !defined?(@string) && value.is_a?(String)
|
18
|
+
@object = case
|
19
|
+
when value.is_a?(::String) then Integer(value) rescue nil
|
20
|
+
when value.is_a?(::Integer) then value
|
21
|
+
when value.respond_to?(:to_i) then value.to_i
|
22
|
+
else Integer(value.to_s) rescue nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
##
|
27
|
+
# Converts the literal into its canonical lexical representation.
|
28
|
+
#
|
29
|
+
# @return [Literal]
|
30
|
+
# @see http://www.w3.org/TR/xmlschema-2/#integer
|
31
|
+
def canonicalize
|
32
|
+
@string = @object.to_s if @object
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
# Returns the value as a string.
|
38
|
+
#
|
39
|
+
# @return [String]
|
40
|
+
def to_s
|
41
|
+
@string || @object.to_s
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# Returns the value as an integer.
|
46
|
+
#
|
47
|
+
# @return [Integer]
|
48
|
+
def to_i
|
49
|
+
@object.to_i
|
50
|
+
end
|
51
|
+
|
52
|
+
##
|
53
|
+
# Returns the value as a floating point number.
|
54
|
+
#
|
55
|
+
# @return [Float]
|
56
|
+
def to_f
|
57
|
+
@object.to_f
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# Returns the value as a decimal number.
|
62
|
+
#
|
63
|
+
# @return [BigDecimal]
|
64
|
+
def to_d
|
65
|
+
@object.respond_to?(:to_d) ? @object.to_d : BigDecimal(@object.to_s)
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# Returns the value as a rational number.
|
70
|
+
#
|
71
|
+
# @return [Rational]
|
72
|
+
def to_r
|
73
|
+
@object.to_r
|
74
|
+
end
|
75
|
+
end # class Integer
|
76
|
+
end; end # class RDF::Literal
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module RDF; class Literal
|
2
|
+
##
|
3
|
+
# A time literal.
|
4
|
+
#
|
5
|
+
# The lexical representation for time is the left truncated lexical
|
6
|
+
# representation for `xsd:dateTime`: "hh:mm:ss.sss" with an optional
|
7
|
+
# following time zone indicator.
|
8
|
+
#
|
9
|
+
# @see http://www.w3.org/TR/xmlschema-2/#time
|
10
|
+
# @since 0.2.1
|
11
|
+
class Time < Literal
|
12
|
+
DATATYPE = XSD.time
|
13
|
+
GRAMMAR = %r(\A\d{2}:\d{2}:\d{2}(\.\d+)?(([\+\-]\d{2}:\d{2})|UTC|Z)?\Z).freeze
|
14
|
+
|
15
|
+
##
|
16
|
+
# @param [Time] value
|
17
|
+
# @option options [String] :lexical (nil)
|
18
|
+
def initialize(value, options = {})
|
19
|
+
@datatype = options[:datatype] || DATATYPE
|
20
|
+
@string = options[:lexical] if options.has_key?(:lexical)
|
21
|
+
@string = value if !defined?(@string) && value.is_a?(String)
|
22
|
+
@object = case
|
23
|
+
when value.is_a?(::Time) then value
|
24
|
+
when value.respond_to?(:to_time) then value.to_time # Ruby 1.9+
|
25
|
+
else ::Time.parse(value.to_s)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# Converts the literal into its canonical lexical representation.
|
31
|
+
#
|
32
|
+
# §3.2.8.2 Canonical representation
|
33
|
+
#
|
34
|
+
# The canonical representation for time is defined by prohibiting
|
35
|
+
# certain options from the Lexical representation (§3.2.8.1).
|
36
|
+
# Specifically, either the time zone must be omitted or, if present, the
|
37
|
+
# time zone must be Coordinated Universal Time (UTC) indicated by a "Z".
|
38
|
+
# Additionally, the canonical representation for midnight is 00:00:00.
|
39
|
+
#
|
40
|
+
# @return [Literal]
|
41
|
+
# @see http://www.w3.org/TR/xmlschema-2/#time
|
42
|
+
def canonicalize
|
43
|
+
@string = @object.strftime('%H:%M:%S%Z').sub(/\+00:00|UTC/, 'Z')
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
47
|
+
##
|
48
|
+
# Returns the value as a string.
|
49
|
+
#
|
50
|
+
# @return [String]
|
51
|
+
def to_s
|
52
|
+
@string || @object.strftime('%H:%M:%S%Z').sub(/\+00:00|UTC/, 'Z')
|
53
|
+
end
|
54
|
+
end # class Time
|
55
|
+
end; end # class RDF::Literal
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module RDF; class Literal
|
2
|
+
##
|
3
|
+
# An XML literal.
|
4
|
+
#
|
5
|
+
# @see http://www.w3.org/TR/rdf-concepts/#section-XMLLiteral
|
6
|
+
# @see http://www.w3.org/TR/rdfa-core/#s_xml_literals
|
7
|
+
# @since 0.2.1
|
8
|
+
class XML < Literal
|
9
|
+
DATATYPE = RDF.XMLLiteral
|
10
|
+
GRAMMAR = nil
|
11
|
+
|
12
|
+
##
|
13
|
+
# @param [Object] value
|
14
|
+
# @option options [String] :lexical (nil)
|
15
|
+
def initialize(value, options = {})
|
16
|
+
@datatype = options[:datatype] || DATATYPE
|
17
|
+
@string = options[:lexical] if options.has_key?(:lexical)
|
18
|
+
@object = value # TODO: parse XML string using REXML
|
19
|
+
end
|
20
|
+
|
21
|
+
##
|
22
|
+
# Converts the literal into its canonical lexical representation.
|
23
|
+
#
|
24
|
+
# @return [Literal]
|
25
|
+
# @see http://www.w3.org/TR/xml-exc-c14n/
|
26
|
+
def canonicalize
|
27
|
+
# TODO: implement XML canonicalization
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# Returns the value as a string.
|
33
|
+
#
|
34
|
+
# @return [String]
|
35
|
+
def to_s
|
36
|
+
@string || @object.to_s # TODO
|
37
|
+
end
|
38
|
+
end # class XML
|
39
|
+
end; end # class RDF::Literal
|
data/lib/rdf/model/node.rb
CHANGED
data/lib/rdf/model/value.rb
CHANGED
data/lib/rdf/ntriples.rb
CHANGED
@@ -63,4 +63,20 @@ module RDF
|
|
63
63
|
Writer.serialize(value)
|
64
64
|
end
|
65
65
|
end
|
66
|
+
|
67
|
+
##
|
68
|
+
# Extensions for `RDF::Value`.
|
69
|
+
module Value
|
70
|
+
##
|
71
|
+
# Returns the N-Triples representation of this value.
|
72
|
+
#
|
73
|
+
# This method is only available when the 'rdf/ntriples' serializer has
|
74
|
+
# been explicitly required.
|
75
|
+
#
|
76
|
+
# @return [String]
|
77
|
+
# @since 0.2.1
|
78
|
+
def to_ntriples
|
79
|
+
RDF::NTriples.serialize(self)
|
80
|
+
end
|
81
|
+
end
|
66
82
|
end
|
data/lib/rdf/query/solution.rb
CHANGED
data/lib/rdf/reader.rb
CHANGED
data/lib/rdf/repository.rb
CHANGED
@@ -116,7 +116,7 @@ module RDF
|
|
116
116
|
#
|
117
117
|
# @return [String]
|
118
118
|
def inspect
|
119
|
-
sprintf("#<%s:%#0x(%s)>", self.class.name,
|
119
|
+
sprintf("#<%s:%#0x(%s)>", self.class.name, __id__, uri.to_s)
|
120
120
|
end
|
121
121
|
|
122
122
|
##
|
@@ -135,7 +135,7 @@ module RDF
|
|
135
135
|
##
|
136
136
|
# @private
|
137
137
|
def self.extend_object(obj)
|
138
|
-
obj.instance_variable_set(:@data, {})
|
138
|
+
obj.instance_variable_set(:@data, obj.options.delete(:data) || {})
|
139
139
|
super
|
140
140
|
end
|
141
141
|
|
data/lib/rdf/util/cache.rb
CHANGED
@@ -83,8 +83,8 @@ module RDF; module Util
|
|
83
83
|
# @return [Object]
|
84
84
|
def []=(key, value)
|
85
85
|
if has_capacity?
|
86
|
-
@cache[key] = value.
|
87
|
-
@index[value.
|
86
|
+
@cache[key] = value.__id__
|
87
|
+
@index[value.__id__] = key
|
88
88
|
define_finalizer!(value)
|
89
89
|
end
|
90
90
|
value
|
@@ -121,7 +121,7 @@ module RDF; module Util
|
|
121
121
|
def []=(key, value)
|
122
122
|
if has_capacity?
|
123
123
|
@cache[key] = WeakRef.new(value)
|
124
|
-
@index[value.
|
124
|
+
@index[value.__id__] = key
|
125
125
|
define_finalizer!(value)
|
126
126
|
end
|
127
127
|
value
|
data/lib/rdf/version.rb
CHANGED
metadata
CHANGED
@@ -5,9 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 2
|
8
|
-
- 0
|
9
8
|
- 1
|
10
|
-
version: 0.2.
|
9
|
+
version: 0.2.1
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Arto Bendiken
|
@@ -16,7 +15,7 @@ autorequire:
|
|
16
15
|
bindir: bin
|
17
16
|
cert_chain: []
|
18
17
|
|
19
|
-
date: 2010-06-
|
18
|
+
date: 2010-06-28 00:00:00 +02:00
|
20
19
|
default_executable: rdf
|
21
20
|
dependencies:
|
22
21
|
- !ruby/object:Gem::Dependency
|
@@ -43,8 +42,8 @@ dependencies:
|
|
43
42
|
segments:
|
44
43
|
- 0
|
45
44
|
- 5
|
46
|
-
-
|
47
|
-
version: 0.5.
|
45
|
+
- 8
|
46
|
+
version: 0.5.8
|
48
47
|
type: :development
|
49
48
|
version_requirements: *id002
|
50
49
|
- !ruby/object:Gem::Dependency
|
@@ -71,8 +70,8 @@ dependencies:
|
|
71
70
|
segments:
|
72
71
|
- 0
|
73
72
|
- 2
|
74
|
-
-
|
75
|
-
version: 0.2.
|
73
|
+
- 1
|
74
|
+
version: 0.2.1
|
76
75
|
type: :development
|
77
76
|
version_requirements: *id004
|
78
77
|
description: RDF.rb is a pure-Ruby library for working with Resource Description Framework (RDF) data.
|
@@ -103,6 +102,14 @@ files:
|
|
103
102
|
- lib/rdf/mixin/readable.rb
|
104
103
|
- lib/rdf/mixin/writable.rb
|
105
104
|
- lib/rdf/model/graph.rb
|
105
|
+
- lib/rdf/model/literal/boolean.rb
|
106
|
+
- lib/rdf/model/literal/date.rb
|
107
|
+
- lib/rdf/model/literal/datetime.rb
|
108
|
+
- lib/rdf/model/literal/decimal.rb
|
109
|
+
- lib/rdf/model/literal/double.rb
|
110
|
+
- lib/rdf/model/literal/integer.rb
|
111
|
+
- lib/rdf/model/literal/time.rb
|
112
|
+
- lib/rdf/model/literal/xml.rb
|
106
113
|
- lib/rdf/model/literal.rb
|
107
114
|
- lib/rdf/model/node.rb
|
108
115
|
- lib/rdf/model/resource.rb
|