rdf 1.1.3 → 1.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/CREDITS +1 -0
  3. data/VERSION +1 -1
  4. data/lib/rdf.rb +10 -48
  5. data/lib/rdf/cli/vocab-loader.rb +78 -142
  6. data/lib/rdf/mixin/enumerable.rb +25 -0
  7. data/lib/rdf/mixin/mutable.rb +3 -0
  8. data/lib/rdf/model/graph.rb +1 -1
  9. data/lib/rdf/model/node.rb +25 -2
  10. data/lib/rdf/model/statement.rb +20 -12
  11. data/lib/rdf/model/uri.rb +11 -2
  12. data/lib/rdf/nquads.rb +8 -6
  13. data/lib/rdf/ntriples/writer.rb +14 -10
  14. data/lib/rdf/query/pattern.rb +10 -8
  15. data/lib/rdf/reader.rb +11 -2
  16. data/lib/rdf/repository.rb +1 -1
  17. data/lib/rdf/vocab.rb +396 -96
  18. data/lib/rdf/vocab/cc.rb +117 -25
  19. data/lib/rdf/vocab/cert.rb +230 -117
  20. data/lib/rdf/vocab/dc.rb +930 -233
  21. data/lib/rdf/vocab/dc11.rb +151 -37
  22. data/lib/rdf/vocab/doap.rb +326 -114
  23. data/lib/rdf/vocab/exif.rb +930 -533
  24. data/lib/rdf/vocab/foaf.rb +602 -346
  25. data/lib/rdf/vocab/geo.rb +139 -33
  26. data/lib/rdf/vocab/gr.rb +1551 -1084
  27. data/lib/rdf/vocab/ht.rb +319 -0
  28. data/lib/rdf/vocab/ical.rb +507 -349
  29. data/lib/rdf/vocab/ma.rb +504 -280
  30. data/lib/rdf/vocab/mo.rb +2425 -876
  31. data/lib/rdf/vocab/og.rb +178 -90
  32. data/lib/rdf/vocab/owl.rb +513 -219
  33. data/lib/rdf/vocab/prov.rb +1557 -479
  34. data/lib/rdf/vocab/rdfs.rb +107 -31
  35. data/lib/rdf/vocab/rdfv.rb +165 -0
  36. data/lib/rdf/vocab/rsa.rb +61 -18
  37. data/lib/rdf/vocab/rss.rb +55 -22
  38. data/lib/rdf/vocab/schema.rb +8590 -3995
  39. data/lib/rdf/vocab/sioc.rb +657 -218
  40. data/lib/rdf/vocab/skos.rb +227 -134
  41. data/lib/rdf/vocab/skosxl.rb +47 -33
  42. data/lib/rdf/vocab/vcard.rb +693 -327
  43. data/lib/rdf/vocab/void.rb +175 -132
  44. data/lib/rdf/vocab/vs.rb +27 -0
  45. data/lib/rdf/vocab/wdrs.rb +123 -119
  46. data/lib/rdf/vocab/wot.rb +155 -45
  47. data/lib/rdf/vocab/xhtml.rb +2 -1
  48. data/lib/rdf/vocab/xhv.rb +496 -231
  49. data/lib/rdf/vocab/xsd.rb +382 -53
  50. data/lib/rdf/writer.rb +8 -4
  51. metadata +5 -4
  52. data/lib/rdf/vocab/http.rb +0 -84
  53. data/lib/rdf/vocab/v.rb +0 -154
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 55eaca604297a43e08c5e5ab9171b1e2ec0beada
4
- data.tar.gz: 139cabcf47483e12266822d66882d7a0913ede67
3
+ metadata.gz: dcb26de738e672fd9328d6f653a98b7171f65805
4
+ data.tar.gz: da26233652361aaa44fa23fe258d0fbbc666dbf0
5
5
  SHA512:
6
- metadata.gz: ffc0b6886fa305b29566f4a5f98119bd60ff16359ea7eb6c1768981dabdc809ea6edfbe2569a8de10e101b3f65a312c62a962b739900cc223461665f3194d635
7
- data.tar.gz: 97a984581ad73bc752aa3c16f0e11ad85fa1eb8814bcf05434d7b90b83ca6807e794fe1bdf371c294f4c10b1a562ec9827129e655652eb437311c4e6b997d239
6
+ metadata.gz: da30c447f12e8412899db7ca822097ced698a689384384a698a5c1ea326d6d1faf32c65053d363424c3f4c73460417bf02fbc8cd6d0930c9edaf3667dfe7b6dd
7
+ data.tar.gz: b4093866aba7ef2198e458d41537eec08142e5faae9f56c0fee832d1f34e88e1f7481a9b5d11257b779719b2b4f37c41be73900277a64c7bcaab11c67df1ae1b
data/CREDITS CHANGED
@@ -10,3 +10,4 @@
10
10
  * Keita Urashima <ursm@ursm.jp>
11
11
  * Pius Uzamere <pius@alum.mit.edu>
12
12
  * Judson Lester <nyarly@gmail.com>
13
+ * Peter Vandenabeele <peter@vandenabeele.com>
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.3
1
+ 1.1.4
data/lib/rdf.rb CHANGED
@@ -193,61 +193,23 @@ module RDF
193
193
  # @return [#to_s] property
194
194
  # @return [URI]
195
195
  def self.[](property)
196
- RDF::URI.intern([to_uri.to_s, property.to_s].join)
196
+ property.to_s =~ %r{_\d+} ? RDF::URI("#{to_uri}#{property}") : RDF::RDFV[property]
197
197
  end
198
198
 
199
199
  ##
200
- # @param [Symbol] property
201
- # @return [URI]
202
- # @raise [NoMethodError]
200
+ # respond to module or RDFV
201
+ def self.respond_to?(method)
202
+ super || RDF::RDFV.respond_to?(method)
203
+ end
204
+
205
+ ##
206
+ # Delegate other methods to RDF::RDF
203
207
  def self.method_missing(property, *args, &block)
204
208
  if args.empty?
205
- self[property]
209
+ # Special-case rdf:_n for all integers
210
+ property.to_s =~ %r{_\d+} ? RDF::URI("#{to_uri}#{property}") : RDF::RDFV.send(property)
206
211
  else
207
212
  super
208
213
  end
209
214
  end
210
-
211
- ##
212
- # @return [URI]
213
- def self.to_rdf
214
- to_uri
215
- end
216
-
217
- ##
218
- # @return [URI]
219
- def self.to_uri
220
- RDF::URI.intern("http://www.w3.org/1999/02/22-rdf-syntax-ns#")
221
- end
222
-
223
- # RDF Vocabulary terms
224
- %w(
225
- Alt
226
- Bag
227
- first
228
- HTML
229
- langString
230
- nil
231
- object
232
- predicate
233
- Property
234
- rest
235
- Seq
236
- subject
237
- type
238
- value
239
- XMLLiteral
240
- ).each do |term|
241
- term_uri = self[term.to_sym]
242
- define_method(term) {term_uri}
243
- module_function term.to_sym
244
- end
245
-
246
- class << self
247
- # For compatibility with `RDF::Vocabulary.__name__`:
248
- alias_method :__name__, :name
249
-
250
- # For IRI compatibility
251
- alias_method :to_iri, :to_uri
252
- end
253
215
  end
@@ -9,27 +9,27 @@ module RDF
9
9
  class VocabularyLoader
10
10
  def initialize(class_name = nil)
11
11
  @class_name = class_name
12
+ @module_name = "RDF"
12
13
  @output = $stdout
13
14
  @output_class_file = true
14
- @prefix = nil
15
- @url = nil
15
+ @uri = nil
16
16
  @strict = true
17
17
  @extra = []
18
18
  end
19
- attr_accessor :class_name, :output, :output_class_file
20
- attr_reader :prefix, :source
19
+ attr_accessor :class_name, :module_name, :output, :output_class_file
20
+ attr_reader :uri, :source
21
21
 
22
- # Set the prefix for the loaded RDF file - by default, sets the source as
22
+ # Set the URI for the loaded RDF file - by default, sets the source as
23
23
  # well
24
- def prefix=(uri)
25
- @prefix = uri
24
+ def uri=(uri)
25
+ @uri = uri
26
26
  @source ||= uri
27
27
  end
28
28
 
29
- # Set the source for the loaded RDF - by default, sets the prefix as well
29
+ # Set the source for the loaded RDF - by default, sets the URI as well
30
30
  def source=(uri)
31
31
  @source = uri
32
- @prefix ||= uri
32
+ @uri ||= uri
33
33
  end
34
34
 
35
35
  # Set output
@@ -50,10 +50,10 @@ module RDF
50
50
  # Parses arguments, for use in a command line tool
51
51
  def parse_options(argv)
52
52
  opti = OptionParser.new
53
- opti.banner = "Usage: #{File.basename($0)} [options] [prefix [outfile]]\nFetch an RDFS file and produce an RDF::StrictVocabulary with it.\n\n"
53
+ opti.banner = "Usage: #{File.basename($0)} [options] [uri]\nFetch an RDFS file and produce an RDF::StrictVocabulary with it.\n\n"
54
54
 
55
- opti.on("--prefix URI", "The prefix for the fetched RDF vocabulary") do |uri|
56
- self.prefix = uri
55
+ opti.on("--uri URI", "The URI for the fetched RDF vocabulary") do |uri|
56
+ self.uri = uri
57
57
  end
58
58
 
59
59
  opti.on("--source SOURCE", "The source URI or file for the vocabulary") do |uri|
@@ -64,6 +64,10 @@ module RDF
64
64
  self.class_name = name
65
65
  end
66
66
 
67
+ opti.on("--module-name NAME", "The module name for the output StrictVocabulary subclass") do |name|
68
+ self.module_name = name
69
+ end
70
+
67
71
  opti.on("--raw", "Don't output an output file - just the RDF") do
68
72
  @output_class_file = false
69
73
  end
@@ -79,26 +83,7 @@ module RDF
79
83
  raise "Class name (--class-name) is required!"
80
84
  end
81
85
 
82
- if prefix.nil?
83
- self.prefix, outfile, extra = *others
84
- else
85
- outfile, extra = *others
86
- end
87
-
88
- unless outfile.nil?
89
- @output = File.open(outfile, "w")
90
- end
91
-
92
- unless extra.nil?
93
- $stderr.puts "Too many arguments!"
94
- $stderr.puts opti
95
- exit 1
96
- end
97
- end
98
-
99
- # Loads the graph
100
- def graph
101
- @graph ||= RDF::Graph.load(source)
86
+ uri ||= others.first
102
87
  end
103
88
 
104
89
  # Parse command line arguments and run the load-and-emit process
@@ -111,126 +96,77 @@ module RDF
111
96
  end
112
97
  end
113
98
 
114
- # @private
115
- def from_solution(solution)
116
- prefix_match = %r{\A#{@prefix}(.*)}
117
- return if !solution.resource.uri? || (match = prefix_match.match(solution.resource.to_s)).nil?
118
- name = match[1]
119
-
120
- # If there's a label or comment, the must either have no language, or be en
121
- label = solution[:label]
122
- comment = solution[:comment]
123
-
124
- return if label && label.has_language? && !label.language.to_s.start_with?("en")
125
- return if comment && comment.has_language? && !comment.language.to_s.start_with?("en")
126
- label = label.to_s.
127
- encode(Encoding::US_ASCII). # also force exception if invalid
128
- strip.
129
- gsub(/\s+/m, ' ')
130
- comment = comment.to_s.
131
- encode(Encoding::US_ASCII). # also force exception if invalid
132
- strip.
133
- gsub(/\s+/m, ' ').
134
- gsub(/([\(\)])/, '\\\\\\1')
135
-
136
- @output.write " property #{name.to_sym.inspect}"
137
- @output.write ", :label => '#{label}'" unless label.empty?
138
- @output.write ", :comment =>\n %(#{comment.scan(/\S.{0,60}\S(?=\s|$)|\S+/).join("\n ")})" unless comment.empty?
139
- @output.puts
140
- rescue Encoding::UndefinedConversionError
99
+ ##
100
+ # Turn a node definition into a property/term expression
101
+ def from_node(name, attributes, term_type)
102
+ op = term_type == :property ? "property" : "term"
103
+
104
+ components = [" #{op} #{name.to_sym.inspect}"]
105
+ attributes.keys.sort_by(&:to_s).each do |key|
106
+ next if key == :vocab
107
+ value = Array(attributes[key])
108
+ component = key.is_a?(Symbol) ? "#{key}: " : "#{key.inspect} => "
109
+ value = value.first if value.length == 1
110
+ component << if value.is_a?(Array)
111
+ '[' + value.map {|v| serialize_value(v, key)}.join(", ") + "]"
112
+ else
113
+ serialize_value(value, key)
114
+ end
115
+ components << component
116
+ end
117
+ @output.puts components.join(",\n ")
118
+ end
119
+
120
+ def serialize_value(value, key)
121
+ case key
122
+ when :comment, String
123
+ "%(#{value.gsub('(', '\(').gsub(')', '\)')}).freeze"
124
+ else
125
+ "#{value.inspect}.freeze"
126
+ end
141
127
  end
142
128
 
143
129
  # Actually executes the load-and-emit process - useful when using this
144
130
  # class outside of a command line - instantiate, set attributes manually,
145
131
  # then call #run
146
132
  def run
147
- @output.print %(# This file generated automatically using vocab-fetch from #{source}
133
+ @output.print %(# -*- encoding: utf-8 -*-
134
+ # This file generated automatically using vocab-fetch from #{source}
148
135
  require 'rdf'
149
- module RDF
150
- class #{class_name} < #{"Strict" if @strict}Vocabulary("#{prefix}")
136
+ module #{module_name}
137
+ class #{class_name} < RDF::#{"Strict" if @strict}Vocabulary("#{uri}")
151
138
  ).gsub(/^ /, '') if @output_class_file
152
139
 
153
- classes = RDF::Query.new do
154
- pattern [:resource, RDF.type, RDFS.Class]
155
- pattern [:resource, RDFS.label, :label], :optional => true
156
- pattern [:resource, RDFS.comment, :comment], :optional => true
157
- end
158
-
159
- owl_classes = RDF::Query.new do
160
- pattern [:resource, RDF.type, OWL.Class]
161
- pattern [:resource, RDFS.label, :label], :optional => true
162
- pattern [:resource, RDFS.comment, :comment], :optional => true
163
- end
164
-
165
- class_defs = graph.query(classes).to_a + graph.query(owl_classes).to_a
166
- unless class_defs.empty?
167
- @output.puts "\n # Class definitions"
168
- class_defs.sort_by {|s| (s[:label] || s[:resource]).to_s}.each do |klass|
169
- from_solution(klass)
170
- end
171
- end
172
-
173
- properties = RDF::Query.new do
174
- pattern [:resource, RDF.type, RDF.Property]
175
- pattern [:resource, RDFS.label, :label], :optional => true
176
- pattern [:resource, RDFS.comment, :comment], :optional => true
177
- end
178
-
179
- dt_properties = RDF::Query.new do
180
- pattern [:resource, RDF.type, OWL.DatatypeProperty]
181
- pattern [:resource, RDFS.label, :label], :optional => true
182
- pattern [:resource, RDFS.comment, :comment], :optional => true
183
- end
184
-
185
- obj_properties = RDF::Query.new do
186
- pattern [:resource, RDF.type, OWL.ObjectProperty]
187
- pattern [:resource, RDFS.label, :label], :optional => true
188
- pattern [:resource, RDFS.comment, :comment], :optional => true
189
- end
190
-
191
- ann_properties = RDF::Query.new do
192
- pattern [:resource, RDF.type, OWL.AnnotationProperty]
193
- pattern [:resource, RDFS.label, :label], :optional => true
194
- pattern [:resource, RDFS.comment, :comment], :optional => true
195
- end
196
-
197
- ont_properties = RDF::Query.new do
198
- pattern [:resource, RDF.type, OWL.OntologyProperty]
199
- pattern [:resource, RDFS.label, :label], :optional => true
200
- pattern [:resource, RDFS.comment, :comment], :optional => true
201
- end
202
- prop_defs = graph.query(properties).to_a.sort_by {|s| (s[:label] || s[:resource]).to_s}
203
- prop_defs += graph.query(dt_properties).to_a.sort_by {|s| (s[:label] || s[:resource]).to_s}
204
- prop_defs += graph.query(obj_properties).to_a.sort_by {|s| (s[:label] || s[:resource]).to_s}
205
- prop_defs += graph.query(ann_properties).to_a.sort_by {|s| (s[:label] || s[:resource]).to_s}
206
- prop_defs += graph.query(ont_properties).to_a.sort_by {|s| (s[:label] || s[:resource]).to_s}
207
- unless prop_defs.empty?
208
- @output.puts "\n # Property definitions"
209
- prop_defs.each do |prop|
210
- from_solution(prop)
211
- end
212
- end
213
-
214
-
215
- datatypes = RDF::Query.new do
216
- pattern [:resource, RDF.type, RDFS.Datatype]
217
- pattern [:resource, RDFS.label, :label], :optional => true
218
- pattern [:resource, RDFS.comment, :comment], :optional => true
219
- end
220
-
221
- dt_defs = graph.query(datatypes).to_a.sort_by {|s| (s[:label] || s[:resource]).to_s}
222
- unless dt_defs.empty?
223
- @output.puts "\n # Datatype definitions"
224
- dt_defs.each do |dt|
225
- from_solution(dt)
226
- end
227
- end
228
-
229
- unless @extra.empty?
230
- @output.puts "\n # Extra definitions"
231
- @extra.each do |extra|
232
- @output.puts " property #{extra.to_sym.inspect}"
140
+ # Extract statements with subjects that have the vocabulary prefix and organize into a hash of properties and values
141
+ vocab = RDF::Vocabulary.load(uri, location: source, extra: @extra)
142
+
143
+ # Split nodes into Class/Property/Datatype/Other
144
+ term_nodes = {
145
+ class: {},
146
+ property: {},
147
+ datatype: {},
148
+ other: {}
149
+ }
150
+ vocab.each.to_a.sort.each do |term|
151
+ name = term.to_s[uri.length..-1].to_sym
152
+ kind = case term.type.to_s
153
+ when /Class/ then :class
154
+ when /Property/ then :property
155
+ when /Datatype/ then :datatype
156
+ else :other
233
157
  end
158
+ term_nodes[kind][name] = term.attributes
159
+ end
160
+
161
+ {
162
+ class: "Class definitions",
163
+ property: "Property definitions",
164
+ datatype: "Datatype definitions",
165
+ other: "Extra definitions"
166
+ }.each do |tt, comment|
167
+ next if term_nodes[tt].empty?
168
+ @output.puts "\n # #{comment}"
169
+ term_nodes[tt].each {|name, attributes| from_node name, attributes, tt}
234
170
  end
235
171
 
236
172
  # Query the vocabulary to extract property and class definitions
@@ -693,5 +693,30 @@ module RDF
693
693
  super
694
694
  end
695
695
  end
696
+
697
+ ##
698
+ # @private
699
+ # @param [Symbol, #to_sym] method
700
+ # @return [Enumerator]
701
+ # @see Object#enum_for
702
+ def enum_for(method = :each, *args)
703
+ # Ensure that enumerators are, themselves, queryable
704
+ this = self
705
+ Enumerable::Enumerator.new do |yielder|
706
+ this.send(method, *args) {|*y| yielder << (y.length > 1 ? y : y.first)}
707
+ end
708
+ end
709
+ alias_method :to_enum, :enum_for
710
+
711
+ # Extends Enumerator with {Queryable} and {Enumerable}, which is used by {Enumerable#each_statement} and {Queryable#enum_for}
712
+ class Enumerator < ::Enumerator
713
+ include Queryable
714
+ include Enumerable
715
+
716
+ # Make sure returned arrays are also queryable
717
+ def to_a
718
+ return super.to_a.extend(RDF::Queryable, RDF::Enumerable)
719
+ end
720
+ end
696
721
  end # Enumerable
697
722
  end # RDF
@@ -33,6 +33,9 @@ module RDF
33
33
  #
34
34
  # @param [String, #to_s] filename
35
35
  # @param [Hash{Symbol => Object}] options
36
+ # Options from {RDF::Reader.open}
37
+ # @option options [RDF::Resource] :context
38
+ # Set set context of each loaded statement
36
39
  # @return [void]
37
40
  def load(filename, options = {})
38
41
  raise TypeError.new("#{self} is immutable") if immutable?
@@ -71,7 +71,7 @@ module RDF
71
71
  #
72
72
  # @param [String, #to_s] url
73
73
  # @param [Hash{Symbol => Object}] options
74
- # Options from {RDF::Reader#initialize}, {RDF::Format.for} and {RDF::Graph#initialize}
74
+ # Options from {RDF::Graph#initialize} and {RDF::Mutable#load}
75
75
  # @yield [graph]
76
76
  # @yieldparam [Graph] graph
77
77
  # @return [Graph]
@@ -12,6 +12,21 @@ module RDF
12
12
  class Node
13
13
  include RDF::Resource
14
14
 
15
+ ##
16
+ # Defines the maximum number of interned Node references that can be held
17
+ # cached in memory at any one time.
18
+ #
19
+ # Note that caching interned nodes means that two different invocations using the same symbol will result in the same node, which may not be appropriate depending on the context from which it is used. RDF requires that bnodes with the same label are, in fact, different bnodes, unless they are used wihin the same document.
20
+ CACHE_SIZE = -1 # unlimited by default
21
+
22
+ ##
23
+ # @return [RDF::Util::Cache]
24
+ # @private
25
+ def self.cache
26
+ require 'rdf/util/cache' unless defined?(::RDF::Util::Cache)
27
+ @cache ||= RDF::Util::Cache.new(CACHE_SIZE)
28
+ end
29
+
15
30
  ##
16
31
  # Returns a blank node with a random UUID-based identifier.
17
32
  #
@@ -41,7 +56,7 @@ module RDF
41
56
  # @return [RDF::Node]
42
57
  # @since 0.2.0
43
58
  def self.intern(id)
44
- self.new(id)
59
+ (cache[id = id.to_s] ||= self.new(id)).freeze
45
60
  end
46
61
 
47
62
  ##
@@ -140,13 +155,21 @@ module RDF
140
155
  alias_method :===, :==
141
156
 
142
157
  ##
143
- # Returns the base representation of this URI.
158
+ # Returns the base representation of this node.
144
159
  #
145
160
  # @return [Sring]
146
161
  def to_base
147
162
  to_s
148
163
  end
149
164
 
165
+ ##
166
+ # Returns a representation of this node independent of any identifier used to initialize it
167
+ #
168
+ # @return [String]
169
+ def to_unique_base
170
+ "_:g#{__id__.to_i.abs}"
171
+ end
172
+
150
173
  ##
151
174
  # Returns a string representation of this blank node.
152
175
  #