rdf 0.0.3 → 0.0.4

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.
@@ -0,0 +1,96 @@
1
+ module RDF
2
+ ##
3
+ # An RDF literal.
4
+ class Literal < Value
5
+ # @return [String] The normalized string representation of the value.
6
+ attr_accessor :value
7
+
8
+ # @return [Symbol] The language tag (optional).
9
+ attr_accessor :language
10
+
11
+ # @return [URI] The XML Schema datatype URI (optional).
12
+ attr_accessor :datatype
13
+
14
+ ##
15
+ # @param [Object]
16
+ # @option options [Symbol] :language (nil)
17
+ # @option options [URI] :datatype (nil)
18
+ def initialize(value, options = {})
19
+ @value = value
20
+ @language = options[:language] ? options[:language].to_s.to_sym : nil
21
+
22
+ if datatype = options[:datatype]
23
+ @datatype = datatype.respond_to?(:to_uri) ? datatype.to_uri : URI.new(datatype.to_s)
24
+ else
25
+ @datatype = case value
26
+ when String then nil # implicit XSD.string
27
+ when TrueClass then XSD.boolean
28
+ when FalseClass then XSD.boolean
29
+ when Fixnum then XSD.int
30
+ when Integer then XSD.long # FIXME
31
+ when Float
32
+ @value = case
33
+ when value.nan? then 'NaN'
34
+ when value.infinite? then value.to_s[0...-'inity'.length].upcase
35
+ else value.to_f
36
+ end
37
+ XSD.double
38
+ when Time, Date, DateTime
39
+ require 'time'
40
+ @value = value.respond_to?(:xmlschema) ? value.xmlschema : value.to_s
41
+ case value
42
+ when DateTime then XSD.dateTime
43
+ when Date then XSD.date
44
+ when Time then XSD.dateTime
45
+ end
46
+ end
47
+ end
48
+
49
+ @value = @value.to_s
50
+ end
51
+
52
+ ##
53
+ # @return [Boolean]
54
+ def eql?(other)
55
+ other.is_a?(Literal) && self == other
56
+ end
57
+
58
+ ##
59
+ # @return [Boolean]
60
+ def ==(other)
61
+ case other
62
+ when Literal
63
+ value.eql?(other.value) &&
64
+ language.eql?(other.language) &&
65
+ datatype.eql?(other.datatype)
66
+ when String
67
+ value.eql?(other) &&
68
+ language.nil? &&
69
+ datatype.nil?
70
+ else false
71
+ end
72
+ end
73
+
74
+ ##
75
+ # @return [Boolean]
76
+ def plain?
77
+ language.nil? && datatype.nil?
78
+ end
79
+
80
+ ##
81
+ # @return [Boolean]
82
+ def typed?
83
+ !datatype.nil?
84
+ end
85
+
86
+ ##
87
+ # @return [String]
88
+ def to_s
89
+ quoted = value # FIXME
90
+ output = "\"#{quoted}\""
91
+ output << "@#{language}" if language
92
+ output << "^^<#{datatype}>" if datatype
93
+ output
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,32 @@
1
+ module RDF
2
+ ##
3
+ # An RDF blank node, also known as an unlabeled node.
4
+ class Node < Resource
5
+ # @return [String]
6
+ attr_accessor :id
7
+
8
+ ##
9
+ # @param [#to_s]
10
+ def initialize(id = nil)
11
+ @id = (id || object_id).to_s
12
+ end
13
+
14
+ ##
15
+ # @return [Boolean]
16
+ def anonymous?() true end
17
+
18
+ ##
19
+ # @return [Boolean]
20
+ def labeled?() !unlabeled? end
21
+
22
+ ##
23
+ # @return [Boolean]
24
+ def unlabeled?() anonymous? end
25
+
26
+ ##
27
+ # @return [String]
28
+ def to_s
29
+ "_:%s" % id.to_s
30
+ end
31
+ end
32
+ end
@@ -1,34 +1,53 @@
1
1
  module RDF
2
- class ReaderError < IOError; end
3
-
2
+ ##
3
+ # An RDF parser.
4
+ #
5
+ # @abstract
4
6
  class Reader
5
7
  autoload :NTriples, 'rdf/reader/ntriples'
6
8
 
7
9
  include Enumerable
8
10
 
9
- @@subclasses = []
10
- @@file_extensions = {}
11
- @@content_types = {}
11
+ @@subclasses = []
12
+ @@file_extensions = {}
13
+ @@content_types = {}
12
14
  @@content_encoding = {}
13
15
 
16
+ ##
17
+ # Enumerates known RDF reader classes.
18
+ #
19
+ # @yield [klass]
20
+ # @yieldparam [Class]
14
21
  def self.each(&block)
15
22
  !block_given? ? @@subclasses : @@subclasses.each { |klass| yield klass }
16
23
  end
17
24
 
25
+ ##
26
+ # @return [{String => Symbol}]
18
27
  def self.content_types
19
28
  @@content_types
20
29
  end
21
30
 
31
+ ##
32
+ # @return [{Symbol => String}]
22
33
  def self.file_extensions
23
34
  @@file_extensions
24
35
  end
25
36
 
37
+ ##
38
+ # @param [Symbol] format
39
+ # @return [Class]
26
40
  def self.for(format)
27
41
  klass = case format.to_s.downcase.to_sym
28
42
  when :ntriples then RDF::Reader::NTriples
29
43
  end
30
44
  end
31
45
 
46
+ ##
47
+ # @param [String] filename
48
+ # @option options [Symbol] :format (:ntriples)
49
+ # @yield [reader]
50
+ # @yieldparam [Reader]
32
51
  def self.open(filename, options = {}, &block)
33
52
  options[:format] ||= :ntriples # FIXME
34
53
 
@@ -37,6 +56,10 @@ module RDF
37
56
  end
38
57
  end
39
58
 
59
+ ##
60
+ # @param [IO, String] input
61
+ # @yield [reader]
62
+ # @yieldparam [Reader]
40
63
  def initialize(input = $stdin, options = {}, &block)
41
64
  @options = options
42
65
  @nodes = {}
@@ -47,35 +70,57 @@ module RDF
47
70
  block.call(self) if block_given?
48
71
  end
49
72
 
73
+ ##
74
+ # @yield [statement]
75
+ # @yieldparam [Statement]
76
+ # @return [Reader]
50
77
  def each(&block)
51
78
  each_statement(&block)
52
79
  end
53
80
 
81
+ ##
82
+ # @yield [statement]
83
+ # @yieldparam [Statement]
84
+ # @return [Reader]
54
85
  def each_statement(&block)
55
86
  each_triple { |*triple| block.call(Statement.new(*triple)) }
87
+ self
56
88
  end
57
89
 
90
+ ##
91
+ # @yield [triple]
92
+ # @yieldparam [Array]
93
+ # @return [Reader]
58
94
  def each_triple(&block)
59
95
  begin
60
96
  loop { block.call(*read_triple) }
61
97
  rescue EOFError => e
62
98
  end
99
+ self
63
100
  end
64
101
 
65
102
  protected
66
103
 
104
+ ##
105
+ # @raise [NotImplementedError] unless implemented in subclass
67
106
  def read_triple
68
107
  raise NotImplementedError
69
108
  end
70
109
 
110
+ ##
111
+ # @raise [ReaderError]
71
112
  def fail_subject
72
113
  raise RDF::ReaderError, "expected subject in #{@input.inspect} line #{lineno}"
73
114
  end
74
115
 
116
+ ##
117
+ # @raise [ReaderError]
75
118
  def fail_predicate
76
119
  raise RDF::ReaderError, "expected predicate in #{@input.inspect} line #{lineno}"
77
120
  end
78
121
 
122
+ ##
123
+ # @raise [ReaderError]
79
124
  def fail_object
80
125
  raise RDF::ReaderError, "expected object in #{@input.inspect} line #{lineno}"
81
126
  end
@@ -125,4 +170,6 @@ module RDF
125
170
  end
126
171
 
127
172
  end
173
+
174
+ class ReaderError < IOError; end
128
175
  end
@@ -1,15 +1,18 @@
1
1
  module RDF class Reader
2
- # See <http://www.w3.org/TR/rdf-testcases/#ntriples>
2
+ ##
3
+ # An N-Triples parser.
4
+ #
5
+ # @see http://www.w3.org/TR/rdf-testcases/#ntriples
3
6
  class NTriples < Reader
4
-
5
7
  content_type 'text/plain', :extension => :nt
6
8
  content_encoding 'ascii'
7
9
 
8
10
  protected
9
11
 
12
+ ##
13
+ # @return [Array, nil]
14
+ # @see http://www.w3.org/TR/rdf-testcases/#ntrip_grammar
10
15
  def read_triple
11
- # <http://www.w3.org/TR/rdf-testcases/#ntrip_grammar>
12
-
13
16
  loop do
14
17
  readline.strip! # EOFError thrown on end of input
15
18
 
@@ -22,31 +25,35 @@ module RDF class Reader
22
25
  end
23
26
  end
24
27
 
28
+ ##
29
+ # @return [Boolean]
30
+ # @see http://www.w3.org/TR/rdf-testcases/#ntrip_grammar (comment)
25
31
  def read_comment
26
- # <http://www.w3.org/TR/rdf-testcases/#ntrip_grammar> (comment)
27
-
28
32
  match(/^#\s*(.*)$/)
29
33
  end
30
34
 
35
+ ##
36
+ # @return [URI, nil]
37
+ # @see http://www.w3.org/TR/rdf-testcases/#ntrip_grammar (uriref)
31
38
  def read_uriref
32
- # <http://www.w3.org/TR/rdf-testcases/#ntrip_grammar> (uriref)
33
-
34
39
  if uri = match(/^<([^>]+)>/)
35
40
  RDF::URI.parse(uri)
36
41
  end
37
42
  end
38
43
 
44
+ ##
45
+ # @return [Node, nil]
46
+ # @see http://www.w3.org/TR/rdf-testcases/#ntrip_grammar (nodeID)
39
47
  def read_bnode
40
- # <http://www.w3.org/TR/rdf-testcases/#ntrip_grammar> (nodeID)
41
-
42
48
  if node_id = match(/^_:([A-Za-z][A-Za-z0-9]*)/)
43
49
  @nodes[node_id] ||= Object.new # TODO: RDF::Node.new
44
50
  end
45
51
  end
46
52
 
53
+ ##
54
+ # @return [String, Literal, nil]
55
+ # @see http://www.w3.org/TR/rdf-testcases/#ntrip_grammar (literal)
47
56
  def read_literal
48
- # <http://www.w3.org/TR/rdf-testcases/#ntrip_grammar> (literal)
49
-
50
57
  if literal = match(/^"((?:\\"|[^"])*)"/)
51
58
  literal = unescaped(literal)
52
59
 
@@ -62,15 +69,16 @@ module RDF class Reader
62
69
  end
63
70
  end
64
71
 
72
+ ##
73
+ # @param [String] string
74
+ # @return [String]
75
+ # @see http://www.w3.org/TR/rdf-testcases/#ntrip_strings
65
76
  def unescaped(string)
66
- # <http://www.w3.org/TR/rdf-testcases/#ntrip_strings>
67
-
68
77
  ["\t", "\n", "\r", "\"", "\\"].each do |escape|
69
78
  string.gsub!(escape.inspect[1...-1], escape)
70
79
  end
71
80
  string.gsub!(/\\u([0-9A-Fa-f]{4,4})/u) { [$1.hex].pack('U*') }
72
81
  string.gsub!(/\\U([0-9A-Fa-f]{8,8})/u) { [$1.hex].pack('U*') }
73
-
74
82
  string
75
83
  end
76
84
 
@@ -0,0 +1,10 @@
1
+ module RDF
2
+ ##
3
+ # An RDF resource.
4
+ #
5
+ # @abstract
6
+ class Resource < Value
7
+ # Prevent instantiation of this class.
8
+ private_class_method :new
9
+ end
10
+ end
@@ -1,30 +1,77 @@
1
1
  module RDF
2
2
  ##
3
3
  # An RDF statement.
4
- class Statement
4
+ class Statement < Value
5
+ # @return [Object]
6
+ attr_accessor :id
7
+
8
+ # @return [Resource]
5
9
  attr_accessor :context
10
+
11
+ # @return [Resource]
6
12
  attr_accessor :subject
13
+
14
+ # @return [URI]
7
15
  attr_accessor :predicate
16
+
17
+ # @return [Value]
8
18
  attr_accessor :object
9
19
 
20
+ ##
21
+ # @param [Resource] s
22
+ # @param [URI] p
23
+ # @param [Value] o
24
+ # @option options [Resource] :context (nil)
10
25
  def initialize(s = nil, p = nil, o = nil, options = {})
11
26
  @context = options[:context] || options[:graph]
12
27
  @subject, @predicate, @object = s, p, o
13
28
  end
14
29
 
30
+ ##
31
+ # @return [Boolean]
15
32
  def asserted?() !quoted? end
33
+
34
+ ##
35
+ # @return [Boolean]
16
36
  def quoted?() false end
17
37
 
38
+ ##
39
+ # @return [Boolean]
18
40
  def has_graph?() has_context? end
41
+
42
+ ##
43
+ # @return [Boolean]
19
44
  def has_context?() !!context end
45
+
46
+ ##
47
+ # @return [Boolean]
20
48
  def has_subject?() !!subject end
49
+
50
+ ##
51
+ # @return [Boolean]
21
52
  def has_predicate?() !!predicate end
53
+
54
+ ##
55
+ # @return [Boolean]
22
56
  def has_object?() !!object end
23
57
 
58
+ ##
59
+ # @param [Statement] other
60
+ # @return [Boolean]
61
+ def eql?(other)
62
+ other.is_a?(Statement) && self == other
63
+ end
64
+
65
+ ##
66
+ # @param [Object] other
67
+ # @return [Boolean]
24
68
  def ==(other)
25
69
  to_a == other.to_a
26
70
  end
27
71
 
72
+ ##
73
+ # @param [Statement] other
74
+ # @return [Boolean]
28
75
  def ===(other)
29
76
  return false if has_subject? && subject != other.subject
30
77
  return false if has_predicate? && predicate != other.predicate
@@ -32,10 +79,17 @@ module RDF
32
79
  return true
33
80
  end
34
81
 
82
+ ##
83
+ # @param [Integer] index
84
+ # @return [Value]
35
85
  def [](index)
36
86
  to_a[index]
37
87
  end
38
88
 
89
+ ##
90
+ # @param [Integer] index
91
+ # @param [Value] value
92
+ # @return [Value]
39
93
  def []=(index, value)
40
94
  case index
41
95
  when 0 then subject = value
@@ -45,16 +99,34 @@ module RDF
45
99
  end
46
100
  end
47
101
 
48
- def to_a() to_ary end
49
-
50
- def to_ary
102
+ ##
103
+ # @return [Array]
104
+ def to_triple
51
105
  [subject, predicate, object]
52
106
  end
53
107
 
108
+ ##
109
+ # @return [Array]
110
+ def to_quad
111
+ [subject, predicate, object, context]
112
+ end
113
+
114
+ ##
115
+ # @return [Array]
116
+ def to_a() to_triple end
117
+
118
+ ##
119
+ # @return [Array]
120
+ def to_ary() to_triple end
121
+
122
+ ##
123
+ # @return [Hash]
54
124
  def to_hash
55
125
  { subject => { predicate => object } }
56
126
  end
57
127
 
128
+ ##
129
+ # @return [String]
58
130
  def to_s
59
131
  require 'stringio' unless defined?(StringIO)
60
132
  StringIO.open do |buffer|
@@ -64,9 +136,5 @@ module RDF
64
136
  buffer.string
65
137
  end
66
138
  end
67
-
68
- def inspect
69
- sprintf("#<%s:%#0x(%s)>", self.class.name, object_id, to_s)
70
- end
71
139
  end
72
140
  end