rdf_context 0.4.5 → 0.4.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,10 @@
1
+ === 0.4.6
2
+ * Added Graph#uri_mapping and AbstractStore#uri_mapping for uri => Namespace mappings in graph
3
+ * Fix BNode creation from existing identifier (named or un-named)
4
+ * Graph#destroy removes graph context from store without configuration, and removes store storage with configuration
5
+ * Added Triple#to_n3 and URIRef#to_n3
6
+ * Added AbstractStore#uri_binding to give uri => namespace mapping from all store classes.
7
+
1
8
  === 0.4.5
2
9
  * Order includes to remove platform dependencies on load requirements.
3
10
  * Fix XML Comparison matcher
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.5
1
+ 0.4.6
@@ -16,9 +16,11 @@ module RdfContext
16
16
  # @param [String] identifier:: Legal NCName or nil for a named BNode
17
17
  # @param [Hash] context:: Context used to store named BNodes
18
18
  def initialize(identifier = nil, context = {})
19
- if identifier != nil && self.valid_id?(identifier)
20
- identifier = identifier.sub(/nbn\d+[a-z]+N/, '') # creating a named BNode from a named BNode
21
- # Generate a name if it's blank. Always prepend "named" to avoid generation overlap
19
+ if identifier.nil?
20
+ @identifier = generate_bn_identifier
21
+ elsif identifier.match(/n?bn\d+[a-z]+(N\w+)?$/)
22
+ @identifier = context[identifier] || identifier
23
+ elsif self.valid_id?(identifier)
22
24
  @identifier = context[identifier] ||= generate_bn_identifier(identifier)
23
25
  else
24
26
  @identifier = generate_bn_identifier
@@ -42,14 +44,7 @@ module RdfContext
42
44
  def to_n3
43
45
  "_:#{self.identifier}"
44
46
  end
45
-
46
- ##
47
- # Exports the BNode in N-Triples form.
48
- #
49
- # Syonym for to_n3
50
- def to_ntriples
51
- self.to_n3
52
- end
47
+ alias_method :to_ntriples, :to_n3
53
48
 
54
49
  # Output URI as resource reference for RDF/XML
55
50
  #
@@ -66,8 +61,12 @@ module RdfContext
66
61
 
67
62
  # Compare BNodes. BNodes are equivalent if they have the same identifier
68
63
  def eql?(other)
69
- other.class == self.class &&
70
- other.identifier == self.identifier
64
+ case other
65
+ when BNode
66
+ other.identifier == self.identifier
67
+ else
68
+ self.identifier == other.to_s
69
+ end
71
70
  end
72
71
  alias_method :==, :eql?
73
72
 
@@ -75,7 +74,7 @@ module RdfContext
75
74
  def hash; self.to_s.hash; end
76
75
 
77
76
  def inspect
78
- "[bn:#{identifier}]"
77
+ "#{self.class}[#{self.to_n3}]"
79
78
  end
80
79
 
81
80
  protected
@@ -59,8 +59,14 @@ module RdfContext
59
59
  def nsbinding; @store.nsbinding; end
60
60
 
61
61
  # Destroy the store identified by _configuration_ if supported
62
+ # If configuration is nil, remove the graph context
62
63
  def destroy(configuration = nil)
63
- @store.destroy(configuration)
64
+ if configuration
65
+ @store.destroy(configuration)
66
+ else
67
+ @store.remove(Triple.new(nil, nil, nil), self)
68
+ end
69
+
64
70
  self.freeze
65
71
  end
66
72
 
@@ -120,13 +126,18 @@ module RdfContext
120
126
  "xml" => XML_NS
121
127
  )
122
128
  rdf_attrs = extended_bindings.values.inject({}) { |hash, ns| hash.merge(ns.xmlns_attr => ns.uri.to_s)}
123
- uri_bindings = extended_bindings.values.inject({}) { |hash, ns| hash.merge(ns.uri.to_s => ns.prefix)}
129
+ uri_bindings = self.uri_binding.merge(
130
+ RDF_NS.uri.to_s => RDF_NS,
131
+ RDFS_NS.uri.to_s => RDFS_NS,
132
+ XHV_NS.uri.to_s => XHV_NS,
133
+ XML_NS.uri.to_s => XML_NS
134
+ )
124
135
 
125
136
  # Add bindings for predicates not already having bindings
126
137
  tmp_ns = "ns0"
127
138
  predicates.each do |p|
128
139
  unless uri_bindings.has_key?(p.base)
129
- uri_bindings[p.base] = tmp_ns
140
+ uri_bindings[p.base] = Namespace.new(p.base, tmp_ns)
130
141
  rdf_attrs["xmlns:#{tmp_ns}"] = p.base
131
142
  tmp_ns = tmp_ns.succ
132
143
  end
@@ -171,9 +182,12 @@ module RdfContext
171
182
  @store.bind(namespace)
172
183
  end
173
184
 
174
- # List of namespace bindings, as a hash
185
+ # Hash of prefix => Namespace bindings
175
186
  def nsbinding; @store.nsbinding; end
176
187
 
188
+ # Hash of uri => Namespace bindings
189
+ def uri_binding; @store.uri_binding; end
190
+
177
191
  # Namespace for prefix
178
192
  def namespace(prefix); @store.namespace(prefix); end
179
193
 
@@ -35,10 +35,6 @@ module RdfContext
35
35
  end
36
36
  end
37
37
 
38
- def inspect
39
- to_s()
40
- end
41
-
42
38
  def self.the_null_encoding
43
39
  @the_null_encoding ||= Null.new(nil)
44
40
  end
@@ -314,6 +310,10 @@ module RdfContext
314
310
  end
315
311
  alias_method :to_ntriples, :to_n3
316
312
 
313
+ def inspect
314
+ "#{self.class}[#{self.to_n3}]"
315
+ end
316
+
317
317
  # Output literal in TriX format
318
318
  def to_trix
319
319
  encoding.format_as_trix(@contents, @lang)
@@ -324,7 +324,7 @@ module RdfContext
324
324
  # ==== Example
325
325
  # Encoding.the_null_encoding.xml_args("foo", "en-US") => ["foo", {"xml:lang" => "en-US"}]
326
326
  def xml_args
327
- encoding.xml_args( @contents, @lang)
327
+ encoding.xml_args(@contents, @lang)
328
328
  end
329
329
 
330
330
  # Is this an XMLLiteral?
@@ -9,9 +9,9 @@ module RdfContext
9
9
 
10
10
  # Parse N3 document from a string or input stream to closure or graph.
11
11
  #
12
- # Optionally, the stream may be a Nokogiri::HTML::Document or Nokogiri::XML::Document
13
- # With a block, yeilds each statement with URIRef, BNode or Literal elements
14
- #
12
+ # If the parser is called with a block, triples are passed to the block rather
13
+ # than added to the graph.
14
+ #
15
15
  # @param [String] n3_str:: the Notation3/Turtle string
16
16
  # @param [String] uri:: the URI of the document
17
17
  # @param [Hash] options:: Options include the following
@@ -18,10 +18,10 @@ module RdfContext
18
18
  #
19
19
  # @author Tom Morris, Pius Uzamere
20
20
  def initialize(uri, prefix, fragment = nil)
21
+ prefix = prefix.to_s
21
22
  @uri = URIRef.new(uri) unless uri.is_a?(URIRef)
22
23
  @fragment = fragment
23
24
  @fragment = uri.to_s.match(/\#$/) ? true : false if fragment.nil?
24
- prefix = nil if prefix.to_s.empty?
25
25
  if prefix_valid?(prefix)
26
26
  @prefix = prefix
27
27
  else
@@ -61,7 +61,7 @@ module RdfContext
61
61
 
62
62
  # Output xmlns attribute name
63
63
  def xmlns_attr
64
- prefix.nil? ? "xmlns" : "xmlns:#{prefix}"
64
+ prefix.empty? ? "xmlns" : "xmlns:#{prefix}"
65
65
  end
66
66
 
67
67
  # Output namespace definition as a hash
@@ -39,6 +39,9 @@ module RdfContext
39
39
 
40
40
  # Parse RDF document from a string or input stream to closure or graph.
41
41
  #
42
+ # If the parser is called with a block, triples are passed to the block rather
43
+ # than added to the graph.
44
+ #
42
45
  # Virtual Class, prototype for Parser subclass.
43
46
  #
44
47
  # @param [IO, String] stream:: the RDF IO stream, string, Nokogiri::HTML::Document or Nokogiri::XML::Document
@@ -96,7 +99,7 @@ module RdfContext
96
99
  when /\.(nt|n3|txt)$/ then :n3
97
100
  else
98
101
  # Got to look into the file to see
99
- if stream.is_a?(IO)
102
+ if stream.is_a?(IO) || stream.is_a?(StringIO)
100
103
  stream.rewind
101
104
  string = stream.read(1000)
102
105
  stream.rewind
@@ -133,6 +136,9 @@ module RdfContext
133
136
 
134
137
  # add a triple, object can be literal or URI or bnode
135
138
  #
139
+ # If the parser is called with a block, triples are passed to the block rather
140
+ # than added to the graph.
141
+ #
136
142
  # @param [Nokogiri::XML::Node, any] node:: XML Node or string for showing context
137
143
  # @param [URIRef, BNode] subject:: the subject of the triple
138
144
  # @param [URIRef] predicate:: the predicate of the triple
@@ -49,6 +49,9 @@ module RdfContext
49
49
 
50
50
  # Parse XHTML+RDFa document from a string or input stream to closure or graph.
51
51
  #
52
+ # If the parser is called with a block, triples are passed to the block rather
53
+ # than added to the graph.
54
+ #
52
55
  # Optionally, the stream may be a Nokogiri::HTML::Document or Nokogiri::XML::Document
53
56
  # With a block, yeilds each statement with URIRef, BNode or Literal elements
54
57
  #
@@ -98,8 +98,10 @@ module RdfContext
98
98
 
99
99
  # Parse RDF/XML document from a string or input stream to closure or graph.
100
100
  #
101
+ # If the parser is called with a block, triples are passed to the block rather
102
+ # than added to the graph.
103
+ #
101
104
  # Optionally, the stream may be a string or Nokogiri::XML::Document
102
- # With a block, yeilds each statement with URIRef, BNode or Literal elements
103
105
  #
104
106
  # @param [IO] stream:: the RDF/XML IO stream, string or Nokogiri::XML::Document
105
107
  # @param [String] uri:: the URI of the document
@@ -116,6 +118,8 @@ module RdfContext
116
118
  else Nokogiri::XML.parse(stream, uri.to_s)
117
119
  end
118
120
 
121
+ raise ParserException, "Synax errors:\n#{@doc.errors}" unless @doc.errors.empty?
122
+
119
123
  @id_mapping = Hash.new
120
124
 
121
125
  raise ParserException, "Empty document" if @doc.nil? || @doc.root.nil?
@@ -196,6 +200,12 @@ module RdfContext
196
200
  # Determine the content type of this property element
197
201
  text_nodes = child.children.select {|e| e.text? && !e.blank?}
198
202
  element_nodes = child.children.select(&:element?)
203
+ add_debug(child, "#{text_nodes.length} text nodes, #{element_nodes.length} element nodes")
204
+ if element_nodes.length > 1
205
+ element_nodes.each do |node|
206
+ add_debug(child, " node: #{node.to_s}")
207
+ end
208
+ end
199
209
 
200
210
  # List expansion
201
211
  predicate = ec.li_next(predicate) if predicate == RDF_NS.li
@@ -245,12 +255,12 @@ module RdfContext
245
255
  resourceAttr = resourceAttr.rdf_escape if resourceAttr
246
256
  nodeID = nodeID_check(el, nodeID.rdf_escape) if nodeID
247
257
 
248
- add_debug(el, "attrs: #{attrs.inspect}")
249
- add_debug(el, "datatype: #{datatype}") if datatype
250
- add_debug(el, "parseType: #{parseType}") if parseType
251
- add_debug(el, "resource: #{resourceAttr}") if resourceAttr
252
- add_debug(el, "nodeID: #{nodeID}") if nodeID
253
- add_debug(el, "id: #{id}") if id
258
+ add_debug(child, "attrs: #{attrs.inspect}")
259
+ add_debug(child, "datatype: #{datatype}") if datatype
260
+ add_debug(child, "parseType: #{parseType}") if parseType
261
+ add_debug(child, "resource: #{resourceAttr}") if resourceAttr
262
+ add_debug(child, "nodeID: #{nodeID}") if nodeID
263
+ add_debug(child, "id: #{id}") if id
254
264
 
255
265
  if attrs.empty? && datatype.nil? && parseType.nil? && element_nodes.length == 1
256
266
  # Production resourcePropertyElt
@@ -512,6 +512,7 @@ module RdfContext
512
512
  @namespaceCache ||= {}
513
513
  @namespaceUriCache ||= {}
514
514
  @nsbinding = nil
515
+ @uri_binding = nil
515
516
  @namespaceCache[namespace.prefix] = namespace
516
517
  @namespaceUriCache[namespace.uri.to_s] = namespace.prefix
517
518
  namespace
@@ -521,14 +522,14 @@ module RdfContext
521
522
  def namespace(prefix)
522
523
  @namespaceCache ||= {}
523
524
  @namespaceUriCache ||= {}
524
- unless @namespaceCache.has_key?(prefix)
525
+ unless @namespaceCache.has_key?(prefix.to_s)
525
526
  @namespaceCache[prefix] = nil
526
- executeSQL("SELECT uri FROM #{namespace_binds} WHERE prefix=?", prefix) do |row|
527
- @namespaceCache[prefix] = Namespace.new(row[0], prefix)
528
- @namespaceUriCache[row[0].to_s] = prefix
527
+ executeSQL("SELECT uri FROM #{namespace_binds} WHERE prefix=?", prefix.to_s) do |row|
528
+ @namespaceCache[prefix.to_s] = Namespace.new(row[0], prefix.to_s)
529
+ @namespaceUriCache[row[0].to_s] = prefix.to_s
529
530
  end
530
531
  end
531
- @namespaceCache[prefix]
532
+ @namespaceCache[prefix.to_s]
532
533
  end
533
534
 
534
535
  # Prefix for namespace
@@ -546,18 +547,30 @@ module RdfContext
546
547
  @namespaceUriCache[uri.to_s]
547
548
  end
548
549
 
549
- # List of namespace bindings, as a hash
550
+ # Hash of prefix => Namespace bindings
550
551
  def nsbinding
551
552
  unless @nsbinding.is_a?(Hash)
552
553
  @nsbinding = {}
554
+ @uri_binding = {}
553
555
  executeSQL("SELECT prefix, uri FROM #{namespace_binds}") do |row|
554
- @nsbinding[row[0]] = Namespace.new(row[1], row[0])
556
+ prefix, uri = row
557
+ namespace = Namespace.new(uri, prefix)
558
+ @nsbinding[prefix] = namespace
559
+ # Over-write an empty prefix
560
+ @uri_binding[uri] = namespace unless prefix.to_s.empty?
561
+ @uri_binding[uri] ||= namespace
555
562
  end
556
563
  @nsbinding
557
564
  end
558
565
  @nsbinding
559
566
  end
560
567
 
568
+ # Hash of uri => Namespace bindings
569
+ def uri_binding
570
+ nsbinding
571
+ @uri_binding
572
+ end
573
+
561
574
  # Transactional interfaces
562
575
  def commit; @db.commit; end
563
576
 
@@ -1,12 +1,12 @@
1
1
  module RdfContext
2
2
  # Abstract storage module, superclass of other storage classes
3
3
  class AbstractStore
4
- attr_reader :nsbinding, :identifier
4
+ attr_reader :nsbinding, :uri_binding, :identifier
5
5
 
6
6
  def initialize(identifier = nil, configuration = {})
7
7
  @nsbinding = {}
8
8
  # Reverse namespace binding
9
- @prefix = {}
9
+ @uri_binding = {}
10
10
 
11
11
  @identifier = identifier || BNode.new
12
12
  end
@@ -34,18 +34,21 @@ module RdfContext
34
34
 
35
35
  # Bind namespace to store, returns bound namespace
36
36
  def bind(namespace)
37
- @prefix[namespace.uri.to_s] = namespace.prefix
38
- @nsbinding[namespace.prefix] ||= namespace
37
+ # Over-write an empty prefix
38
+ uri = namespace.uri.to_s
39
+ @uri_binding[uri] = namespace unless namespace.prefix.to_s.empty?
40
+ @uri_binding[uri] ||= namespace
41
+ @nsbinding[namespace.prefix.to_s] ||= namespace
39
42
  end
40
43
 
41
44
  # Namespace for prefix
42
45
  def namespace(prefix)
43
- @nsbinding[prefix]
46
+ @nsbinding[prefix.to_s]
44
47
  end
45
48
 
46
49
  # Prefix for namespace
47
50
  def prefix(namespace)
48
- namespace.is_a?(Namespace) ? @prefix[namespace.uri.to_s] : @prefix[namespace]
51
+ namespace.is_a?(Namespace) ? @uri_binding[namespace.uri.to_s].prefix : @uri_binding[namespace].prefix
49
52
  end
50
53
 
51
54
  # Get all BNodes with usage count used within graph
@@ -74,7 +74,7 @@ module RdfContext
74
74
  oi = resource_to_int(triple.object) || gen_key(triple.object)
75
75
  ci = resource_to_int(context) || gen_key(context)
76
76
 
77
- #puts "add: #{si}, #{pi}, #{oi}, #{ci}" if $DEBUG
77
+ puts "add: #{si}, #{pi}, #{oi}, #{ci}" if $DEBUG
78
78
  set_nested_index(@cspo, ci, si, pi, oi)
79
79
  set_nested_index(@cpos, ci, pi, oi, si)
80
80
  set_nested_index(@cosp, ci, oi, si, pi)
@@ -36,16 +36,17 @@ module RdfContext
36
36
  @patern
37
37
  end
38
38
 
39
- # Serialize Triple to N-Triples
40
- def to_ntriples
39
+ # Serialize Triple to N3
40
+ def to_n3
41
41
  raise RdfException.new("Can't serialize patern triple") if is_patern?
42
42
  @subject.to_ntriples + " " + @predicate.to_ntriples + " " + @object.to_ntriples + " ."
43
43
  end
44
+ alias_method :to_ntriples, :to_n3
44
45
 
45
46
  def to_s; self.to_ntriples; end
46
47
 
47
48
  def inspect
48
- [@subject, @predicate, @object, @patern].inspect
49
+ "#{self.class}[#{self.to_n3}]"
49
50
  end
50
51
 
51
52
  # Is the predicate of this statment rdf:type?
@@ -3,6 +3,7 @@ require 'net/http'
3
3
  module RdfContext
4
4
  class URIRef
5
5
  attr_accessor :uri
6
+ attr_reader :namespace
6
7
 
7
8
  # Create a URIRef from a URI or a fragment and a URI
8
9
  #
@@ -70,19 +71,20 @@ module RdfContext
70
71
  @uri.to_s
71
72
  end
72
73
 
73
- def to_ntriples
74
+ def to_n3
74
75
  "<" + @uri.to_s + ">"
75
76
  end
77
+ alias_method :to_ntriples, :to_n3
76
78
 
77
79
  # Output URI as QName using URI binding
78
80
  def to_qname(uri_binding = {})
79
- sn = self.short_name
80
- uri_base = self.base
81
- if uri_binding.has_key?(uri_base)
82
- "#{uri_binding[uri_base]}:#{sn}"
83
- else
84
- raise ParserException, "Couldn't find QName for #{@uri}, base: #{uri_base}"
85
- end
81
+ @namespace ||= uri_binding[self.base]
82
+ raise RdfException, "Couldn't find QName for #{@uri}" unless @namespace
83
+ "#{@namespace.prefix}:#{self.short_name}"
84
+ end
85
+
86
+ def inspect
87
+ "#{self.class}[#{self.to_n3}]"
86
88
  end
87
89
 
88
90
  # Output URI as resource reference for RDF/XML
@@ -34,6 +34,16 @@ describe "Blank nodes" do
34
34
  end
35
35
  end
36
36
 
37
+ it "should accept valid bnode identifier" do
38
+ bn = BNode.new
39
+ BNode.new(bn.to_s).should == bn
40
+ end
41
+
42
+ it "should accept valid named bnode identifier" do
43
+ bn = BNode.new("foo")
44
+ BNode.new(bn.to_s).should == bn
45
+ end
46
+
37
47
  describe "which has a blank identifier" do
38
48
  subject { BNode.new("", @context) }
39
49
  it "should not be the same as an anonymous identifier" do should_not == BNode.new end
@@ -72,11 +72,14 @@ describe "URI References" do
72
72
  end
73
73
 
74
74
  it "should create QName from URI with namespace" do
75
- uri = URIRef.new("http://example.org/foo#bar")
76
- uri.to_qname("http://example.org/foo#" => "ex").should == "ex:bar"
75
+ ex = Namespace.new("http://example.org/foo#", "ex")
76
+ foaf = Namespace.new("http://xmlns.com/foaf/0.1/", "foaf")
77
+
78
+ uri = ex.bar
79
+ uri.to_qname(ex.uri.to_s => ex).should == "ex:bar"
77
80
 
78
- uri = URIRef.new("http://xmlns.com/foaf/0.1/knows")
79
- uri.to_qname("http://xmlns.com/foaf/0.1/" => "foaf").should == "foaf:knows"
81
+ uri = foaf.knows
82
+ uri.to_qname(foaf.uri.to_s => foaf).should == "foaf:knows"
80
83
  end
81
84
 
82
85
  it "should create resource hash for RDF/XML" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rdf_context
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.5
4
+ version: 0.4.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gregg Kellogg
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-01-08 00:00:00 -08:00
12
+ date: 2010-01-15 00:00:00 -08:00
13
13
  default_executable: rdf_context
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency