Class: RDF::Writer Abstract
- Inherits:
-
Object
- Object
- RDF::Writer
- Extended by:
- Enumerable, Util::Aliasing::LateBound
- Includes:
- Util::Logger, Writable
- Defined in:
- lib/rdf/writer.rb
Overview
The base class for RDF serializers.
Direct Known Subclasses
Constant Summary
Constants included from Util::Logger
Instance Attribute Summary collapse
-
#options ⇒ Hash
readonly
Any additional options for this writer.
Class Method Summary collapse
-
.accept?(accept_params) {|accept_params| ... } ⇒ Boolean
Use parameters from accept-params to determine if the parameters are acceptable to invoke this writer.
-
.buffer(*args, **options) {|writer| ... } ⇒ String
Buffers output into a string buffer.
- .dump(data, io = nil, **options)
-
.each {|klass| ... } ⇒ Enumerator
Enumerates known RDF writer classes.
-
.for(*arg, &block) ⇒ Class
Finds an RDF writer class based on the given criteria.
-
.format(klass = nil) ⇒ Class
(also: format_class)
Retrieves the RDF serialization format class for this writer class.
-
.open(filename, format: nil, **options, &block) ⇒ RDF::Writer
Writes output to the given
filename
. -
.options ⇒ Array<RDF::CLI::Option>
Options suitable for automatic Writer provisioning.
-
.to_sym ⇒ Symbol
Returns a symbol appropriate to use with RDF::Writer.for().
Instance Method Summary collapse
-
#base_uri ⇒ RDF::URI
Returns the base URI used for this writer.
-
#canonicalize? ⇒ Boolean
Returns
true
if terms should be in canonical form. -
#encoding ⇒ Encoding
Returns the encoding of the output stream.
- #escaped(string) ⇒ String protected
-
#flush ⇒ self
(also: #flush!)
Flushes the underlying output buffer.
- #format_list(value, **options) ⇒ String abstract
- #format_literal(value, **options) ⇒ String abstract
- #format_node(value, **options) ⇒ String abstract
-
#format_quotedTriple(value, **options) ⇒ String
abstract
Formats a referenced triple.
- #format_term(term, **options) ⇒ String
- #format_uri(value, **options) ⇒ String abstract
-
#initialize(output = $stdout, **options) {|writer| ... } ⇒ Writer
constructor
Initializes the writer.
- #node_id ⇒ String protected
-
#prefix(name, uri = nil) ⇒ RDF::URI
(also: #prefix!)
Defines the given named URI prefix for this writer.
-
#prefixes ⇒ Hash{Symbol => RDF::URI}
Returns the URI prefixes currently defined for this writer.
-
#prefixes=(prefixes) ⇒ Hash{Symbol => RDF::URI}
Defines the given URI prefixes for this writer.
- #puts(*args) protected
- #quoted(string) ⇒ String protected
-
#to_sym ⇒ Symbol
Returns a symbol appropriate to use with RDF::Writer.for().
- #uri_for(term) ⇒ String protected
-
#validate? ⇒ Boolean
Returns
true
if statements and terms should be validated. - #write_comment(text) ⇒ self abstract
- #write_epilogue ⇒ self abstract
- #write_prologue ⇒ self abstract
-
#write_statement(statement) ⇒ self
(also: #insert_statement)
Add a statement to the writer.
- #write_triple(subject, predicate, object) ⇒ self abstract
- #write_triples(*triples) ⇒ self
Methods included from Util::Aliasing::LateBound
Methods included from Writable
#<<, #insert, #insert_graph, #insert_reader, #insert_statements, #writable?
Methods included from Util::Coercions
Methods included from Util::Logger
#log_debug, #log_depth, #log_error, #log_fatal, #log_info, #log_recover, #log_recovering?, #log_statistics, #log_warn, #logger
Constructor Details
#initialize(output = $stdout, **options) {|writer| ... } ⇒ Writer
Initializes the writer.
287 288 289 290 291 292 293 294 295 296 297 298 299 |
# File 'lib/rdf/writer.rb', line 287 def initialize(output = $stdout, **, &block) @output, @options = output, .dup @nodes, @node_id, @node_id_map = {}, 0, {} if block_given? write_prologue case block.arity when 1 then block.call(self) else instance_eval(&block) end write_epilogue end end |
Instance Attribute Details
#options ⇒ Hash (readonly)
Any additional options for this writer.
306 307 308 |
# File 'lib/rdf/writer.rb', line 306 def @options end |
Class Method Details
.accept?(accept_params) {|accept_params| ... } ⇒ Boolean
Use parameters from accept-params to determine if the parameters are acceptable to invoke this writer. The accept_params
will subsequently be provided to the writer instance.
173 174 175 |
# File 'lib/rdf/writer.rb', line 173 def accept?(accept_params) block_given? ? yield(accept_params) : true end |
.buffer(*args, **options) {|writer| ... } ⇒ String
Buffers output into a string buffer.
216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/rdf/writer.rb', line 216 def self.buffer(*args, **, &block) raise ArgumentError, "block expected" unless block_given? StringIO.open do |buffer| self.new(buffer, *args, **) do |writer| buffer.set_encoding(writer.encoding) block.call(writer) end buffer.string end end |
.dump(data, io = nil, **options)
This method returns an undefined value.
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/rdf/writer.rb', line 186 def self.dump(data, io = nil, **) io = File.open(io, 'w') if io.is_a?(String) method = data.respond_to?(:each_statement) ? :each_statement : :each if io new(io, **) do |writer| io.set_encoding(writer.encoding) if io.respond_to?(:set_encoding) data.send(method) do |statement| writer << statement end writer.flush end else buffer(**) do |writer| data.send(method) do |statement| writer << statement end end end end |
.each {|klass| ... } ⇒ Enumerator
Enumerates known RDF writer classes.
63 64 65 |
# File 'lib/rdf/writer.rb', line 63 def self.each(&block) RDF::Format.map(&:writer).reject(&:nil?).each(&block) end |
.for(format) ⇒ Class .for(filename) ⇒ Class .for(options = {}) ⇒ Class
Finds an RDF writer class based on the given criteria.
92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/rdf/writer.rb', line 92 def self.for(*arg, &block) case arg.length when 0 then arg = nil when 1 then arg = arg.first else raise ArgumentError, "Format.for accepts zero or one argument, got #{arg.length}." end arg = arg.merge(has_writer: true) if arg.is_a?(Hash) if format = self.format || Format.for(arg) format.writer end end |
.format(klass = nil) ⇒ Class Also known as: format_class
Retrieves the RDF serialization format class for this writer class.
109 110 111 112 113 114 115 116 117 118 |
# File 'lib/rdf/writer.rb', line 109 def self.format(klass = nil) if klass.nil? Format.each do |format| if format.writer == self return format end end nil # not found end end |
.open(filename, format: nil, **options, &block) ⇒ RDF::Writer
Writes output to the given filename
.
236 237 238 239 240 241 242 243 244 245 |
# File 'lib/rdf/writer.rb', line 236 def self.open(filename, format: nil, **, &block) File.open(filename, 'wb') do |file| = .dup [:file_name] ||= filename self.for(format || ).new(file, **) do |writer| file.set_encoding(writer.encoding) block.call(writer) end end end |
.options ⇒ Array<RDF::CLI::Option>
Options suitable for automatic Writer provisioning.
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/rdf/writer.rb', line 123 def self. [ RDF::CLI::Option.new( symbol: :canonicalize, datatype: TrueClass, control: :checkbox, on: ["--canonicalize"], description: "Canonicalize input/output.") {true}, RDF::CLI::Option.new( symbol: :encoding, datatype: Encoding, control: :text, on: ["--encoding ENCODING"], description: "The encoding of the input stream.") {|arg| Encoding.find arg}, RDF::CLI::Option.new( symbol: :prefixes, datatype: Hash, multiple: true, control: :none, on: ["--prefixes PREFIX,PREFIX"], description: "A comma-separated list of prefix:uri pairs.") do |arg| arg.split(',').inject({}) do |memo, pfxuri| pfx,uri = pfxuri.split(':', 2) memo.merge(pfx.to_sym => RDF::URI(uri)) end end, RDF::CLI::Option.new( symbol: :unique_bnodes, datatype: TrueClass, control: :checkbox, on: ["--unique-bnodes"], description: "Use unique Node identifiers.") {true}, ] end |
.to_sym ⇒ Symbol
Returns a symbol appropriate to use with RDF::Writer.for()
250 251 252 |
# File 'lib/rdf/writer.rb', line 250 def self.to_sym self.format.to_sym end |
Instance Method Details
#base_uri ⇒ RDF::URI
Returns the base URI used for this writer.
316 317 318 |
# File 'lib/rdf/writer.rb', line 316 def base_uri RDF::URI(@options[:base_uri]) if @options[:base_uri] end |
#canonicalize? ⇒ Boolean
This is for term canonicalization, for graph/dataset canonicalization use RDF::Normalize
.
Returns true
if terms should be in canonical form.
401 402 403 |
# File 'lib/rdf/writer.rb', line 401 def canonicalize? @options[:canonicalize] end |
#encoding ⇒ Encoding
Returns the encoding of the output stream.
374 375 376 377 378 379 380 381 382 383 |
# File 'lib/rdf/writer.rb', line 374 def encoding case @options[:encoding] when String, Symbol Encoding.find(@options[:encoding].to_s) when Encoding @options[:encoding] else @options[:encoding] ||= Encoding.find(self.class.format.content_encoding.to_s) end end |
#escaped(string) ⇒ String (protected)
614 615 616 617 618 619 620 621 622 |
# File 'lib/rdf/writer.rb', line 614 def escaped(string) string.gsub('\\', '\\\\\\\\'). gsub("\b", '\\b'). gsub("\f", '\\f'). gsub("\t", '\\t'). gsub("\n", '\\n'). gsub("\r", '\\r'). gsub('"', '\\"') end |
#flush ⇒ self Also known as: flush!
Flushes the underlying output buffer.
409 410 411 412 |
# File 'lib/rdf/writer.rb', line 409 def flush @output.flush if @output.respond_to?(:flush) self end |
#format_list(value, **options) ⇒ String
564 565 566 |
# File 'lib/rdf/writer.rb', line 564 def format_list(value, **) format_term(value.subject, **) end |
#format_literal(value, **options) ⇒ String
554 555 556 |
# File 'lib/rdf/writer.rb', line 554 def format_literal(value, **) raise NotImplementedError.new("#{self.class}#format_literal") # override in subclasses end |
#format_node(value, **options) ⇒ String
534 535 536 |
# File 'lib/rdf/writer.rb', line 534 def format_node(value, **) raise NotImplementedError.new("#{self.class}#format_node") # override in subclasses end |
#format_quotedTriple(value, **options) ⇒ String
Formats a referenced triple.
579 580 581 |
# File 'lib/rdf/writer.rb', line 579 def format_quotedTriple(value, **) raise NotImplementedError.new("#{self.class}#format_statement") # override in subclasses end |
#format_term(term, **options) ⇒ String
514 515 516 517 518 519 520 521 522 523 524 |
# File 'lib/rdf/writer.rb', line 514 def format_term(term, **) case term when String then format_literal(RDF::Literal(term, **), **) when RDF::List then format_list(term, **) when RDF::Literal then format_literal(term, **) when RDF::URI then format_uri(term, **) when RDF::Node then format_node(term, **) when RDF::Statement then format_quotedTriple(term, **) else nil end end |
#format_uri(value, **options) ⇒ String
544 545 546 |
# File 'lib/rdf/writer.rb', line 544 def format_uri(value, **) raise NotImplementedError.new("#{self.class}#format_uri") # override in subclasses end |
#node_id ⇒ String (protected)
607 608 609 |
# File 'lib/rdf/writer.rb', line 607 def node_id "_:n#{@node_id += 1}" end |
#prefix(name, uri) ⇒ RDF::URI #prefix(name) ⇒ RDF::URI Also known as: prefix!
Defines the given named URI prefix for this writer.
364 365 366 367 |
# File 'lib/rdf/writer.rb', line 364 def prefix(name, uri = nil) name = name.to_s.empty? ? nil : (name.respond_to?(:to_sym) ? name.to_sym : name.to_s.to_sym) uri.nil? ? prefixes[name] : prefixes[name] = uri end |
#prefixes ⇒ Hash{Symbol => RDF::URI}
Returns the URI prefixes currently defined for this writer.
328 329 330 |
# File 'lib/rdf/writer.rb', line 328 def prefixes @options[:prefixes] ||= {} end |
#prefixes=(prefixes) ⇒ Hash{Symbol => RDF::URI}
Defines the given URI prefixes for this writer.
343 344 345 |
# File 'lib/rdf/writer.rb', line 343 def prefixes=(prefixes) @options[:prefixes] = prefixes end |
#puts(*args) (protected)
This method returns an undefined value.
587 588 589 |
# File 'lib/rdf/writer.rb', line 587 def puts(*args) @output.puts(*args.map {|s| s.encode(encoding)}) end |
#quoted(string) ⇒ String (protected)
627 628 629 |
# File 'lib/rdf/writer.rb', line 627 def quoted(string) "\"#{string}\"" end |
#to_sym ⇒ Symbol
Returns a symbol appropriate to use with RDF::Writer.for()
257 258 259 |
# File 'lib/rdf/writer.rb', line 257 def to_sym self.class.to_sym end |
#uri_for(term) ⇒ String (protected)
594 595 596 597 598 599 600 601 602 603 |
# File 'lib/rdf/writer.rb', line 594 def uri_for(term) case when term.is_a?(RDF::Node) @nodes[term] ||= term.to_base when term.respond_to?(:to_uri) term.to_uri.to_s else term.to_s end end |
#validate? ⇒ Boolean
Returns true
if statements and terms should be validated.
390 391 392 |
# File 'lib/rdf/writer.rb', line 390 def validate? @options[:validate] end |
#write_comment(text) ⇒ self
438 439 440 |
# File 'lib/rdf/writer.rb', line 438 def write_comment(text) self end |
#write_epilogue ⇒ self
427 428 429 430 431 432 |
# File 'lib/rdf/writer.rb', line 427 def write_epilogue if log_statistics[:error].to_i > @logged_errors_at_prolog raise RDF::WriterError, "Errors found during processing" end self end |
#write_prologue ⇒ self
418 419 420 421 |
# File 'lib/rdf/writer.rb', line 418 def write_prologue @logged_errors_at_prolog = log_statistics[:error].to_i self end |
#write_statement(statement) ⇒ self Also known as: insert_statement
logs error if attempting to write an invalid Statement or if canonicalizing a statement which cannot be canonicalized.
Add a statement to the writer. This will check to ensure that the statement is complete (no nil terms) and is valid, if the :validation
option is set.
Additionally, it will de-duplicate BNode terms sharing a common identifier.
450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 |
# File 'lib/rdf/writer.rb', line 450 def write_statement(statement) statement = statement.canonicalize! if canonicalize? # Make sure BNodes in statement use unique identifiers if statement.node? statement.to_quad.map do |term| if term.is_a?(RDF::Node) term = term.original while term.original @nodes[term] ||= begin # Account for duplicated nodes @node_id_map[term.to_s] ||= term if !@node_id_map[term.to_s].equal?(term) # Rename node term.make_unique! @node_id_map[term.to_s] = term end end else term end end statement = RDF::Statement.from(statement.to_quad) end if statement.incomplete? log_error "Statement #{statement.inspect} is incomplete" elsif validate? && statement.invalid? log_error "Statement #{statement.inspect} is invalid" elsif respond_to?(:write_quad) write_quad(*statement.to_quad) else write_triple(*statement.to_triple) end self rescue ArgumentError => e log_error e. end |
#write_triple(subject, predicate, object) ⇒ self
logs error if attempting to write an invalid Statement or if canonicalizing a statement which cannot be canonicalized.
506 507 508 |
# File 'lib/rdf/writer.rb', line 506 def write_triple(subject, predicate, object) raise NotImplementedError.new("#{self.class}#write_triple") # override in subclasses end |
#write_triples(*triples) ⇒ self
logs error if attempting to write an invalid Statement or if canonicalizing a statement which cannot be canonicalized.
493 494 495 496 |
# File 'lib/rdf/writer.rb', line 493 def write_triples(*triples) triples.each { |triple| write_triple(*triple) } self end |