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_term(term, **options) ⇒ String
-
#format_tripleTerm(value, **options) ⇒ String
abstract
Formats a referenced triple term.
- #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. -
#version ⇒ String
Returns the RDF version determined by this reader.
- #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.
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 |
# File 'lib/rdf/writer.rb', line 295 def initialize(output = $stdout, **, &block) @output, @options = output, .dup @nodes, @node_id, @node_id_map = {}, 0, {} # The rdfstar option implies version 1.2, but can be overridden @options[:version] ||= "1.2" if @options[:rdfstar] unless self.version.nil? || RDF::Format::VERSIONS.include?(self.version) log_warn("Expected version to be one of #{RDF::Format::VERSIONS.join(', ')}, was #{self.version}") end 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.
321 322 323 |
# File 'lib/rdf/writer.rb', line 321 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.
179 180 181 |
# File 'lib/rdf/writer.rb', line 179 def accept?(accept_params) block_given? ? yield(accept_params) : true end |
.buffer(*args, **options) {|writer| ... } ⇒ String
Buffers output into a string buffer.
222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/rdf/writer.rb', line 222 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.
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 |
# File 'lib/rdf/writer.rb', line 192 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
.
242 243 244 245 246 247 248 249 250 251 |
# File 'lib/rdf/writer.rb', line 242 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 157 158 159 160 161 162 |
# 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}, RDF::CLI::Option.new( symbol: :version, control: :select, datatype: RDF::Format::VERSIONS, # 1.1, 1.2, or 1.2-basic on: ["--version VERSION"], description: "RDF Version."), ] end |
.to_sym ⇒ Symbol
Returns a symbol appropriate to use with RDF::Writer.for()
256 257 258 |
# File 'lib/rdf/writer.rb', line 256 def self.to_sym self.format.to_sym end |
Instance Method Details
#base_uri ⇒ RDF::URI
Returns the base URI used for this writer.
331 332 333 |
# File 'lib/rdf/writer.rb', line 331 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.
416 417 418 |
# File 'lib/rdf/writer.rb', line 416 def canonicalize? @options[:canonicalize] end |
#encoding ⇒ Encoding
Returns the encoding of the output stream.
389 390 391 392 393 394 395 396 397 398 |
# File 'lib/rdf/writer.rb', line 389 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)
641 642 643 644 645 646 647 648 649 |
# File 'lib/rdf/writer.rb', line 641 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.
424 425 426 427 |
# File 'lib/rdf/writer.rb', line 424 def flush @output.flush if @output.respond_to?(:flush) self end |
#format_list(value, **options) ⇒ String
591 592 593 |
# File 'lib/rdf/writer.rb', line 591 def format_list(value, **) format_term(value.subject, **) end |
#format_literal(value, **options) ⇒ String
581 582 583 |
# File 'lib/rdf/writer.rb', line 581 def format_literal(value, **) raise NotImplementedError.new("#{self.class}#format_literal") # override in subclasses end |
#format_node(value, **options) ⇒ String
561 562 563 |
# File 'lib/rdf/writer.rb', line 561 def format_node(value, **) raise NotImplementedError.new("#{self.class}#format_node") # override in subclasses end |
#format_term(term, **options) ⇒ String
541 542 543 544 545 546 547 548 549 550 551 |
# File 'lib/rdf/writer.rb', line 541 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_tripleTerm(term, **) else nil end end |
#format_tripleTerm(value, **options) ⇒ String
Formats a referenced triple term.
606 607 608 |
# File 'lib/rdf/writer.rb', line 606 def format_tripleTerm(value, **) raise NotImplementedError.new("#{self.class}#format_tripleTerm") # override in subclasses end |
#format_uri(value, **options) ⇒ String
571 572 573 |
# File 'lib/rdf/writer.rb', line 571 def format_uri(value, **) raise NotImplementedError.new("#{self.class}#format_uri") # override in subclasses end |
#node_id ⇒ String (protected)
634 635 636 |
# File 'lib/rdf/writer.rb', line 634 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.
379 380 381 382 |
# File 'lib/rdf/writer.rb', line 379 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.
343 344 345 |
# File 'lib/rdf/writer.rb', line 343 def prefixes @options[:prefixes] ||= {} end |
#prefixes=(prefixes) ⇒ Hash{Symbol => RDF::URI}
Defines the given URI prefixes for this writer.
358 359 360 |
# File 'lib/rdf/writer.rb', line 358 def prefixes=(prefixes) @options[:prefixes] = prefixes end |
#puts(*args) (protected)
This method returns an undefined value.
614 615 616 |
# File 'lib/rdf/writer.rb', line 614 def puts(*args) @output.puts(*args.map {|s| s.encode(encoding)}) end |
#quoted(string) ⇒ String (protected)
654 655 656 |
# File 'lib/rdf/writer.rb', line 654 def quoted(string) "\"#{string}\"" end |
#to_sym ⇒ Symbol
Returns a symbol appropriate to use with RDF::Writer.for()
263 264 265 |
# File 'lib/rdf/writer.rb', line 263 def to_sym self.class.to_sym end |
#uri_for(term) ⇒ String (protected)
621 622 623 624 625 626 627 628 629 630 |
# File 'lib/rdf/writer.rb', line 621 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.
405 406 407 |
# File 'lib/rdf/writer.rb', line 405 def validate? @options[:validate] end |
#version ⇒ String
Returns the RDF version determined by this reader.
438 439 440 |
# File 'lib/rdf/writer.rb', line 438 def version @options[:version] end |
#write_comment(text) ⇒ self
465 466 467 |
# File 'lib/rdf/writer.rb', line 465 def write_comment(text) self end |
#write_epilogue ⇒ self
454 455 456 457 458 459 |
# File 'lib/rdf/writer.rb', line 454 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
445 446 447 448 |
# File 'lib/rdf/writer.rb', line 445 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.
477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 |
# File 'lib/rdf/writer.rb', line 477 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. + " at #{e.backtrace.first}" 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.
533 534 535 |
# File 'lib/rdf/writer.rb', line 533 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.
520 521 522 523 |
# File 'lib/rdf/writer.rb', line 520 def write_triples(*triples) triples.each { |triple| write_triple(*triple) } self end |