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.
@@ -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