rdf 0.2.0.1 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|