rdf 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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