openlogic-rdf 0.3.6

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