rdf_context 0.4.5 → 0.4.6

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,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