Class: RDF::Vocabulary

Inherits:
Object
  • Object
show all
Extended by:
Enumerable
Defined in:
lib/rdf/vocabulary.rb,
lib/rdf/vocab/writer.rb

Overview

Vocabulary format specification. This can be used to generate a Ruby class definition from a loaded vocabulary.

Direct Known Subclasses

StrictVocabulary, XSD

Defined Under Namespace

Classes: Format, Term, Writer

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(uri) ⇒ Vocabulary



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

def initialize(uri)
  @uri = case uri
    when RDF::URI then uri.to_s
    else RDF::URI.parse(uri.to_s) ? uri.to_s : nil
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(property, *args, &block) ⇒ Object (protected)



438
439
440
441
442
443
444
445
446
447
# File 'lib/rdf/vocabulary.rb', line 438

def method_missing(property, *args, &block)
  property = self.class.camelize(property.to_s)
  if %w(to_ary).include?(property.to_s)
    super
  elsif args.empty?
    self[property]
  else
    super
  end
end

Class Method Details

.[](property) ⇒ RDF::URI

Returns the URI for the term ‘property` in this vocabulary.



189
190
191
192
193
194
195
# File 'lib/rdf/vocabulary.rb', line 189

def [](property)
  if props.has_key?(property.to_sym)
    props[property.to_sym]
  else
    Term.intern([to_s, property.to_s].join(''), attributes: {vocab: self})
  end
end

.__prefix__Symbol

Returns a suggested CURIE/PName prefix for this vocabulary class.

Since:

  • 0.3.0



348
349
350
# File 'lib/rdf/vocabulary.rb', line 348

def __prefix__
  __name__.split('::').last.downcase.to_sym
end

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

Enumerates known RDF vocabulary classes.

Yields:

  • (klass)

Yield Parameters:

  • klass (Class)


70
71
72
73
74
75
76
77
78
79
80
# File 'lib/rdf/vocabulary.rb', line 70

def each(&block)
  if self.equal?(Vocabulary)
    # This is needed since all vocabulary classes are defined using
    # Ruby's autoloading facility, meaning that `@@subclasses` will be
    # empty until each subclass has been touched or require'd.
    RDF::VOCABS.each { |v| require "rdf/vocab/#{v}" unless v == :rdf }
    @@subclasses.select(&:name).each(&block)
  else
    __properties__.each(&block)
  end
end

.each_statement {|| ... } ⇒ Object

Enumerate each statement constructed from the defined vocabulary terms

If a property value is known to be a URI, or expands to a URI, the ‘object` is a URI, otherwise, it will be a Literal.

Yields:

  • statement

Yield Parameters:



251
252
253
254
255
# File 'lib/rdf/vocabulary.rb', line 251

def each_statement(&block)
  props.each do |name, subject|
    subject.each_statement(&block)
  end
end

.enum_for(method = :each_statement, *args) ⇒ RDF::Enumerable::Enumerator Also known as: to_enum

Return an enumerator over Statement defined for this vocabulary.

See Also:

  • Object#enum_for


235
236
237
238
239
240
241
# File 'lib/rdf/vocabulary.rb', line 235

def enum_for(method = :each_statement, *args)
  # Ensure that enumerators are, themselves, queryable
  this = self
  Enumerable::Enumerator.new do |yielder|
    this.send(method, *args) {|*y| yielder << (y.length > 1 ? y : y.first)}
  end
end

.expand_pname(pname) ⇒ RDF::URI

Attempt to expand a Compact IRI/PName/QName using loaded vocabularies

Raises:

  • (KeyError)

    if pname suffix not found in identified vocabulary



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

def expand_pname(pname)
  prefix, suffix = pname.to_s.split(":", 2)
  if prefix == "rdf"
    RDF[suffix]
  elsif vocab = RDF::Vocabulary.each.detect {|v| v.__name__ && v.__prefix__ == prefix.to_sym}
    suffix.to_s.empty? ? vocab.to_uri : vocab[suffix]
  else
    RDF::Vocabulary.find_term(pname) || RDF::URI(pname)
  end
end

.find(uri) ⇒ Vocabulary

Return the Vocabulary associated with a URI. Allows the trailing ‘/’ or ‘#’ to be excluded



162
163
164
165
166
167
168
169
170
# File 'lib/rdf/vocabulary.rb', line 162

def find(uri)
  RDF::Vocabulary.detect do |v|
    if uri.length >= v.to_uri.length
      RDF::URI(uri).start_with?(v.to_uri)
    else
      v.to_uri.to_s.sub(%r([/#]$), '') == uri.to_s
    end
  end
end

.find_term(uri) ⇒ Vocabulary::Term

Return the Vocabulary term associated with a URI



177
178
179
180
181
182
# File 'lib/rdf/vocabulary.rb', line 177

def find_term(uri)
  uri = RDF::URI(uri)
  return uri if uri.is_a?(Vocabulary::Term)
  vocab = RDF::Vocabulary.detect {|v| uri.start_with?(v.to_uri)}
  vocab[uri.to_s[vocab.to_uri.to_s.length..-1]] if vocab
end

.from_graph(graph, url: nil, class_name: nil, extra: nil) ⇒ RDF::Vocabulary

Create a vocabulary from a graph or enumerable



275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
# File 'lib/rdf/vocabulary.rb', line 275

def from_graph(graph, url: nil, class_name: nil, extra: nil)
  vocab = if class_name
    Object.const_set(class_name, Class.new(self.create(url)))
  else
    Class.new(self.create(url))
  end

  term_defs = {}
  graph.each do |statement|
    next unless statement.subject.uri? && statement.subject.start_with?(url)
    name = statement.subject.to_s[url.to_s.length..-1] 
    term = (term_defs[name.to_sym] ||= {})
    key = case statement.predicate
    when RDF.type                                     then :type
    when RDF::RDFS.subClassOf                         then :subClassOf
    when RDF::RDFS.subPropertyOf                      then :subPropertyOf
    when RDF::RDFS.range                              then :range
    when RDF::RDFS.domain                             then :domain
    when RDF::RDFS.comment                            then :comment
    when RDF::RDFS.label                              then :label
    when RDF::URI("http://schema.org/inverseOf")      then :inverseOf
    when RDF::URI("http://schema.org/domainIncludes") then :domainIncludes
    when RDF::URI("http://schema.org/rangeIncludes")  then :rangeIncludes
    else                                              statement.predicate.pname
    end

    value = if statement.object.uri?
      statement.object.pname
    elsif statement.object.literal? && (statement.object.language || :en).to_s =~ /^en-?/
      statement.object.to_s
    end

    (term[key] ||= []) << value if value
  end

  # Create extra terms
  term_defs = case extra
  when Array
    extra.inject({}) {|memo, s| memo[s.to_sym] = {label: s.to_s}; memo}.merge(term_defs)
  when Hash
    extra.merge(term_defs)
  else
    term_defs
  end

  term_defs.each do |term, attributes|
    vocab.__property__ term, attributes
  end

  vocab
end

.imported_fromArray<RDF::Vocabulary>

List of vocabularies which import this vocabulary



214
215
216
217
218
# File 'lib/rdf/vocabulary.rb', line 214

def imported_from
  @imported_from ||= begin
    RDF::Vocabulary.select {|v| v.__imports__.include?(self)}
  end
end

.importsArray<RDF::Vocabulary> Also known as: __imports__

Note:

the alias __imports__ guards against ‘RDF::OWL.imports` returning a term, rather than an array of vocabularies

List of vocabularies this vocabulary ‘owl:imports`



202
203
204
205
206
207
208
# File 'lib/rdf/vocabulary.rb', line 202

def imports
  @imports ||= begin
    Array(self[""].attributes[:"owl:imports"]).map {|pn|find(expand_pname(pn)) rescue nil}.compact
  rescue KeyError
    []
  end
end

.inspectString

Returns a developer-friendly representation of this vocabulary class.



331
332
333
334
335
336
337
# File 'lib/rdf/vocabulary.rb', line 331

def inspect
  if self == Vocabulary
    self.to_s
  else
    sprintf("%s(%s)", superclass.to_s, to_s)
  end
end

.propertiesObject Also known as: __properties__

@return [Array<RDF::URI>] a list of properties in the current vocabulary



135
136
137
# File 'lib/rdf/vocabulary.rb', line 135

def properties
  props.values
end

.propertyRDF::Vocabulary::Term .property(name, options) ⇒ RDF::Vocabulary::Term Also known as: term, __property__

Overloads:

  • .propertyRDF::Vocabulary::Term

    Returns ‘property` in the current vocabulary

  • .property(name, options) ⇒ RDF::Vocabulary::Term

    Defines a new property or class in the vocabulary.

    Options Hash (options):

    • :label (String, Array<String>)

      Shortcut for ‘rdfs:label`, values are String interpreted as a Literal.

    • :comment (String, Array<String>)

      Shortcut for ‘rdfs:comment`, values are String interpreted as a Literal.

    • :subClassOf (String, Array<String>)

      Shortcut for ‘rdfs:subClassOf`, values are String interpreted as a URI.

    • :subPropertyOf (String, Array<String>)

      Shortcut for ‘rdfs:subPropertyOf`, values are String interpreted as a URI.

    • :domain (String, Array<String>)

      Shortcut for ‘rdfs:domain`, values are String interpreted as a URI.

    • :range (String, Array<String>)

      Shortcut for ‘rdfs:range`, values are String interpreted as a URI.

    • :type (String, Array<String>)

      Shortcut for ‘rdf:type`, values are String interpreted as a URI.



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/rdf/vocabulary.rb', line 112

def property(*args)
  case args.length
  when 0
    Term.intern("#{self}property", attributes: {label: "property", vocab: self})
  else
    name, options = args
    options = {label: name.to_s, vocab: self}.merge(options || {})
    uri_str = [to_s, name.to_s].join('')
    Term.cache.delete(uri_str)  # Clear any previous entry
    prop = Term.intern(uri_str, attributes: options)
    props[name.to_sym] = prop
    # Define an accessor, except for problematic properties
    (class << self; self; end).send(:define_method, name) { prop } unless %w(property hash).include?(name.to_s)
    prop
  end
end

.strict?Boolean

Is this a strict vocabulary, or a liberal vocabulary allowing arbitrary properties?



84
# File 'lib/rdf/vocabulary.rb', line 84

def strict?; false; end

.to_iriRDF::URI

Returns the base URI for this vocabulary class. For IRI compatibility



229
230
231
# File 'lib/rdf/vocabulary.rb', line 229

def to_uri
  RDF::URI.intern(to_s)
end

.to_sString

Returns a string representation of this vocabulary class.



261
262
263
# File 'lib/rdf/vocabulary.rb', line 261

def to_s
  @@uris.has_key?(self) ? @@uris[self].to_s : super
end

.to_uriRDF::URI

Returns the base URI for this vocabulary class.



224
225
226
# File 'lib/rdf/vocabulary.rb', line 224

def to_uri
  RDF::URI.intern(to_s)
end

Instance Method Details

#[](property) ⇒ URI

Returns the URI for the term ‘property` in this vocabulary.



400
401
402
# File 'lib/rdf/vocabulary.rb', line 400

def [](property)
  Term.intern([to_s, property.to_s].join(''), attributes: {vocab: self.class})
end

#inspectString

Returns a developer-friendly representation of this vocabulary.



427
428
429
# File 'lib/rdf/vocabulary.rb', line 427

def inspect
  sprintf("#<%s:%#0x(%s)>", self.class.name, __id__, to_s)
end

#to_sString

Returns a string representation of this vocabulary.



419
420
421
# File 'lib/rdf/vocabulary.rb', line 419

def to_s
  @uri.to_s
end

#to_uriURI Also known as: to_iri

Returns the base URI for this vocabulary.



408
409
410
# File 'lib/rdf/vocabulary.rb', line 408

def to_uri
  RDF::URI.intern(to_s)
end