openlogic-rdf 0.3.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.
Files changed (80) hide show
  1. data/AUTHORS +3 -0
  2. data/CREDITS +9 -0
  3. data/README +361 -0
  4. data/UNLICENSE +24 -0
  5. data/VERSION +1 -0
  6. data/bin/rdf +18 -0
  7. data/etc/doap.nt +62 -0
  8. data/lib/df.rb +1 -0
  9. data/lib/rdf/cli.rb +200 -0
  10. data/lib/rdf/format.rb +383 -0
  11. data/lib/rdf/mixin/countable.rb +39 -0
  12. data/lib/rdf/mixin/durable.rb +31 -0
  13. data/lib/rdf/mixin/enumerable.rb +637 -0
  14. data/lib/rdf/mixin/indexable.rb +26 -0
  15. data/lib/rdf/mixin/inferable.rb +5 -0
  16. data/lib/rdf/mixin/mutable.rb +191 -0
  17. data/lib/rdf/mixin/queryable.rb +265 -0
  18. data/lib/rdf/mixin/readable.rb +15 -0
  19. data/lib/rdf/mixin/type_check.rb +21 -0
  20. data/lib/rdf/mixin/writable.rb +152 -0
  21. data/lib/rdf/model/graph.rb +263 -0
  22. data/lib/rdf/model/list.rb +731 -0
  23. data/lib/rdf/model/literal/boolean.rb +121 -0
  24. data/lib/rdf/model/literal/date.rb +73 -0
  25. data/lib/rdf/model/literal/datetime.rb +72 -0
  26. data/lib/rdf/model/literal/decimal.rb +86 -0
  27. data/lib/rdf/model/literal/double.rb +189 -0
  28. data/lib/rdf/model/literal/integer.rb +126 -0
  29. data/lib/rdf/model/literal/numeric.rb +184 -0
  30. data/lib/rdf/model/literal/time.rb +87 -0
  31. data/lib/rdf/model/literal/token.rb +47 -0
  32. data/lib/rdf/model/literal/xml.rb +39 -0
  33. data/lib/rdf/model/literal.rb +373 -0
  34. data/lib/rdf/model/node.rb +156 -0
  35. data/lib/rdf/model/resource.rb +28 -0
  36. data/lib/rdf/model/statement.rb +296 -0
  37. data/lib/rdf/model/term.rb +77 -0
  38. data/lib/rdf/model/uri.rb +570 -0
  39. data/lib/rdf/model/value.rb +133 -0
  40. data/lib/rdf/nquads.rb +152 -0
  41. data/lib/rdf/ntriples/format.rb +48 -0
  42. data/lib/rdf/ntriples/reader.rb +239 -0
  43. data/lib/rdf/ntriples/writer.rb +219 -0
  44. data/lib/rdf/ntriples.rb +104 -0
  45. data/lib/rdf/query/pattern.rb +329 -0
  46. data/lib/rdf/query/solution.rb +252 -0
  47. data/lib/rdf/query/solutions.rb +237 -0
  48. data/lib/rdf/query/variable.rb +221 -0
  49. data/lib/rdf/query.rb +404 -0
  50. data/lib/rdf/reader.rb +511 -0
  51. data/lib/rdf/repository.rb +389 -0
  52. data/lib/rdf/transaction.rb +161 -0
  53. data/lib/rdf/util/aliasing.rb +63 -0
  54. data/lib/rdf/util/cache.rb +139 -0
  55. data/lib/rdf/util/file.rb +38 -0
  56. data/lib/rdf/util/uuid.rb +36 -0
  57. data/lib/rdf/util.rb +6 -0
  58. data/lib/rdf/version.rb +19 -0
  59. data/lib/rdf/vocab/cc.rb +18 -0
  60. data/lib/rdf/vocab/cert.rb +13 -0
  61. data/lib/rdf/vocab/dc.rb +63 -0
  62. data/lib/rdf/vocab/dc11.rb +23 -0
  63. data/lib/rdf/vocab/doap.rb +45 -0
  64. data/lib/rdf/vocab/exif.rb +168 -0
  65. data/lib/rdf/vocab/foaf.rb +69 -0
  66. data/lib/rdf/vocab/geo.rb +13 -0
  67. data/lib/rdf/vocab/http.rb +26 -0
  68. data/lib/rdf/vocab/owl.rb +59 -0
  69. data/lib/rdf/vocab/rdfs.rb +17 -0
  70. data/lib/rdf/vocab/rsa.rb +12 -0
  71. data/lib/rdf/vocab/rss.rb +14 -0
  72. data/lib/rdf/vocab/sioc.rb +93 -0
  73. data/lib/rdf/vocab/skos.rb +36 -0
  74. data/lib/rdf/vocab/wot.rb +21 -0
  75. data/lib/rdf/vocab/xhtml.rb +9 -0
  76. data/lib/rdf/vocab/xsd.rb +58 -0
  77. data/lib/rdf/vocab.rb +215 -0
  78. data/lib/rdf/writer.rb +475 -0
  79. data/lib/rdf.rb +192 -0
  80. metadata +173 -0
data/lib/rdf/cli.rb ADDED
@@ -0,0 +1,200 @@
1
+ require 'rdf'
2
+ require 'rdf/ntriples'
3
+ require 'rdf/nquads'
4
+ require 'optparse'
5
+ begin
6
+ gem 'linkeddata'
7
+ require 'linkeddata'
8
+ rescue LoadError
9
+ # Silently load without linkeddata
10
+ end
11
+
12
+ class OptionParser
13
+ def options; @options || {}; end
14
+ def options=(value); @options = value; end
15
+ end
16
+
17
+ module RDF
18
+ class CLI
19
+
20
+ COMMANDS = {
21
+ "count" => lambda do |argv, opts|
22
+ start = Time.new
23
+ count = 0
24
+ self.parse(argv, opts) do |reader|
25
+ reader.each_statement do |statement|
26
+ count += 1
27
+ end
28
+ end
29
+ secs = Time.new - start
30
+ $stdout.puts "Parsed #{count} statements with #{@readers.join(', ')} in #{secs} seconds @ #{count/secs} statements/second."
31
+ end,
32
+ "lenghts" => lambda do |argv, opts|
33
+ self.parse(argv, opts) do |reader|
34
+ reader.each_statement do |statement|
35
+ $stdout.puts statement.to_s.size
36
+ end
37
+ end
38
+ end,
39
+ "objects" => lambda do |argv, opts|
40
+ self.parse(argv, opts) do |reader|
41
+ reader.each_statement do |statement|
42
+ $stdout.puts statement.object.to_ntriples
43
+ end
44
+ end
45
+ end,
46
+ "predicates" => lambda do |argv, opts|
47
+ self.parse(argv, opts) do |reader|
48
+ reader.each_statement do |statement|
49
+ $stdout.puts statement.predicate.to_ntriples
50
+ end
51
+ end
52
+ end,
53
+ "serialize" => lambda do |argv, opts|
54
+ writer_class = RDF::Writer.for(opts[:output_format]) || RDF::NTriples::Writer
55
+ out = opts[:output] || $stdout
56
+ opts = opts.merge(:prefixes => {})
57
+ writer_opts = opts.merge(:standard_prefixes => true)
58
+ self.parse(argv, opts) do |reader|
59
+ writer_class.new(out, writer_opts) do |writer|
60
+ writer << reader
61
+ end
62
+ end
63
+ end,
64
+ "subjects" => lambda do |argv, opts|
65
+ self.parse(argv, opts) do |reader|
66
+ reader.each_statement do |statement|
67
+ $stdout.puts statement.subject.to_ntriples
68
+ end
69
+ end
70
+ end
71
+ }
72
+
73
+ ##
74
+ # @return [String]
75
+ def self.basename() File.basename($0) end
76
+
77
+ ##
78
+ # @yield [options]
79
+ # @yieldparam [OptionParser]
80
+ # @return [OptionParser]
81
+ def self.options(&block)
82
+ options = OptionParser.new
83
+ opts = options.options = {
84
+ :base_uri => nil,
85
+ :canonicalize => false,
86
+ :debug => false,
87
+ :evaluate => nil,
88
+ :format => nil,
89
+ :output => $stdout,
90
+ :output_format => :ntriples,
91
+ :validate => false,
92
+ }
93
+
94
+ # Command-specific options
95
+ if block_given?
96
+ case block.arity
97
+ when 1 then block.call(options)
98
+ else options.instance_eval(&block)
99
+ end
100
+ end
101
+ options.banner ||= "Usage: #{self.basename} [options] command [args...]"
102
+
103
+ options.on('--canonicalize', 'Canonicalize input.') do
104
+ opts[:canonicalize] = true
105
+ end
106
+
107
+ options.on('-d', '--debug', 'Enable debug output for troubleshooting.') do
108
+ opts[:debug] = $DEBUG = true
109
+ end
110
+
111
+ options.on("-e", "--evaluate STRING", "Evaluate argument as RDF input, if no files are specified") do |arg|
112
+ opts[:evaluate] = arg
113
+ end
114
+
115
+ options.on("--input-format FORMAT", "Format of input file, uses heuristic if not specified") do |arg|
116
+ opts[:format] = arg.downcase.to_sym
117
+ end
118
+
119
+ options.on("-o", "--output FILE", "File to write output, defaults to STDOUT") do |arg|
120
+ opts[:output] = File.open(arg, "w")
121
+ end
122
+
123
+ options.on("--output-format FORMAT", "Format of output file, defaults to NTriples") do |arg|
124
+ opts[:output_format] = arg.downcase.to_sym
125
+ end
126
+
127
+ options.on('--uri URI', 'Base URI of input file, defaults to the filename.') do |arg|
128
+ opts[:base_uri] = arg
129
+ end
130
+
131
+ options.on('--validate', 'Validate input file.') do
132
+ opts[:validate] = true
133
+ end
134
+
135
+ options.on_tail("-h", "--help", "Show this message") do
136
+ $stdout.puts options
137
+ $stdout.puts "Available commands:\n\t#{self.commands.join("\n\t")}"
138
+ exit
139
+ end
140
+
141
+ begin
142
+ options.parse!
143
+ rescue OptionParser::InvalidOption => e
144
+ abort e
145
+ end
146
+
147
+ options
148
+ end
149
+
150
+ ##
151
+ # @param [String] command
152
+ # @param [Array<String>] args
153
+ # @return [Boolean]
154
+ def self.exec_command(command, args, options = {})
155
+ unless COMMANDS.has_key?(command)
156
+ abort "#{File.basename($0)}: unknown command `#{command}'"
157
+ end
158
+
159
+ COMMANDS[command].call(args, options)
160
+ end
161
+
162
+ ##
163
+ # @return [Array<String>] list of executable commands
164
+ def self.commands
165
+ COMMANDS.keys
166
+ end
167
+
168
+ ##
169
+ # Parse each file, STDIN or specified string in options[:evaluate] yielding
170
+ # a reader
171
+ #
172
+ # @param [Array<String>] files
173
+ # @yield [reader]
174
+ # @yieldparam [RDF::Reader]
175
+ # @return [nil]
176
+ def self.parse(files, options = {}, &block)
177
+ if files.empty?
178
+ # If files are empty, either use options[:execute]
179
+ input = options[:evaluate] ? StringIO.new(options[:evaluate]) : STDIN
180
+ RDF::Reader.for(options[:format] || :ntriples).new(input, options) do |reader|
181
+ yield(reader)
182
+ end
183
+ else
184
+ files.each do |file|
185
+ RDF::Reader.open(file, options) do |reader|
186
+ (@readers ||= []) << reader.class.to_s
187
+ yield(reader)
188
+ end
189
+ end
190
+ end
191
+ end
192
+
193
+ ##
194
+ # @param [String] msg
195
+ # @return [void]
196
+ def self.abort(msg)
197
+ Kernel.abort "#{basename}: #{msg}"
198
+ end
199
+ end
200
+ end
data/lib/rdf/format.rb ADDED
@@ -0,0 +1,383 @@
1
+ module RDF
2
+ ##
3
+ # The base class for RDF serialization formats.
4
+ #
5
+ # @example Loading an RDF serialization format implementation
6
+ # require 'rdf/ntriples'
7
+ #
8
+ # @example Iterating over known RDF serialization formats
9
+ # RDF::Format.each { |klass| puts klass.name }
10
+ #
11
+ # @example Getting a serialization format class
12
+ # RDF::Format.for(:ntriples) #=> RDF::NTriples::Format
13
+ # RDF::Format.for("etc/doap.nt")
14
+ # RDF::Format.for(:file_name => "etc/doap.nt")
15
+ # RDF::Format.for(:file_extension => "nt")
16
+ # RDF::Format.for(:content_type => "text/plain")
17
+ #
18
+ # @example Obtaining serialization format MIME types
19
+ # RDF::Format.content_types #=> {"text/plain" => [RDF::NTriples::Format]}
20
+ #
21
+ # @example Obtaining serialization format file extension mappings
22
+ # RDF::Format.file_extensions #=> {:nt => [RDF::NTriples::Format]}
23
+ #
24
+ # @example Defining a new RDF serialization format class
25
+ # class RDF::NTriples::Format < RDF::Format
26
+ # content_type 'text/plain', :extension => :nt
27
+ # content_encoding 'ascii'
28
+ #
29
+ # reader RDF::NTriples::Reader
30
+ # writer RDF::NTriples::Writer
31
+ # end
32
+ #
33
+ # @example Instantiating an RDF reader or writer class (1)
34
+ # RDF::Format.for(:ntriples).reader.new($stdin) { |reader| ... }
35
+ # RDF::Format.for(:ntriples).writer.new($stdout) { |writer| ... }
36
+ #
37
+ # @example Instantiating an RDF reader or writer class (2)
38
+ # RDF::Reader.for(:ntriples).new($stdin) { |reader| ... }
39
+ # RDF::Writer.for(:ntriples).new($stdout) { |writer| ... }
40
+ #
41
+ # @abstract
42
+ # @see RDF::Reader
43
+ # @see RDF::Writer
44
+ # @see http://en.wikipedia.org/wiki/Resource_Description_Framework#Serialization_formats
45
+ class Format
46
+ extend ::Enumerable
47
+
48
+ ##
49
+ # Enumerates known RDF serialization format classes.
50
+ #
51
+ # @yield [klass]
52
+ # @yieldparam [Class]
53
+ # @return [Enumerator]
54
+ def self.each(&block)
55
+ @@subclasses.each(&block)
56
+ end
57
+
58
+ ##
59
+ # Finds an RDF serialization format class based on the given criteria.
60
+ #
61
+ # @overload for(format)
62
+ # Finds an RDF serialization format class based on a symbolic name.
63
+ #
64
+ # @param [Symbol] format
65
+ # @return [Class]
66
+ #
67
+ # @overload for(filename)
68
+ # Finds an RDF serialization format class based on a file name.
69
+ #
70
+ # @param [String] filename
71
+ # @return [Class]
72
+ #
73
+ # @overload for(options = {})
74
+ # Finds an RDF serialization format class based on various options.
75
+ #
76
+ # @param [Hash{Symbol => Object}] options
77
+ # @option options [String, #to_s] :file_name (nil)
78
+ # @option options [Symbol, #to_sym] :file_extension (nil)
79
+ # @option options [String, #to_s] :content_type (nil)
80
+ # Note that content_type will be taken from a URL opened using {RDF::Util::File.open_file}.
81
+ # @option options [Boolean] :has_reader (false)
82
+ # Only return a format having a reader.
83
+ # @option options [Boolean] :has_writer (false)
84
+ # Only return a format having a writer.
85
+ # @option options [String] :sample (nil)
86
+ # A sample of input used for performing format detection.
87
+ # If we find no formats, or we find more than one, and we have a sample, we can
88
+ # perform format detection to find a specific format to use, in which case
89
+ # we pick the first one we find
90
+ # @return [Class]
91
+ # @yieldreturn [String] another way to provide a sample, allows lazy for retrieving the sample.
92
+ #
93
+ # @return [Class]
94
+ def self.for(options = {})
95
+ format = case options
96
+ when String
97
+ # Find a format based on the file name
98
+ self.for(:file_name => options)
99
+
100
+ when Hash
101
+ case
102
+ # Find a format based on the MIME content type:
103
+ when mime_type = options[:content_type]
104
+ # @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.17
105
+ # @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7
106
+ mime_type = mime_type.to_s
107
+ mime_type = mime_type.split(';').first # remove any media type parameters
108
+ content_types[mime_type]
109
+ # Find a format based on the file name:
110
+ when file_name = options[:file_name]
111
+ self.for(:file_extension => File.extname(file_name.to_s)[1..-1])
112
+ # Find a format based on the file extension:
113
+ when file_ext = options[:file_extension]
114
+ file_extensions[file_ext.to_sym]
115
+ end
116
+
117
+ when Symbol
118
+ case format = options
119
+ # Special case, since we want this to work despite autoloading
120
+ when :ntriples
121
+ RDF::NTriples::Format
122
+ # For anything else, find a match based on the full class name
123
+ else
124
+ @@subclasses.detect { |klass| klass.to_sym == format }
125
+ end
126
+ end
127
+
128
+ if format.is_a?(Array)
129
+ format = format.select {|f| f.reader} if options[:has_reader]
130
+ format = format.select {|f| f.writer} if options[:has_writer]
131
+
132
+ return format.first if format.uniq.length == 1
133
+ elsif !format.nil?
134
+ return format
135
+ end
136
+
137
+ # If we have a sample, use that for format detection
138
+ if sample = (options[:sample] if options.is_a?(Hash)) || (yield if block_given?)
139
+ # Given a sample, perform format detection across the appropriate formats, choosing
140
+ # the first that matches
141
+ format ||= @@subclasses
142
+
143
+ # Return first format that has a positive detection
144
+ format.detect {|f| f.detect(sample)} || format.first
145
+ elsif format.is_a?(Array)
146
+ # Otherwise, just return the first matching format
147
+ format.first
148
+ else
149
+ nil
150
+ end
151
+ end
152
+
153
+ ##
154
+ # Returns MIME content types for known RDF serialization formats.
155
+ #
156
+ # @return [Hash{String => Array<Class>}]
157
+ def self.content_types
158
+ @@content_types
159
+ end
160
+
161
+ ##
162
+ # Returns file extensions for known RDF serialization formats.
163
+ #
164
+ # @return [Hash{Symbol => Array<Class>}]
165
+ def self.file_extensions
166
+ @@file_extensions
167
+ end
168
+
169
+ ##
170
+ # Returns a symbol appropriate to use with RDF::Format.for()
171
+ # @return [Symbol]
172
+ def self.to_sym
173
+ elements = self.to_s.split("::")
174
+ sym = elements.pop
175
+ sym = elements.pop if sym == 'Format'
176
+ sym.downcase.to_s.to_sym
177
+ end
178
+
179
+ ##
180
+ # Retrieves or defines the reader class for this RDF serialization
181
+ # format.
182
+ #
183
+ # @overload reader(klass)
184
+ # Defines the reader class for this RDF serialization format.
185
+ #
186
+ # The class should be a subclass of {RDF::Reader}, or implement the
187
+ # same interface.
188
+ #
189
+ # @param [Class] klass
190
+ # @return [void]
191
+ #
192
+ # @overload reader
193
+ # Defines the reader class for this RDF serialization format.
194
+ #
195
+ # The block should return a subclass of {RDF::Reader}, or a class that
196
+ # implements the same interface. The block won't be invoked until the
197
+ # reader class is first needed.
198
+ #
199
+ # @yield
200
+ # @yieldreturn [Class] klass
201
+ # @return [void]
202
+ #
203
+ # @overload reader
204
+ # Retrieves the reader class for this RDF serialization format.
205
+ #
206
+ # @return [Class]
207
+ #
208
+ # @return [void]
209
+ def self.reader(klass = nil, &block)
210
+ case
211
+ when klass
212
+ @@readers[self] = klass
213
+ when block_given?
214
+ @@readers[self] = block
215
+ else
216
+ klass = @@readers[self]
217
+ klass = @@readers[self] = klass.call if klass.is_a?(Proc)
218
+ klass
219
+ end
220
+ end
221
+
222
+ ##
223
+ # Retrieves or defines the writer class for this RDF serialization
224
+ # format.
225
+ #
226
+ # @overload writer(klass)
227
+ # Defines the writer class for this RDF serialization format.
228
+ #
229
+ # The class should be a subclass of {RDF::Writer}, or implement the
230
+ # same interface.
231
+ #
232
+ # @param [Class] klass
233
+ # @return [void]
234
+ #
235
+ # @overload writer
236
+ # Defines the writer class for this RDF serialization format.
237
+ #
238
+ # The block should return a subclass of {RDF::Writer}, or a class that
239
+ # implements the same interface. The block won't be invoked until the
240
+ # writer class is first needed.
241
+ #
242
+ # @yield
243
+ # @yieldreturn [Class] klass
244
+ # @return [void]
245
+ #
246
+ # @overload writer
247
+ # Retrieves the writer class for this RDF serialization format.
248
+ #
249
+ # @return [Class]
250
+ #
251
+ # @return [void]
252
+ def self.writer(klass = nil, &block)
253
+ case
254
+ when klass
255
+ @@writers[self] = klass
256
+ when block_given?
257
+ @@writers[self] = block
258
+ else
259
+ klass = @@writers[self]
260
+ klass = @@writers[self] = klass.call if klass.is_a?(Proc)
261
+ klass
262
+ end
263
+ end
264
+
265
+
266
+ ##
267
+ # Use a text sample to detect the format of an input file. Sub-classes implement
268
+ # a matcher sufficient to detect probably format matches, including disambiguating
269
+ # between other similar formats.
270
+ #
271
+ # Used to determine format class from loaded formats by {RDF::Format.for} when a
272
+ # match cannot be unambigiously found otherwise.
273
+ #
274
+ # @example
275
+ # RDF::NTriples::Format.detect("<a> <b> <c> .") => true
276
+ #
277
+ # @param [String] sample Beginning several bytes (~ 1K) of input.
278
+ # @return [Boolean]
279
+ def self.detect(sample)
280
+ false
281
+ end
282
+
283
+ class << self
284
+ alias_method :reader_class, :reader
285
+ alias_method :writer_class, :writer
286
+ end
287
+
288
+ ##
289
+ # Retrieves or defines MIME content types for this RDF serialization format.
290
+ #
291
+ # @overload content_type(type, options)
292
+ # Retrieves or defines the MIME content type for this RDF serialization format.
293
+ #
294
+ # Optionally also defines alias MIME content types for this RDF serialization format.
295
+ #
296
+ # Optionally also defines a file extension, or a list of file
297
+ # extensions, that should be mapped to the given MIME type and handled
298
+ # by this class.
299
+ #
300
+ # @param [String] type
301
+ # @param [Hash{Symbol => Object}] options
302
+ # @option options [String] :alias (nil)
303
+ # @option options [Array<String>] :aliases (nil)
304
+ # @option options [Symbol] :extension (nil)
305
+ # @option options [Array<Symbol>] :extensions (nil)
306
+ # @return [void]
307
+ #
308
+ # @overload content_type
309
+ # Retrieves the MIME content types for this RDF serialization format.
310
+ #
311
+ # The return is an array where the first element is the cannonical
312
+ # MIME type for the format and following elements are alias MIME types.
313
+ #
314
+ # @return [Array<String>]
315
+ def self.content_type(type = nil, options = {})
316
+ if type.nil?
317
+ [@@content_type[self], @@content_types.map {
318
+ |ct, cl| (cl.include?(self) && ct != @@content_type[self]) ? ct : nil }].flatten.compact
319
+ else
320
+ @@content_type[self] = type
321
+ (@@content_types[type] ||= []) << self
322
+
323
+ if extensions = (options[:extension] || options[:extensions])
324
+ extensions = [extensions].flatten.map(&:to_sym)
325
+ extensions.each { |ext| (@@file_extensions[ext] ||= []) << self }
326
+ end
327
+ if aliases = (options[:alias] || options[:aliases])
328
+ aliases = [aliases].flatten.each { |a| (@@content_types[a] ||= []) << self }
329
+ end
330
+ end
331
+ end
332
+
333
+ protected
334
+
335
+ ##
336
+ # Defines a required Ruby library for this RDF serialization format.
337
+ #
338
+ # The given library will be required lazily, i.e. only when it is
339
+ # actually first needed, such as when instantiating a reader or parser
340
+ # instance for this format.
341
+ #
342
+ # @param [String, #to_s] library
343
+ # @return [void]
344
+ def self.require(library)
345
+ (@@requires[self] ||= []) << library.to_s
346
+ end
347
+
348
+ ##
349
+ # Defines the content encoding for this RDF serialization format.
350
+ #
351
+ # @param [#to_sym] encoding
352
+ # @return [void]
353
+ def self.content_encoding(encoding)
354
+ @@content_encoding[self] = encoding.to_sym
355
+ end
356
+
357
+ private
358
+
359
+ private_class_method :new
360
+
361
+ @@requires = {} # @private
362
+ @@file_extensions = {} # @private
363
+ @@content_type = {} # @private
364
+ @@content_types = {} # @private
365
+ @@content_encoding = {} # @private
366
+ @@readers = {} # @private
367
+ @@writers = {} # @private
368
+ @@subclasses = [] # @private
369
+
370
+ ##
371
+ # @private
372
+ # @return [void]
373
+ def self.inherited(child)
374
+ @@subclasses << child
375
+ super
376
+ end
377
+ end # Format
378
+
379
+ ##
380
+ # The base class for RDF serialization format errors.
381
+ class FormatError < IOError
382
+ end # FormatError
383
+ end # RDF
@@ -0,0 +1,39 @@
1
+ module RDF
2
+ ##
3
+ # @since 0.2.0
4
+ module Countable
5
+ extend RDF::Util::Aliasing::LateBound
6
+
7
+ ##
8
+ # Returns `true` if `self` contains no RDF statements.
9
+ #
10
+ # @return [Boolean]
11
+ def empty?
12
+ empty = true
13
+ each { empty = false; break }
14
+ empty
15
+ end
16
+
17
+ ##
18
+ # Returns the number of RDF statements in `self`.
19
+ #
20
+ # @return [Integer]
21
+ def count
22
+ count = 0
23
+ each { count += 1 }
24
+ count
25
+ end
26
+ alias_method :size, :count
27
+
28
+ ##
29
+ # @private
30
+ # @param [Symbol, #to_sym] method
31
+ # @return [Enumerator]
32
+ # @see Object#enum_for
33
+ def enum_for(method = :each, *args)
34
+ # Ensure that enumerators support the `#empty?` and `#count` methods:
35
+ super.extend(RDF::Countable)
36
+ end
37
+ alias_method :to_enum, :enum_for
38
+ end # Countable
39
+ end # RDF
@@ -0,0 +1,31 @@
1
+ module RDF
2
+ ##
3
+ module Durable
4
+ extend RDF::Util::Aliasing::LateBound
5
+
6
+ ##
7
+ # Returns `true` if `self` is durable.
8
+ #
9
+ # @return [Boolean]
10
+ # @see #nondurable?
11
+ def durable?
12
+ true
13
+ end
14
+
15
+ alias_method :persistent?, :durable?
16
+
17
+ ##
18
+ # Returns `true` if `self` is nondurable.
19
+ #
20
+ # @return [Boolean]
21
+ # @see #durable?
22
+ def nondurable?
23
+ !durable?
24
+ end
25
+
26
+ alias_method :ephemeral?, :nondurable?
27
+ alias_method :nonpersistent?, :nondurable?
28
+ alias_method :transient?, :nondurable?
29
+ alias_method :volatile?, :nondurable?
30
+ end
31
+ end