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.
@@ -1,3 +1,4 @@
1
+ * Gregg Kellogg <gregg@kellogg-assoc.com>
1
2
  * Hellekin O. Wolf <hellekin@cepheide.org>
2
3
  * John Fieber <jrf@ursamaris.org>
3
4
  * Pius Uzamere <pius@alum.mit.edu>
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.0.1
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
- URI.new(*args, &block)
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
  ##
@@ -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
- # @return [String] The normalized string representation of the value.
45
- attr_accessor :value
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
- @value = value
59
- @language = options[:language] ? options[:language].to_s.to_sym : nil
60
-
61
- if datatype = options[:datatype]
62
- @datatype = datatype.respond_to?(:to_uri) ? datatype.to_uri : URI.intern(datatype.to_s)
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
- @value = @value.to_s
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
- require 'bigdecimal' unless defined?(BigDecimal)
115
- BigDecimal.new(value)
142
+ ::BigDecimal.new(value)
116
143
  when XSD.date
117
- require 'date' unless defined?(Date)
118
- Date.parse(value)
144
+ ::Date.parse(value)
119
145
  when XSD.dateTime
120
- require 'date' unless defined?(DateTime)
121
- DateTime.parse(value)
146
+ ::DateTime.parse(value)
122
147
  when XSD.time
123
- require 'time'
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 a string representation of this literal.
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
- quoted = value # FIXME
211
- output = "\"#{quoted}\""
212
- output << "@#{language}" if language
213
- output << "^^<#{datatype}>" if datatype
214
- output
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
@@ -49,7 +49,7 @@ module RDF
49
49
  ##
50
50
  # @param [#to_s] id
51
51
  def initialize(id = nil)
52
- @id = (id || "g#{object_id}").to_s
52
+ @id = (id || "g#{__id__.to_i.abs}").to_s
53
53
  end
54
54
 
55
55
  ##
@@ -125,7 +125,7 @@ module RDF
125
125
  #
126
126
  # @return [String]
127
127
  def inspect
128
- sprintf("#<%s:%#0x(%s)>", self.class.name, object_id, to_s)
128
+ sprintf("#<%s:%#0x(%s)>", self.class.name, __id__, to_s)
129
129
  end
130
130
 
131
131
  ##
@@ -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
@@ -120,7 +120,7 @@ class RDF::Query
120
120
  ##
121
121
  # @return [String]
122
122
  def inspect
123
- sprintf("#<%s:%#0x(%s)>", self.class.name, object_id, @bindings.inspect)
123
+ sprintf("#<%s:%#0x(%s)>", self.class.name, __id__, @bindings.inspect)
124
124
  end
125
125
 
126
126
  protected
@@ -169,7 +169,7 @@ module RDF
169
169
  ##
170
170
  # @raise [NotImplementedError] unless implemented in subclass
171
171
  def read_triple
172
- raise NotImplementedError
172
+ raise NotImplementedError.new("#{self.class}#read_triple") # override in subclasses
173
173
  end
174
174
 
175
175
  ##
@@ -116,7 +116,7 @@ module RDF
116
116
  #
117
117
  # @return [String]
118
118
  def inspect
119
- sprintf("#<%s:%#0x(%s)>", self.class.name, object_id, uri.to_s)
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
 
@@ -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.object_id
87
- @index[value.object_id] = key
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.object_id] = key
124
+ @index[value.__id__] = key
125
125
  define_finalizer!(value)
126
126
  end
127
127
  value
@@ -2,8 +2,8 @@ module RDF
2
2
  module VERSION
3
3
  MAJOR = 0
4
4
  MINOR = 2
5
- TINY = 0
6
- EXTRA = 1
5
+ TINY = 1
6
+ EXTRA = nil
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY, EXTRA].compact.join('.')
9
9
 
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.0.1
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-19 00:00:00 +02:00
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
- - 6
47
- version: 0.5.6
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
- - 0
75
- version: 0.2.0
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