Class: RDF::Writer Abstract

Inherits:
Object
  • Object
show all
Extended by:
Enumerable, Util::Aliasing::LateBound
Includes:
Writable
Defined in:
lib/rdf/writer.rb

Overview

This class is abstract.

The base class for RDF serializers.

Examples:

Loading an RDF writer implementation

require 'rdf/ntriples'

Iterating over known RDF writer classes

RDF::Writer.each { |klass| puts klass.name }

Obtaining an RDF writer class

RDF::Writer.for(:ntriples)     #=> RDF::NTriples::Writer
RDF::Writer.for("spec/data/output.nt")
RDF::Writer.for(:file_name      => "spec/data/output.nt")
RDF::Writer.for(:file_extension => "nt")
RDF::Writer.for(:content_type   => "text/plain")

Instantiating an RDF writer class

RDF::Writer.for(:ntriples).new($stdout) { |writer| ... }

Serializing RDF statements into a file

RDF::Writer.open("spec/data/output.nt") do |writer|
  graph.each_statement do |statement|
    writer << statement
  end
end

Serializing RDF statements into a string

RDF::Writer.for(:ntriples).buffer do |writer|
  graph.each_statement do |statement|
    writer << statement
  end
end

See Also:

Direct Known Subclasses

NTriples::Writer

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Util::Aliasing::LateBound

alias_method

Methods included from Writable

#<<, #insert, #insert_graph, #insert_reader, #insert_statements, #writable?

Constructor Details

#initialize(output = $stdout, options = {}) {|writer| ... } ⇒ Writer

Initializes the writer.

Options Hash (options):

  • :encoding (Encoding, String, Symbol)

    the encoding to use on the output stream. Defaults to the format associated with content_encoding.

  • :canonicalize (Boolean) — default: false

    whether to canonicalize terms when serializing

  • :validate (Boolean) — default: false

    whether to validate terms when serializing

  • :prefixes (Hash) — default: Hash.new

    the prefix mappings to use (not supported by all writers)

  • :base_uri (#to_s) — default: nil

    the base URI to use when constructing relative URIs (not supported by all writers)

  • :unique_bnodes (Boolean) — default: false

    Use unique Node identifiers, defaults to using the identifier which the node was originall initialized with (if any). Implementations should ensure that Nodes are serialized using a unique representation independent of any identifier used when creating the node. See NTriples#format_node

Yields:

  • (writer)

    self

Yield Parameters:

Yield Returns:

  • (void)


216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/rdf/writer.rb', line 216

def initialize(output = $stdout, options = {}, &block)
  @output, @options = output, options.dup
  @nodes, @node_id  = {}, 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

#optionsHash (readonly)

Any additional options for this writer.

Since:

  • 0.2.2



235
236
237
# File 'lib/rdf/writer.rb', line 235

def options
  @options
end

Class Method Details

.buffer(*args) {|writer| ... } ⇒ String

Buffers output into a string buffer.

Yields:

  • (writer)

Yield Parameters:

Yield Returns:

  • (void)

Raises:

  • (ArgumentError)

    if no block is provided



146
147
148
149
150
151
152
153
154
155
156
# File 'lib/rdf/writer.rb', line 146

def self.buffer(*args, &block)
  options = args.last.is_a?(Hash) ? args.last : {}
  options[:encoding] ||= Encoding::UTF_8 if RUBY_PLATFORM == "java"
  raise ArgumentError, "block expected" unless block_given?

  StringIO.open do |buffer|
    buffer.set_encoding(options[:encoding]) if options[:encoding]
    self.new(buffer, *args) { |writer| block.call(writer) }
    buffer.string
  end
end

.dump(data, io = nil, options = {})



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/rdf/writer.rb', line 114

def self.dump(data, io = nil, options = {})
  if io.is_a?(String)
    io = File.open(io, 'w')
  elsif io.respond_to?(:external_encoding) && io.external_encoding
    options = {:encoding => io.external_encoding}.merge(options)
  end
  io.set_encoding(options[:encoding]) if io.respond_to?(:set_encoding) && options[:encoding]
  method = data.respond_to?(:each_statement) ? :each_statement : :each
  if io
    new(io, options) do |writer|
      data.send(method) do |statement|
        writer << statement
      end
      writer.flush
    end
  else
    buffer(options) do |writer|
      data.send(method) do |statement|
        writer << statement
      end
    end
  end
end

.each {|klass| ... } ⇒ Enumerator

Enumerates known RDF writer classes.

Yields:

  • (klass)

Yield Parameters:

  • klass (Class)

Yield Returns:

  • (void)

    ignored



51
52
53
# File 'lib/rdf/writer.rb', line 51

def self.each(&block)
  @@subclasses.each(&block)
end

.for(format) ⇒ Class .for(filename) ⇒ Class .for(options = {}) ⇒ Class

Finds an RDF writer class based on the given criteria.

Overloads:

  • .for(format) ⇒ Class

    Finds an RDF writer class based on a symbolic name.

  • .for(filename) ⇒ Class

    Finds an RDF writer class based on a file name.

  • .for(options = {}) ⇒ Class

    Finds an RDF writer class based on various options.

    Options Hash (options):

    • :file_name (String, #to_s) — default: nil
    • :file_extension (Symbol, #to_sym) — default: nil
    • :content_type (String, #to_s) — default: nil


80
81
82
83
84
85
# File 'lib/rdf/writer.rb', line 80

def self.for(options = {})
  options = options.merge(:has_writer => true) if options.is_a?(Hash)
  if format = self.format || Format.for(options)
    format.writer
  end
end

.format(klass = nil) ⇒ Class Also known as: format_class

Retrieves the RDF serialization format class for this writer class.



91
92
93
94
95
96
97
98
99
100
# File 'lib/rdf/writer.rb', line 91

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, options = {}, &block) ⇒ RDF::Writer

Writes output to the given filename.

Options Hash (options):

  • :format (Symbol) — default: nil


166
167
168
169
170
171
172
173
# File 'lib/rdf/writer.rb', line 166

def self.open(filename, options = {}, &block)
  File.open(filename, 'wb') do |file|
    file.set_encoding(options[:encoding]) if options[:encoding]
    format_options = options.dup
    format_options[:file_name] ||= filename
    self.for(options[:format] || format_options).new(file, options, &block)
  end
end

.to_symSymbol

Returns a symbol appropriate to use with RDF::Writer.for()



178
179
180
181
182
183
# File 'lib/rdf/writer.rb', line 178

def self.to_sym
  elements = self.to_s.split("::")
  sym = elements.pop
  sym = elements.pop if sym == 'Writer'
  sym.downcase.to_s.to_sym
end

Instance Method Details

#base_uriRDF::URI

Returns the base URI used for this writer.

Examples:

writer.prefixes[:dc]  #=> RDF::URI('http://purl.org/dc/terms/')

Since:

  • 0.3.4



245
246
247
# File 'lib/rdf/writer.rb', line 245

def base_uri
  RDF::URI(@options[:base_uri]) if @options[:base_uri]
end

#canonicalize?Boolean

Returns true if terms should be canonicalized.

Since:

  • 1.0.8



328
329
330
# File 'lib/rdf/writer.rb', line 328

def canonicalize?
  @options[:canonicalize]
end

#encodingEncoding

Returns the encoding of the output stream.



303
304
305
306
307
308
309
310
311
312
# File 'lib/rdf/writer.rb', line 303

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)



508
509
510
511
512
513
514
515
516
# File 'lib/rdf/writer.rb', line 508

def escaped(string)
  string.gsub('\\', '\\\\\\\\').
         gsub("\b", '\\b').
         gsub("\f", '\\f').
         gsub("\t", '\\t').
         gsub("\n", '\\n').
         gsub("\r", '\\r').
         gsub('"', '\\"')
end

#flush Also known as: flush!

This method returns an undefined value.

Flushes the underlying output buffer.



336
337
338
339
# File 'lib/rdf/writer.rb', line 336

def flush
  @output.flush if @output.respond_to?(:flush)
  self
end

#format_list(value, options = {}) ⇒ String

This method is abstract.

Since:

  • 0.2.3



473
474
475
# File 'lib/rdf/writer.rb', line 473

def format_list(value, options = {})
  format_term(value.subject, options)
end

#format_literal(value, options = {}) ⇒ String

This method is abstract.

Raises:

  • (NotImplementedError)

    unless implemented in subclass



463
464
465
# File 'lib/rdf/writer.rb', line 463

def format_literal(value, options = {})
  raise NotImplementedError.new("#{self.class}#format_literal") # override in subclasses
end

#format_node(value, options = {}) ⇒ String

This method is abstract.

Options Hash (options):

  • :unique_bnodes (Boolean) — default: false

    Serialize node using unique identifier, rather than any used to create the node.

Raises:

  • (NotImplementedError)

    unless implemented in subclass



443
444
445
# File 'lib/rdf/writer.rb', line 443

def format_node(value, options = {})
  raise NotImplementedError.new("#{self.class}#format_node") # override in subclasses
end

#format_term(term, options = {}) ⇒ String Also known as: format_value

Since:

  • 0.3.0



423
424
425
426
427
428
429
430
431
432
# File 'lib/rdf/writer.rb', line 423

def format_term(term, options = {})
  case term
    when String       then format_literal(RDF::Literal(term, options), options)
    when RDF::List    then format_list(term, options)
    when RDF::Literal then format_literal(term, options)
    when RDF::URI     then format_uri(term, options)
    when RDF::Node    then format_node(term, options)
    else nil
  end
end

#format_uri(value, options = {}) ⇒ String

This method is abstract.

Raises:

  • (NotImplementedError)

    unless implemented in subclass



453
454
455
# File 'lib/rdf/writer.rb', line 453

def format_uri(value, options = {})
  raise NotImplementedError.new("#{self.class}#format_uri") # override in subclasses
end

#node_idString (protected)



501
502
503
# File 'lib/rdf/writer.rb', line 501

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.

Examples:

Defining a URI prefix

writer.prefix :dc, RDF::URI('http://purl.org/dc/terms/')

Returning a URI prefix

writer.prefix(:dc)    #=> RDF::URI('http://purl.org/dc/terms/')


293
294
295
296
# File 'lib/rdf/writer.rb', line 293

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

#prefixesHash{Symbol => RDF::URI}

Returns the URI prefixes currently defined for this writer.

Examples:

writer.prefixes[:dc]  #=> RDF::URI('http://purl.org/dc/terms/')

Since:

  • 0.2.2



257
258
259
# File 'lib/rdf/writer.rb', line 257

def prefixes
  @options[:prefixes] ||= {}
end

#prefixes=(prefixes) ⇒ Hash{Symbol => RDF::URI}

Defines the given URI prefixes for this writer.

Examples:

writer.prefixes = {
  :dc => RDF::URI('http://purl.org/dc/terms/'),
}

Since:

  • 0.3.0



272
273
274
# File 'lib/rdf/writer.rb', line 272

def prefixes=(prefixes)
  @options[:prefixes] = prefixes
end

#puts(*args) (protected)



481
482
483
# File 'lib/rdf/writer.rb', line 481

def puts(*args)
  @output.puts(*args.map {|s| s.encode(encoding)})
end

#quoted(string) ⇒ String (protected)



521
522
523
# File 'lib/rdf/writer.rb', line 521

def quoted(string)
  "\"#{string}\""
end

#to_symSymbol

Returns a symbol appropriate to use with RDF::Writer.for()



188
189
190
# File 'lib/rdf/writer.rb', line 188

def to_sym
  self.class.to_sym
end

#uri_for(uriref) ⇒ String (protected)



488
489
490
491
492
493
494
495
496
497
# File 'lib/rdf/writer.rb', line 488

def uri_for(uriref)
  case
    when uriref.is_a?(RDF::Node)
      @nodes[uriref]
    when uriref.respond_to?(:to_uri)
      uriref.to_uri.to_s
    else
      uriref.to_s
  end
end

#validate?Boolean

Returns true if statements and terms should be validated.

Since:

  • 1.0.8



319
320
321
# File 'lib/rdf/writer.rb', line 319

def validate?
  @options[:validate]
end

#write_comment(text)

This method is abstract.

This method returns an undefined value.

Returns self



360
361
362
# File 'lib/rdf/writer.rb', line 360

def write_comment(text)
  self
end

#write_epilogue

This method is abstract.

This method returns an undefined value.

Returns self



352
353
354
# File 'lib/rdf/writer.rb', line 352

def write_epilogue
  self
end

#write_graph(graph)

Deprecated.

Please use RDF::Writable#insert_graph instead

This method returns an undefined value.

Returns self



368
369
370
371
372
# File 'lib/rdf/writer.rb', line 368

def write_graph(graph)
  warn "[DEPRECATION] `Writer#graph_write is deprecated. Please use RDF::Writable#insert instead."
  graph.each_triple { |*triple| write_triple(*triple) }
  self
end

#write_prologue

This method is abstract.

This method returns an undefined value.

Returns self



345
346
347
# File 'lib/rdf/writer.rb', line 345

def write_prologue
  self
end

#write_statement(statement) Also known as: insert_statement

This method returns an undefined value.

Returns self

Raises:

  • (RDF::WriterError)

    if validating and attempting to write an invalid Statement or if canonicalizing a statement which cannot be canonicalized.



388
389
390
391
392
393
394
395
# File 'lib/rdf/writer.rb', line 388

def write_statement(statement)
  statement = statement.canonicalize! if canonicalize?
  raise RDF::WriterError, "Statement #{statement.inspect} is invalid" if validate? && statement.invalid?
  write_triple(*statement.to_triple)
  self
rescue ArgumentError => e
  raise WriterError, e.message
end

#write_statements(*statements)

Deprecated.

replace by RDF::Writable#insert

This method returns an undefined value.

Returns self



378
379
380
381
382
# File 'lib/rdf/writer.rb', line 378

def write_statements(*statements)
  warn "[DEPRECATION] `Writer#write_statements is deprecated. Please use RDF::Writable#insert instead."
  statements.each { |statement| write_statement(statement) }
  self
end

#write_triple(subject, predicate, object)

This method is abstract.

This method returns an undefined value.

Returns self

Raises:

  • (NotImplementedError)

    unless implemented in subclass

  • (RDF::WriterError)

    if validating and attempting to write an invalid Term.



415
416
417
# File 'lib/rdf/writer.rb', line 415

def write_triple(subject, predicate, object)
  raise NotImplementedError.new("#{self.class}#write_triple") # override in subclasses
end

#write_triples(*triples)

This method returns an undefined value.

Returns self

Raises:



402
403
404
405
# File 'lib/rdf/writer.rb', line 402

def write_triples(*triples)
  triples.each { |triple| write_triple(*triple) }
  self
end