Class: RDF::URI

Inherits:
Object
  • Object
show all
Includes:
Resource
Defined in:
lib/rdf/model/uri.rb

Overview

A Uniform Resource Identifier (URI).

‘RDF::URI` supports all the instance methods of `Addressable::URI`.

Examples:

Creating a URI reference (1)

uri = RDF::URI.new("http://rdf.rubyforge.org/")

Creating a URI reference (2)

uri = RDF::URI.new(:scheme => 'http', :host => 'rdf.rubyforge.org', :path => '/')

Creating an interned URI reference

uri = RDF::URI.intern("http://rdf.rubyforge.org/")

Getting the string representation of a URI

uri.to_s #=> "http://rdf.rubyforge.org/"

See Also:

Constant Summary collapse

CACHE_SIZE =

Defines the maximum number of interned URI references that can be held cached in memory at any one time.

-1 # unlimited by default

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Resource

new, #resource?

Methods included from Term

#<=>, #constant?, #variable?

Methods included from Value

#graph?, #inspect, #inspect!, #iri?, #literal?, #node?, #resource?, #statement?, #to_ntriples, #to_quad, #to_rdf, #type_error, #variable?

Constructor Details

#URI.new(uri) ⇒ URI #URI.new(options = {}) ⇒ URI

Returns a new instance of URI.

Overloads:

  • #URI.new(uri) ⇒ URI

    Parameters:

  • #URI.new(options = {}) ⇒ URI

    Parameters:

    • Hash{Symbol (Hash{Symbol => Object} options)

      > Object} options



78
79
80
81
82
83
84
85
86
87
# File 'lib/rdf/model/uri.rb', line 78

def initialize(uri_or_options)
  case uri_or_options
    when Hash
      @uri = Addressable::URI.new(uri_or_options)
    when Addressable::URI
      @uri = uri_or_options
    else
      @uri = Addressable::URI.parse(uri_or_options.to_s)
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(symbol, *args) { ... } ⇒ Object (protected)

Parameters:

  • symbol (Symbol, String, #to_s)
  • args (Array<Object>)

Yields:

Returns:

  • (Object)


558
559
560
561
562
563
564
565
566
567
568
# File 'lib/rdf/model/uri.rb', line 558

def method_missing(symbol, *args, &block)
  if @uri.respond_to?(symbol)
    case result = @uri.send(symbol, *args, &block)
      when Addressable::URI
        self.class.new(result)
      else result
    end
  else
    super
  end
end

Class Method Details

.cacheRDF::Util::Cache

Returns:



34
35
36
37
# File 'lib/rdf/model/uri.rb', line 34

def self.cache
  require 'rdf/util/cache' unless defined?(::RDF::Util::Cache)
  @cache ||= RDF::Util::Cache.new(CACHE_SIZE)
end

.intern(str) ⇒ RDF::URI

Returns an interned ‘RDF::URI` instance based on the given `uri` string.

The maximum number of cached interned URI references is given by the ‘CACHE_SIZE` constant. This value is unlimited by default, in which case an interned URI object will be purged only when the last strong reference to it is garbage collected (i.e., when its finalizer runs).

Excepting special memory-limited circumstances, it should always be safe and preferred to construct new URI references using ‘RDF::URI.intern` instead of `RDF::URI.new`, since if an interned object can’t be returned for some reason, this method will fall back to returning a freshly-allocated one.

Parameters:

  • str (String, #to_s)

Returns:

  • (RDF::URI)

    an immutable, frozen URI object



56
57
58
# File 'lib/rdf/model/uri.rb', line 56

def self.intern(str)
  (cache[str = str.to_s] ||= self.new(str)).freeze
end

.parse(str) ⇒ RDF::URI

Creates a new ‘RDF::URI` instance based on the given `uri` string.

This is just an alias for RDF::URI.new for compatibity with ‘Addressable::URI.parse`.

Parameters:

  • str (String, #to_s)

Returns:



68
69
70
# File 'lib/rdf/model/uri.rb', line 68

def self.parse(str)
  self.new(str)
end

Instance Method Details

#+(other) ⇒ RDF::URI

Simple concatenation operator. Returns a URI formed from concatenating the string form of two elements.

For building URIs from fragments, you may want to use the smart separator, ‘#/`. `#join` implements another set of URI building semantics.

Examples:

Concatenating a string to a URI

RDF::URI.new('http://example.org/test') + 'test'
#=> RDF::URI('http://example.org/testtest')

Concatenating two URIs

RDF::URI.new('http://example.org/test') + RDF::URI.new('test')
#=> RDF::URI('http://example.org/testtest')

Parameters:

  • (Any)

Returns:

See Also:



289
290
291
# File 'lib/rdf/model/uri.rb', line 289

def +(other)
  RDF::URI.intern(self.to_s + other.to_s)
end

#/(fragment) ⇒ RDF::URI

‘Smart separator’ URI builder

This method attempts to use some understanding of the most common use cases for URLs and URNs to create a simple method for building new URIs from fragments. This means that it will always insert a separator of some sort, will remove duplicate seperators, will always assume that a fragment argument represents a relative and not absolute path, and throws an exception when an absolute URI is received for a fragment argument.

This is separate from the semantics for ‘#join`, which are well-defined by RFC3986 section 5.2 as part of the merging and normalization process; this method does not perform any normalization, removal of spurious paths, or removal of parent directory references `(/../)`.

See also ‘#+`, which concatenates the string forms of two URIs without any sort of checking or processing.

For an up-to-date list of edge case behavior, see the shared examples for RDF::URI in the rdf-spec project.

Examples:

Building a HTTP URL

RDF::URI.new('http://example.org') / 'jhacker' / 'foaf.ttl'
#=> RDF::URI('http://example.org/jhacker/foaf.ttl')

Building a HTTP URL

RDF::URI.new('http://example.org/') / '/jhacker/' / '/foaf.ttl'
#=> RDF::URI('http://example.org/jhacker/foaf.ttl')

Using an anchored base URI

RDF::URI.new('http://example.org/users#') / 'jhacker'
#=> RDF::URI('http://example.org/users#jhacker')

Building a URN

RDF::URI.new('urn:isbn') / 125235111
#=> RDF::URI('urn:isbn:125235111')

Parameters:

  • fragment (Any)

    A URI fragment to be appended to this URI

Returns:

Raises:

  • (ArgumentError)

See Also:



246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
# File 'lib/rdf/model/uri.rb', line 246

def /(fragment)
  frag = fragment.respond_to?(:to_uri) ? fragment.to_uri : RDF::URI(fragment.to_s)
  raise ArgumentError, "Non-absolute URI or string required, got #{frag}" unless frag.relative?
  if urn?
    RDF::URI.intern(to_s.sub(/:+$/,'') + ':' + fragment.to_s.sub(/^:+/,''))
  else # !urn?
    case to_s[-1].chr
      when '#'
        case fragment.to_s[0].chr
          when '/' then # Base ending with '#', fragment beginning with '/'.  The fragment wins, we use '/'.
          RDF::URI.intern(to_s.sub(/#+$/,'') + '/' + fragment.to_s.sub(/^\/+/,''))
        else
          RDF::URI.intern(to_s.sub(/#+$/,'') + '#' + fragment.to_s.sub(/^#+/,''))
        end
      else # includes '/'.  Results from bases ending in '/' are the same as if there were no trailing slash.
        case fragment.to_s[0].chr
          when '#' then # Base ending with '/', fragment beginning with '#'.  The fragment wins, we use '#'.
            RDF::URI.intern(to_s.sub(/\/+$/,'') + '#' + fragment.to_s.sub(/^#+/,''))
          else
            RDF::URI.intern(to_s.sub(/\/+$/,'') + '/' + fragment.to_s.sub(/^\/+/,''))
          end
      end
  end
end

#==(other) ⇒ Boolean

Checks whether this URI is equal to ‘other` (type checking).

Per SPARQL data-r2/expr-equal/eq-2-2, numeric can’t be compared with other types

Examples:

RDF::URI('http://t.co/') == RDF::URI('http://t.co/')    #=> true
RDF::URI('http://t.co/') == 'http://t.co/'              #=> true
RDF::URI('http://purl.org/dc/terms/') == RDF::DC        #=> true

Parameters:

  • other (Object)

Returns:

  • (Boolean)

    ‘true` or `false`

See Also:



464
465
466
467
468
469
470
471
472
473
# File 'lib/rdf/model/uri.rb', line 464

def ==(other)
  case other
  when Literal
    # If other is a Literal, reverse test to consolodate complex type checking logic
    other == self
  when String then to_s == other
  when URI, Addressable::URI then to_s == other.to_s
  else other.respond_to?(:to_uri) && to_s == other.to_uri.to_s
  end
end

#===(other) ⇒ Boolean

Checks for case equality to the given ‘other` object.

Examples:

RDF::URI('http://example.org/') === /example/           #=> true
RDF::URI('http://example.org/') === /foobar/            #=> false
RDF::URI('http://t.co/') === RDF::URI('http://t.co/')   #=> true
RDF::URI('http://t.co/') === 'http://t.co/'             #=> true
RDF::URI('http://purl.org/dc/terms/') === RDF::DC       #=> true

Parameters:

  • other (Object)

Returns:

  • (Boolean)

    ‘true` or `false`

Since:

  • 0.3.0



488
489
490
491
492
493
# File 'lib/rdf/model/uri.rb', line 488

def ===(other)
  case other
    when Regexp then other === to_s
    else self == other
  end
end

#=~(pattern) ⇒ Integer

Performs a pattern match using the given regular expression.

Examples:

RDF::URI('http://example.org/') =~ /example/            #=> 7
RDF::URI('http://example.org/') =~ /foobar/             #=> nil

Parameters:

  • pattern (Regexp)

Returns:

  • (Integer)

    the position the match starts

See Also:

  • String#=~

Since:

  • 0.3.0



506
507
508
509
510
511
# File 'lib/rdf/model/uri.rb', line 506

def =~(pattern)
  case pattern
    when Regexp then to_s =~ pattern
    else super # `Object#=~` returns `false`
  end
end

#anonymous?Boolean

Returns ‘false`.

Returns:

  • (Boolean)

    ‘true` or `false`



93
94
95
# File 'lib/rdf/model/uri.rb', line 93

def anonymous?
  false
end

#canonicalizeRDF::URI

Returns a copy of this URI converted into its canonical lexical representation.

Returns:

Since:

  • 0.3.0



163
164
165
# File 'lib/rdf/model/uri.rb', line 163

def canonicalize
  self.dup.canonicalize!
end

#canonicalize!RDF::URI

Converts this URI into its canonical lexical representation.

Returns:

Since:

  • 0.3.0



172
173
174
175
# File 'lib/rdf/model/uri.rb', line 172

def canonicalize!
  # TODO: canonicalize this URI
  self
end

#dupRDF::URI

Returns a duplicate copy of ‘self`.

Returns:



394
395
396
# File 'lib/rdf/model/uri.rb', line 394

def dup
  self.class.new(@uri.dup)
end

#end_with?(string) ⇒ Boolean Also known as: ends_with?

Returns ‘true` if this URI ends with the given `string`.

Examples:

RDF::URI('http://example.org/').end_with?('/')          #=> true
RDF::URI('http://example.org/').end_with?('#')          #=> false

Parameters:

  • string (String, #to_s)

Returns:

  • (Boolean)

    ‘true` or `false`

See Also:

  • String#end_with?

Since:

  • 0.3.0



432
433
434
# File 'lib/rdf/model/uri.rb', line 432

def end_with?(string)
  to_s.end_with?(string.to_s)
end

#eql?(other) ⇒ Boolean

Checks whether this URI the same term as ‘other’.

Examples:

RDF::URI('http://t.co/').eql?(RDF::URI('http://t.co/')) #=> true
RDF::URI('http://t.co/').eql?('http://t.co/')           #=> false
RDF::URI('http://purl.org/dc/terms/').eql?(RDF::DC)     #=> false

Parameters:

Returns:

  • (Boolean)

    ‘true` or `false`



447
448
449
# File 'lib/rdf/model/uri.rb', line 447

def eql?(other)
  other.is_a?(URI) && self == other
end

#freezeObject



400
401
402
403
# File 'lib/rdf/model/uri.rb', line 400

def freeze
  @uri.freeze
  super
end

#has_parent?Boolean

Returns ‘true` if this URI’s path component isn’t equal to ‘/`.

Examples:

RDF::URI('http://example.org/').has_parent?             #=> false
RDF::URI('http://example.org/path/').has_parent?        #=> true

Returns:

  • (Boolean)

    ‘true` or `false`



331
332
333
# File 'lib/rdf/model/uri.rb', line 331

def has_parent?
  !root?
end

#hashFixnum

Returns a hash code for this URI.

Returns:

  • (Fixnum)


537
538
539
# File 'lib/rdf/model/uri.rb', line 537

def hash
  @uri.hash
end

#join(*uris) ⇒ RDF::URI

Joins several URIs together.

This method conforms to join normalization semantics as per RFC3986, section 5.2. This method normalizes URIs, removes some duplicate path information, such as double slashes, and other behavior specified in the RFC.

Other URI building methods are ‘#/` and `#+`.

For an up-to-date list of edge case behavior, see the shared examples for RDF::URI in the rdf-spec project.

Examples:

Joining two URIs

RDF::URI.new('http://example.org/foo/bar').join('/foo')
#=> RDF::URI('http://example.org/foo')

Parameters:

Returns:

See Also:



199
200
201
202
203
204
205
# File 'lib/rdf/model/uri.rb', line 199

def join(*uris)
  result = @uri.dup
  uris.each do |uri|
    result = result.join(uri)
  end
  self.class.new(result)
end

#lengthInteger Also known as: size

Returns the string length of this URI.

Examples:

RDF::URI('http://example.org/').length                  #=> 19

Returns:

  • (Integer)

Since:

  • 0.3.0



140
141
142
# File 'lib/rdf/model/uri.rb', line 140

def length
  to_s.length
end

#parentRDF::URI

Returns a copy of this URI with the path component ascended to the parent directory, if any.

Examples:

RDF::URI('http://example.org/').parent                  #=> nil
RDF::URI('http://example.org/path/').parent             #=> RDF::URI('http://example.org/')

Returns:



344
345
346
347
348
349
350
351
352
353
354
355
356
# File 'lib/rdf/model/uri.rb', line 344

def parent
  case
    when root? then nil
    else
      require 'pathname' unless defined?(Pathname)
      if path = Pathname.new(self.path).parent
        uri = self.dup
        uri.path = path.to_s
        uri.path << '/' unless uri.root?
        uri
      end
  end
end

#qnameArray(Symbol, Symbol)

Returns a qualified name (QName) for this URI, if possible.

Examples:

RDF::URI('http://purl.org/dc/terms/').qname             #=> [:dc, nil]
RDF::URI('http://purl.org/dc/terms/title').qname        #=> [:dc, :title]
RDF::DC.title.qname                                     #=> [:dc, :title]

Returns:

  • (Array(Symbol, Symbol))

    or ‘nil` if no QName found



367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
# File 'lib/rdf/model/uri.rb', line 367

def qname
  if self.to_s =~ %r([:/#]([^:/#]*)$)
    local_name = $1
    vocab_uri  = local_name.empty? ? self.to_s : self.to_s[0...-(local_name.length)]
    Vocabulary.each do |vocab|
      if vocab.to_uri == vocab_uri
        prefix = vocab.equal?(RDF) ? :rdf : vocab.__prefix__
        return [prefix, local_name.empty? ? nil : local_name.to_sym]
      end
    end
  else
    Vocabulary.each do |vocab|
      vocab_uri = vocab.to_uri
      if self.start_with?(vocab_uri)
        prefix = vocab.equal?(RDF) ? :rdf : vocab.__prefix__
        local_name = self.to_s[vocab_uri.length..-1]
        return [prefix, local_name.empty? ? nil : local_name.to_sym]
      end
    end
  end
  return nil # no QName found
end

#respond_to?(symbol) ⇒ Boolean

Returns ‘true` if this URI instance supports the `symbol` method.

Parameters:

  • symbol (Symbol, String, #to_s)

Returns:

  • (Boolean)

    ‘true` or `false`



546
547
548
# File 'lib/rdf/model/uri.rb', line 546

def respond_to?(symbol)
  @uri.respond_to?(symbol) || super
end

#rootRDF::URI

Returns a copy of this URI with the path component set to ‘/`.

Examples:

RDF::URI('http://example.org/').root                    #=> RDF::URI('http://example.org/')
RDF::URI('http://example.org/path/').root               #=> RDF::URI('http://example.org/')

Returns:



313
314
315
316
317
318
319
320
321
# File 'lib/rdf/model/uri.rb', line 313

def root
  if root?
    self
  else
    uri = self.dup
    uri.path = '/'
    uri
  end
end

#root?Boolean

Returns ‘true` if this URI’s path component is equal to ‘/`.

Examples:

RDF::URI('http://example.org/').root?                   #=> true
RDF::URI('http://example.org/path/').root?              #=> false

Returns:

  • (Boolean)

    ‘true` or `false`



301
302
303
# File 'lib/rdf/model/uri.rb', line 301

def root?
  self.path == '/' || self.path.empty?
end

#start_with?(string) ⇒ Boolean Also known as: starts_with?

Returns ‘true` if this URI starts with the given `string`.

Examples:

RDF::URI('http://example.org/').start_with?('http')     #=> true
RDF::URI('http://example.org/').start_with?('ftp')      #=> false

Parameters:

  • string (String, #to_s)

Returns:

  • (Boolean)

    ‘true` or `false`

See Also:

  • String#start_with?

Since:

  • 0.3.0



416
417
418
# File 'lib/rdf/model/uri.rb', line 416

def start_with?(string)
  to_s.start_with?(string.to_s)
end

#to_strString Also known as: to_s

Returns the string representation of this URI.

Examples:

RDF::URI('http://example.org/').to_str                  #=> 'http://example.org/'

Returns:

  • (String)


528
529
530
# File 'lib/rdf/model/uri.rb', line 528

def to_str
  @uri.to_s
end

#to_uriRDF::URI

Returns ‘self`.

Returns:



517
518
519
# File 'lib/rdf/model/uri.rb', line 517

def to_uri
  self
end

#uri?Boolean

Returns ‘true`.

Returns:

  • (Boolean)

    ‘true` or `false`

See Also:



102
103
104
# File 'lib/rdf/model/uri.rb', line 102

def uri?
  true
end

#url?Boolean

Returns ‘true` if this URI is a URL.

Examples:

RDF::URI('http://example.org/').url?                    #=> true

Returns:

  • (Boolean)

    ‘true` or `false`

See Also:

Since:

  • 0.2.0



128
129
130
# File 'lib/rdf/model/uri.rb', line 128

def url?
  !urn?
end

#urn?Boolean

Returns ‘true` if this URI is a URN.

Examples:

RDF::URI('http://example.org/').urn?                    #=> false

Returns:

  • (Boolean)

    ‘true` or `false`

See Also:

Since:

  • 0.2.0



115
116
117
# File 'lib/rdf/model/uri.rb', line 115

def urn?
  self.start_with?('urn:')
end

#validate!RDF::URI Also known as: validate

Validates this URI, raising an error if it is invalid.

Returns:

Raises:

  • (ArgumentError)

    if the URI is invalid

Since:

  • 0.3.0



151
152
153
154
# File 'lib/rdf/model/uri.rb', line 151

def validate!
  # TODO: raise error if the URI fails validation
  self
end