Class: RDF::URI

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

Overview

A Uniform Resource Identifier (URI). Also compatible with International Resource Identifier (IRI)

Examples:

Creating a URI reference (1)

uri = RDF::URI.new("https://rubygems.org/gems/rdf")

Creating a URI reference (2)

uri = RDF::URI.new(scheme: 'http', host: 'rubygems.org', path: '/gems/rdf')
  #=> RDF::URI.new("https://rubygems.org/gems/rdf")

Creating an interned URI reference

uri = RDF::URI.intern("https://rubygems.org/gems/rdf")

Getting the string representation of a URI

uri.to_s #=> "https://rubygems.org/gems/rdf"

See Also:

Constant Summary collapse

UCSCHAR =

IRI components

%(
  \\u00A0-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF
  \\u{10000}-\\u{1FFFD}\\u{20000}-\\u{2FFFD}\\u{30000}-\\u{3FFFD}
  \\u{40000}-\\u{4FFFD}\\u{50000}-\\u{5FFFD}\\u{60000}-\\u{6FFFD}
  \\u{70000}-\\u{7FFFD}\\u{80000}-\\u{8FFFD}\\u{90000}-\\u{9FFFD}
  \\u{A0000}-\\u{AFFFD}\\u{B0000}-\\u{BFFFD}\\u{C0000}-\\u{CFFFD}
  \\u{D0000}-\\u{DFFFD}\\u{E1000}-\\u{EFFFD}
).gsub(/\s+/, '')
IPRIVATE =
Regexp.compile("[\\uE000-\\uF8FF\\u{F0000}-\\u{FFFFD}\\u{100000}-\\u{10FFFD}]").freeze
SCHEME =
Regexp.compile("[A-Za-z](?:[A-Za-z0-9+-\.])*").freeze
PORT =
Regexp.compile("[0-9]*").freeze
IP_literal =

Simplified, no IPvFuture

Regexp.compile("\\[[0-9A-Fa-f:\\.]*\\]").freeze
PCT_ENCODED =
Regexp.compile("%[0-9A-Fa-f][0-9A-Fa-f]").freeze
GEN_DELIMS =
Regexp.compile(%q{[:/\?\#\[\]@]}).freeze
SUB_DELIMS =
Regexp.compile(%q{[!\$&'\(\)\*\+,;=]}).freeze
RESERVED =
Regexp.union(GEN_DELIMS, SUB_DELIMS).freeze
UNRESERVED =
Regexp.compile("[A-Za-z0-9\._~-]").freeze
IUNRESERVED =
Regexp.union(UNRESERVED, Regexp.compile("[#{UCSCHAR}]")).freeze
IPCHAR =
Regexp.union(IUNRESERVED, PCT_ENCODED, SUB_DELIMS, /[:|@]/).freeze
IQUERY =
Regexp.compile("(?:#{IPCHAR}|#{IPRIVATE}|/|\\?)*").freeze
IFRAGMENT =
Regexp.compile("(?:#{IPCHAR}|/|\\?)*").freeze
ISEGMENT =
Regexp.compile("(?:#{IPCHAR})*").freeze
ISEGMENT_NZ =
Regexp.compile("(?:#{IPCHAR})+").freeze
ISEGMENT_NZ_NC =
Regexp.compile("(?:(?:#{IUNRESERVED})|(?:#{PCT_ENCODED})|(?:#{SUB_DELIMS})|@)+").freeze
IPATH_ABEMPTY =
Regexp.compile("(?:/#{ISEGMENT})*").freeze
IPATH_ABSOLUTE =
Regexp.compile("/(?:(?:#{ISEGMENT_NZ})(/#{ISEGMENT})*)?").freeze
IPATH_NOSCHEME =
Regexp.compile("(?:#{ISEGMENT_NZ_NC})(?:/#{ISEGMENT})*").freeze
IPATH_ROOTLESS =
Regexp.compile("(?:#{ISEGMENT_NZ})(?:/#{ISEGMENT})*").freeze
IPATH_EMPTY =
Regexp.compile("").freeze
IREG_NAME =
Regexp.compile("(?:(?:#{IUNRESERVED})|(?:#{PCT_ENCODED})|(?:#{SUB_DELIMS}))*").freeze
IHOST =
Regexp.union(IP_literal, IREG_NAME).freeze
IUSERINFO =
Regexp.compile("(?:(?:#{IUNRESERVED})|(?:#{PCT_ENCODED})|(?:#{SUB_DELIMS})|:)*").freeze
IAUTHORITY =
Regexp.compile("(?:#{IUSERINFO}@)?#{IHOST}(?::#{PORT})?").freeze
IRELATIVE_PART =
Regexp.compile("//#{IAUTHORITY}(?:#{IPATH_ABEMPTY})|(?:#{IPATH_ABSOLUTE})|(?:#{IPATH_NOSCHEME})|(?:#{IPATH_EMPTY})").freeze
IRELATIVE_REF =
Regexp.compile("^(?:#{IRELATIVE_PART})(?:\\?#{IQUERY})?(?:\\##{IFRAGMENT})?$").freeze
IHIER_PART =
Regexp.compile("//#{IAUTHORITY}(?:#{IPATH_ABEMPTY})|(?:#{IPATH_ABSOLUTE})|(?:#{IPATH_ROOTLESS})|(?:#{IPATH_EMPTY})").freeze
IRI =
Regexp.compile("^#{SCHEME}:(?:#{IHIER_PART})(?:\\?#{IQUERY})?(?:\\##{IFRAGMENT})?$").freeze
IRI_PARTS =

Split an IRI into it's component parts scheme, authority, path, query, fragment

/^(?:([^:\/?#]+):)?(?:\/\/([^\/?#]*))?([^?#]*)(\?[^#]*)?(#.*)?$/.freeze
FILE_PARTS =

Special version for file-scheme on Windows (path SHOULD begin with /, but may not) scheme, authority, path, query, fragment

/^file:(?:\/\/(#{IHOST}))?(\/?[^?#]*)(\?[^#]*)?(#.*)?$/.freeze
RDS_2A =

Remove dot expressions regular expressions

/^\.?\.\/(.*)$/.freeze
RDS_2B1 =
/^\/\.$/.freeze
RDS_2B2 =
/^(?:\/\.\/)(.*)$/.freeze
RDS_2C1 =
/^\/\.\.$/.freeze
RDS_2C2 =
/^(?:\/\.\.\/)(.*)$/.freeze
RDS_2D =
/^\.\.?$/.freeze
RDS_2E =
/^(\/?[^\/]*)(\/?.*)?$/.freeze
PORT_MAPPING =

Remove port, if it is standard for the scheme when normalizing

{
  "http"     => 80,
  "https"    => 443,
  "ftp"      => 21,
  "tftp"     => 69,
  "sftp"     => 22,
  "ssh"      => 22,
  "svn+ssh"  => 22,
  "telnet"   => 23,
  "nntp"     => 119,
  "gopher"   => 70,
  "wais"     => 210,
  "ldap"     => 389,
  "prospero" => 1525
}
NON_HIER_SCHEMES =

List of schemes known not to be hierarchical

%w(
  about acct bitcoin callto cid data fax geo gtalk h323 iax icon im jabber
  jms magnet mailto maps news pres proxy session sip sips skype sms spotify stun stuns
  tag tel turn turns tv urn javascript
).freeze
PN_ESCAPE_CHARS =

Characters in a PName which must be escaped Note: not all reserved characters need to be escaped in SPARQL/Turtle, but they must be unescaped when encountered

/[~\.!\$&'\(\)\*\+,;=\/\?\#@%]/.freeze
PN_ESCAPES =
/\\#{Regexp.union(PN_ESCAPE_CHARS, /[\-_]/)}/.freeze
ENCODE_USER =

For URI encoding iuserinfo = *( iunreserved / pct-encoded / sub-delims / ":" )

ENCODE_PASSWORD = Regexp.compile("[^A-Za-z0-9\._~#{UCSCHAR}!$&'\(\)\*\+,;=:-]").freeze
ENCODE_ISEGMENT =

isegment = *ipchar ipchar = iunreserved / pct-encoded / sub-delims / ":" / "@"

Regexp.compile("[^A-Za-z0-9\._~#{UCSCHAR}!$&'\(\)\*\+,;=:-]").freeze
ENCODE_ISEGMENT_NC =

isegment-nz-nc = 1*( iunreserved / pct-encoded / sub-delims / "@" )

Regexp.compile("[^A-Za-z0-9\._~#{UCSCHAR}!$&'\(\)\*\+,;=-]").freeze
ENCODE_IQUERY =

iquery = *( ipchar / iprivate / "/" / "?" )

Regexp.compile("[^A-Za-z0-9\._~#{UCSCHAR}\\uE000-\\uF8FF\\u{F0000}-\\u{FFFFD}\\u{100000}-\\u{10FFFD}/?=]").freeze
ENCODE_IFRAGMENT =

ifragment = *( ipchar / "/" / "?" )

Regexp.compile("[^A-Za-z0-9\._~#{UCSCHAR}/?]").freeze
HOST_FROM_AUTHORITY_RE =
/(?:[^@]+@)?([^:]+)(?::.*)?$/.freeze
PORT_FROM_AUTHORITY_RE =
/:(\d+)$/.freeze

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Resource

new, #resource?

Methods included from Term

#<=>, #compatible?, #escape, #term?, #terms, #to_base, #to_term

Methods included from Value

#anonymous?, #constant?, #graph?, #inspect!, #invalid?, #iri?, #list?, #literal?, #node?, #resource?, #start_with?, #statement?, #term?, #to_nquads, #to_ntriples, #to_rdf, #to_term, #type_error, #variable?

Constructor Details

#initialize(uri, **options) ⇒ URI #initialize(**options) ⇒ URI

Returns a new instance of URI.

Overloads:

  • #initialize(uri, **options) ⇒ URI

    Parameters:

  • #initialize(**options) ⇒ URI

    Parameters:

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

      (false)

    • canonicalize (Boolean)

      (false)



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

def initialize(*args, validate: false, canonicalize: false, **options)
  @value = @object = @hash = nil
  @mutex = Mutex.new
  uri = args.first
  if uri
    @value = uri.to_s.dup
    @value.dup.force_encoding(Encoding::UTF_8) if @value.encoding != Encoding::UTF_8
    @value.freeze
  else
    %i(
      scheme
      user password userinfo
      host port authority
      path query fragment
    ).each do |meth|
      if options.key?(meth)
        self.send("#{meth}=".to_sym, options[meth])
      else
        self.send(meth)
      end
    end
  end

  validate!     if validate
  canonicalize! if canonicalize
end

Class Method Details

._load(data) ⇒ RDF::URI

Load dumped data to reconsitute marshaled object This override is needed to avoid serializing @mutex.

Parameters:

  • data (String)

    The dump of data needed to reconsitute this object.

Returns:

  • (RDF::URI)

    The reconsituted object.



1363
1364
1365
# File 'lib/rdf/model/uri.rb', line 1363

def self._load(data)
  new(data)
end

.intern(str, *args, **options) ⇒ 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.

(see #initialize)

Returns:

  • (RDF::URI)

    an immutable, frozen URI object



166
167
168
# File 'lib/rdf/model/uri.rb', line 166

def self.intern(str, *args, **options)
  (cache[(str = str.to_s).to_sym] ||= self.new(str.to_s, *args, **options)).freeze
end

.normalize_path(path) ⇒ String

TODO:

This process is correct, but overly iterative. It could be better done with a single regexp which handled most of the segment collapses all at once. Parent segments would still require iteration.

Resolve paths to their simplest form.

Parameters:

  • path (String)

Returns:

  • (String)

    normalized path

See Also:



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# File 'lib/rdf/model/uri.rb', line 191

def self.normalize_path(path)
  output, input = String.new, path.to_s
  if input.encoding != Encoding::ASCII_8BIT
    input = input.dup.force_encoding(Encoding::ASCII_8BIT)
  end
  until input.empty?
    if input.match(RDS_2A)
      # If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
      input = $1
    elsif input.match(RDS_2B1) || input.match(RDS_2B2)
      # if the input buffer begins with a prefix of "/./" or "/.", where "." is a complete path segment, then replace that prefix with "/" in the input buffer; otherwise,
      input = "/#{$1}"
    elsif input.match(RDS_2C1) || input.match(RDS_2C2)
      # if the input buffer begins with a prefix of "/../" or "/..", where ".." is a complete path segment, then replace that prefix with "/" in the input buffer
      input = "/#{$1}"

      #  and remove the last segment and its preceding "/" (if any) from the output buffer; otherwise,
      output.sub!(/\/?[^\/]*$/, '')
    elsif input.match(RDS_2D)
      # if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
      input = ""
    elsif input.match(RDS_2E)
      # move the first path segment in the input buffer to the end of the output buffer, including the initial "/" character (if any) and any subsequent characters up to, but not including, the next "/" character or the end of the input buffer.end
      seg, input = $1, $2
      output << seg
    end
  end

  output.force_encoding(Encoding::UTF_8)
end

.parse(str) ⇒ RDF::URI

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

This is just an alias for #initialize for compatibity with Addressable::URI.parse. Actual parsing is defered until #object is accessed.

Parameters:

  • str (String, #to_s)

Returns:



179
180
181
# File 'lib/rdf/model/uri.rb', line 179

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:

  • other (Any)

Returns:

See Also:



574
575
576
# File 'lib/rdf/model/uri.rb', line 574

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 (/../).

When fragment is a path segment containing a colon, best practice is to prepend a ./ and use #join, which resolves dot-segments.

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 (absolute path components)

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)

    if the URI is invalid

See Also:



519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
# File 'lib/rdf/model/uri.rb', line 519

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?
    res = self.dup
    if res.fragment
      case fragment.to_s[0,1]
      when '/'
        # Base with a fragment, fragment beginning with '/'. The fragment wins, we use '/'.
        path, frag = fragment.to_s.split('#', 2)
        res.path = "#{res.path}/#{path.sub(/^\/*/,'')}"
        res.fragment = frag
      else
        # Replace fragment
        res.fragment = fragment.to_s.sub(/^#+/,'')
      end
    else
      # Not a fragment. includes '/'. Results from bases ending in '/' are the same as if there were no trailing slash.
      case fragment.to_s[0,1]
      when '#'
        # Base ending with '/', fragment beginning with '#'. The fragment wins, we use '#'.
        res.path = res.path.to_s.sub(/\/*$/, '')
        # Add fragment
        res.fragment = fragment.to_s.sub(/^#+/,'')
      else
        # Add fragment as path component
        path, frag = fragment.to_s.split('#', 2)
        res.path = res.path.to_s.sub(/\/*$/,'/') + path.sub(/^\/*/,'')
        res.fragment = frag
      end
    end
    RDF::URI.intern(res.to_s)
  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://www.w3.org/2000/01/rdf-schema#') == RDF::RDFS        #=> true

Parameters:

  • other (Object)

Returns:

  • (Boolean)

    true or false

See Also:



779
780
781
782
783
784
785
786
787
788
# File 'lib/rdf/model/uri.rb', line 779

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 then hash == other.hash && 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://www.w3.org/2000/01/rdf-schema#') === RDF::RDFS       #=> true

Parameters:

  • other (Object)

Returns:

  • (Boolean)

    true or false

Since:

  • 0.3.0



803
804
805
806
807
808
# File 'lib/rdf/model/uri.rb', line 803

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



821
822
823
824
825
826
# File 'lib/rdf/model/uri.rb', line 821

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

#_dump(level) ⇒ String

Dump of data needed to reconsitute this object using Marshal.load This override is needed to avoid serializing @mutex.

Parameters:

  • level (Integer)

    The maximum depth of objects to dump.

Returns:

  • (String)

    The dump of data needed to reconsitute this object.



1353
1354
1355
# File 'lib/rdf/model/uri.rb', line 1353

def _dump(level)
  value
end

#absolute?Boolean

A URI is absolute when it has a scheme

Returns:

  • (Boolean)

    true or false



325
# File 'lib/rdf/model/uri.rb', line 325

def absolute?; !scheme.nil?; end

#authorityObject

Authority is a combination of user, password, host and port



1190
1191
1192
1193
1194
# File 'lib/rdf/model/uri.rb', line 1190

def authority
  object.fetch(:authority) {
    @object[:authority] = (format_authority if @object[:host])
  }
end

#authority=(value) ⇒ RDF::URI

Returns self.

Parameters:

  • value (String, #to_s)

Returns:



1199
1200
1201
1202
1203
1204
1205
# File 'lib/rdf/model/uri.rb', line 1199

def authority=(value)
  object.delete_if {|k, v| %i(user password host port userinfo).include?(k)}
  object[:authority] = (value.to_s.dup.force_encoding(Encoding::UTF_8) if value)
  user; password; userinfo; host; port
  @value = nil
  self
end

#canonicalizeRDF::URI Also known as: normalize

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

Returns:

Since:

  • 0.3.0



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

def canonicalize
  self.dup.canonicalize!
end

#canonicalize!RDF::URI Also known as: normalize!

Converts this URI into its canonical lexical representation.

Returns:

Since:

  • 0.3.0



405
406
407
408
409
410
411
412
413
414
415
416
# File 'lib/rdf/model/uri.rb', line 405

def canonicalize!
  @object = {
    scheme: normalized_scheme,
    authority: normalized_authority,
    path: normalized_path.squeeze('/'),
    query: normalized_query,
    fragment: normalized_fragment
  }
  @value = nil
  @hash = nil
  self
end

#dupRDF::URI

Returns a duplicate copy of self.

Returns:



716
717
718
# File 'lib/rdf/model/uri.rb', line 716

def dup
  self.class.new(@value, **(@object || {}))
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



747
748
749
# File 'lib/rdf/model/uri.rb', line 747

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://www.w3.org/2000/01/rdf-schema#').eql?(RDF::RDFS) #=> false

Parameters:

Returns:

  • (Boolean)

    true or false



762
763
764
# File 'lib/rdf/model/uri.rb', line 762

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

#fragmentString

Returns:

  • (String)


1166
1167
1168
1169
1170
# File 'lib/rdf/model/uri.rb', line 1166

def fragment
  object.fetch(:fragment) do
    nil
  end
end

#fragment=(value) ⇒ RDF::URI

Returns self.

Parameters:

  • value (String, #to_s)

Returns:



1175
1176
1177
1178
1179
# File 'lib/rdf/model/uri.rb', line 1175

def fragment=(value)
  object[:fragment] = (value.to_s.dup.force_encoding(Encoding::UTF_8) if value)
  @value = nil
  self
end

#hashInteger

Returns a hash code for this URI.

Returns:

  • (Integer)


871
872
873
# File 'lib/rdf/model/uri.rb', line 871

def hash
  @hash || @hash = (value.hash * -1)
end

#hier?Boolean

Returns true if the URI scheme is hierarchical.

Examples:

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

Returns:

  • (Boolean)

    true or false

See Also:

Since:

  • 1.0.10



305
306
307
# File 'lib/rdf/model/uri.rb', line 305

def hier?
  !NON_HIER_SCHEMES.include?(scheme)
end

#hostString

Returns:

  • (String)


1018
1019
1020
1021
1022
# File 'lib/rdf/model/uri.rb', line 1018

def host
  object.fetch(:host) do
    @object[:host] = ($1 if @object[:authority] && HOST_FROM_AUTHORITY_RE.match(@object[:authority]))
  end
end

#host=(value) ⇒ RDF::URI

Returns self.

Parameters:

  • value (String, #to_s)

Returns:



1027
1028
1029
1030
1031
1032
# File 'lib/rdf/model/uri.rb', line 1027

def host=(value)
  object[:host] = (value.to_s.dup.force_encoding(Encoding::UTF_8) if value)
  @object[:authority] = format_authority
  @value = nil
  self
end

#inspectString

Returns a String representation of the URI object's state.

Returns:

  • (String)

    The URI object's state, as a String.



850
851
852
# File 'lib/rdf/model/uri.rb', line 850

def inspect
  sprintf("#<%s:%#0x URI:%s>", URI.to_s, self.object_id, self.to_s)
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:

  • uris (Array<String, RDF::URI, #to_s>)

    absolute or relative URIs.

Returns:

See Also:



443
444
445
446
447
448
449
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
# File 'lib/rdf/model/uri.rb', line 443

def join(*uris)
  joined_parts = object.dup.delete_if {|k, v| %i(user password host port).include?(k)}

  uris.each do |uri|
    uri = RDF::URI.new(uri) unless uri.is_a?(RDF::URI)
    next if uri.to_s.empty? # Don't mess with base URI

    case
    when uri.scheme
      joined_parts = uri.object.merge(path: self.class.normalize_path(uri.path))
    when uri.authority
      joined_parts[:authority] = uri.authority
      joined_parts[:path] = self.class.normalize_path(uri.path)
      joined_parts[:query] = uri.query
    when uri.path.to_s.empty?
      joined_parts[:query] = uri.query if uri.query
    when uri.path[0,1] == '/'
      joined_parts[:path] = self.class.normalize_path(uri.path)
      joined_parts[:query] = uri.query
    else
      # Merge path segments from section 5.2.3
      # Note that if the path includes no segments, the entire path is removed
      #  > return a string consisting of the reference's path component appended to all but the last segment of the base URI's path (i.e., excluding any characters after the right-most "/" in the base URI path, or excluding the entire base URI path if it does not contain any "/" characters).
      base_path = path.to_s.include?('/') ? path.to_s.sub(/\/[^\/]*$/, '/') : ''
      joined_parts[:path] = self.class.normalize_path(base_path + uri.path)
      joined_parts[:query] = uri.query
    end
    joined_parts[:fragment] = uri.fragment
  end

  # Return joined URI
  RDF::URI.new(**joined_parts)
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



362
363
364
# File 'lib/rdf/model/uri.rb', line 362

def length
  to_s.length
end

#normalized_authorityString

Return normalized version of authority, if any

Returns:

  • (String)


1210
1211
1212
1213
1214
1215
1216
# File 'lib/rdf/model/uri.rb', line 1210

def normalized_authority
  if authority
    (userinfo ? normalized_userinfo.to_s + "@" : "") +
    normalized_host.to_s +
    (normalized_port ? ":" + normalized_port.to_s : "")
  end
end

#normalized_fragmentString

Normalized version of fragment

Returns:

  • (String)


1184
1185
1186
# File 'lib/rdf/model/uri.rb', line 1184

def normalized_fragment
  normalize_segment(fragment, ENCODE_IFRAGMENT) if fragment
end

#normalized_hostString

Normalized version of host

Returns:

  • (String)


1037
1038
1039
1040
# File 'lib/rdf/model/uri.rb', line 1037

def normalized_host
  # Remove trailing '.' characters
  host.sub(/\.*$/, '').downcase if host
end

#normalized_passwordString

Normalized version of password

Returns:

  • (String)


1010
1011
1012
# File 'lib/rdf/model/uri.rb', line 1010

def normalized_password
  URI.encode(CGI.unescape(password), ENCODE_PASSWORD).force_encoding(Encoding::UTF_8) if password
end

#normalized_pathString

Normalized version of path

Returns:

  • (String)


1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
# File 'lib/rdf/model/uri.rb', line 1098

def normalized_path
  if normalized_scheme == "urn"
    # Special-case URI. Normalize the NID component only
    nid, p = path.to_s.split(':', 2)
    return "#{nid.downcase}:#{p}"
  end

  segments = path.to_s.split('/', -1) # preserve null segments

  norm_segs = case
  when authority
    # ipath-abempty
    segments.map {|s| normalize_segment(s, ENCODE_ISEGMENT)}
  when segments[0].nil?
    # ipath-absolute
    res = [nil]
    res << normalize_segment(segments[1], ENCODE_ISEGMENT) if segments.length > 1
    res += segments[2..-1].map {|s| normalize_segment(s, ENCODE_ISEGMENT)} if segments.length > 2
    res
  when segments[0].to_s.index(':')
    # ipath-noscheme
    res = []
    res << normalize_segment(segments[0], ENCODE_ISEGMENT_NC)
    res += segments[1..-1].map {|s| normalize_segment(s, ENCODE_ISEGMENT)} if segments.length > 1
    res
  when segments[0]
    # ipath-rootless
    # ipath-noscheme
    res = []
    res << normalize_segment(segments[0], ENCODE_ISEGMENT)
    res += segments[1..-1].map {|s| normalize_segment(s, ENCODE_ISEGMENT)} if segments.length > 1
    res
  else
    # Should be empty
    segments
  end

  res = self.class.normalize_path(norm_segs.join("/"))
  # Special rules for specific protocols having empty paths
  (res.empty? && %w(http https ftp tftp).include?(normalized_scheme)) ? '/' : res
end

#normalized_portString

Normalized version of port

Returns:

  • (String)


1065
1066
1067
1068
1069
1070
# File 'lib/rdf/model/uri.rb', line 1065

def normalized_port
  if port
    np = port.to_i
    PORT_MAPPING[normalized_scheme] != np ? np : nil
  end
end

#normalized_queryString

Normalized version of query

Returns:

  • (String)


1160
1161
1162
# File 'lib/rdf/model/uri.rb', line 1160

def normalized_query
  normalize_segment(query, ENCODE_IQUERY) if query
end

#normalized_schemeString

Return normalized version of scheme, if any

Returns:

  • (String)


958
959
960
# File 'lib/rdf/model/uri.rb', line 958

def normalized_scheme
  scheme.strip.downcase if scheme
end

#normalized_userString

Normalized version of user

Returns:

  • (String)


984
985
986
# File 'lib/rdf/model/uri.rb', line 984

def normalized_user
  URI.encode(CGI.unescape(user), ENCODE_USER).force_encoding(Encoding::UTF_8) if user
end

#normalized_userinfoString

Normalized version of userinfo

Returns:

  • (String)


1240
1241
1242
# File 'lib/rdf/model/uri.rb', line 1240

def normalized_userinfo
  normalized_user + (password ? ":#{normalized_password}" : "") if userinfo
end

#objectHash{Symbol => String} Also known as: to_h

Returns object representation of this URI, broken into components

Returns:

  • (Hash{Symbol => String})


879
880
881
# File 'lib/rdf/model/uri.rb', line 879

def object
  @object || @object = parse(@value)
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:



634
635
636
637
638
639
640
641
642
643
644
645
646
# File 'lib/rdf/model/uri.rb', line 634

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

#parent?Boolean Also known as: has_parent?

Returns true if this URI is hierarchical and it's path component isn't equal to /.

Examples:

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

Returns:

  • (Boolean)

    true or false



620
621
622
# File 'lib/rdf/model/uri.rb', line 620

def parent?
  !root?
end

#parse(value) ⇒ Object{Symbol => String}

{ Parse a URI into it's components

Parameters:

  • value (String, to_s)

Returns:

  • (Object{Symbol => String})

See Also:



890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
# File 'lib/rdf/model/uri.rb', line 890

def parse(value)
  value = value.to_s.dup.force_encoding(Encoding::UTF_8) unless value && value.encoding == Encoding::UTF_8
  parts = {}
  if matchdata = FILE_PARTS.match(value)
    # A file-based URI is always in the folloring form:
    # * file:/path  - absolute path, no host name
    # * file:///path - absolute path, empty host name
    # * file://hostname/path - absolute path with authority.
    # * file://path – is invalid, but treated as file:///path
    scheme = 'file'
    authority, path, query, fragment = matchdata[1..-1]
    if authority && authority.match?(/^[A-Za-z]$/) && Gem.win_platform?
      # In this case, if the authority is a drive letter and part of the path
      authority, path = nil, "#{authority}#{path}"
    end
    # We accept paths that aren't absolute, but coerce them to be absolute
    path = "/#{path}" unless path.start_with?('/')
  elsif matchdata = IRI_PARTS.match(value)
    scheme, authority, path, query, fragment = matchdata[1..-1]
    authority = nil if authority && authority.empty?

    if scheme && scheme.match?(/^[A-Za-z]$/) && Gem.win_platform?
      # On Windows treat D:/foo/bar as a path, not a scheme
      scheme, authority, path = 'file', nil, "/#{scheme}:#{path}"
    end
  end

  if matchdata
    userinfo, hostport = authority.to_s.split('@', 2)
    hostport, userinfo = userinfo, nil unless hostport
    user, password = userinfo.to_s.split(':', 2)
    host, port = hostport.to_s.split(':', 2)

    parts[:scheme] = (scheme.dup.force_encoding(Encoding::UTF_8) if scheme)
    parts[:authority] = (authority.dup.force_encoding(Encoding::UTF_8) if authority)
    parts[:userinfo] = (userinfo.dup.force_encoding(Encoding::UTF_8) if userinfo)
    parts[:user] = (user.dup.force_encoding(Encoding::UTF_8) if user)
    parts[:password] = (password.dup.force_encoding(Encoding::UTF_8) if password)
    parts[:host] = (host.dup.force_encoding(Encoding::UTF_8) if host)
    parts[:port] = (CGI.unescape(port).to_i if port)
    parts[:path] = (path.to_s.dup.force_encoding(Encoding::UTF_8) unless path.empty?)
    parts[:query] = (query[1..-1].dup.force_encoding(Encoding::UTF_8) if query)
    parts[:fragment] = (fragment[1..-1].dup.force_encoding(Encoding::UTF_8) if fragment)
  end
  
  parts
end

#passwordString

Returns:

  • (String)


990
991
992
993
994
# File 'lib/rdf/model/uri.rb', line 990

def password
  object.fetch(:password) do
    @object[:password] = (userinfo.split(':', 2)[1] if userinfo)
  end
end

#password=(value) ⇒ RDF::URI

Returns self.

Parameters:

  • value (String, #to_s)

Returns:



999
1000
1001
1002
1003
1004
1005
# File 'lib/rdf/model/uri.rb', line 999

def password=(value)
  object[:password] = (value.to_s.dup.force_encoding(Encoding::UTF_8) if value)
  @object[:userinfo] = format_userinfo("")
  @object[:authority] = format_authority
  @value = nil
  self
end

#pathString

Returns:

  • (String)


1074
1075
1076
1077
1078
# File 'lib/rdf/model/uri.rb', line 1074

def path
  object.fetch(:path) do
    nil
  end
end

#path=(value) ⇒ RDF::URI

Returns self.

Parameters:

  • value (String, #to_s)

Returns:



1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
# File 'lib/rdf/model/uri.rb', line 1083

def path=(value)
  if value
    # Always lead with a slash
    value = "/#{value}" if host && value.to_s.match?(/^[^\/]/)
    object[:path] = value.to_s.dup.force_encoding(Encoding::UTF_8)
  else
    object[:path] = nil
  end
  @value = nil
  self
end

#pname(prefixes: nil) ⇒ String

Returns a Prefixed Name (PName) or the full IRI with any reserved characters in the suffix escaped.

Examples:

Using a custom prefix for creating a PNname.

RDF::URI('http://purl.org/dc/terms/creator').
  pname(prefixes: {dcterms: 'http://purl.org/dc/terms/'})
  #=> "dcterms:creator"

Parameters:

  • prefixes (Hash{Symbol => String}) (defaults to: nil)

    Explicit set of prefixes to look for matches, defaults to loaded vocabularies.

Returns:

  • (String)

    or nil

See Also:



703
704
705
706
707
708
709
710
# File 'lib/rdf/model/uri.rb', line 703

def pname(prefixes: nil)
  q = self.qname(prefixes: prefixes)
  return self.to_s unless q
  prefix, suffix = q
  suffix = suffix.to_s.gsub(PN_ESCAPE_CHARS) {|c| "\\#{c}"} if
    suffix.to_s.match?(PN_ESCAPE_CHARS)
  [prefix, suffix].join(":")
end

#portString

Returns:

  • (String)


1046
1047
1048
1049
1050
# File 'lib/rdf/model/uri.rb', line 1046

def port
  object.fetch(:port) do
    @object[:port] = ($1 if @object[:authority] && PORT_FROM_AUTHORITY_RE.match(@object[:authority]))
  end
end

#port=(value) ⇒ RDF::URI

Returns self.

Parameters:

  • value (String, #to_s)

Returns:



1055
1056
1057
1058
1059
1060
# File 'lib/rdf/model/uri.rb', line 1055

def port=(value)
  object[:port] = (value.to_s.to_i if value)
  @object[:authority] = format_authority
  @value = nil
  self
end

#qname(prefixes: nil) ⇒ Array(Symbol, Symbol)

Note:

within this software, the term QName is used to describe the tuple of prefix and suffix for a given IRI, where the prefix identifies some defined vocabulary. This somewhat contrasts with the notion of a Qualified Name from XML, which are a subset of Prefixed Names.

Returns a qualified name (QName) as a tuple of [prefix, suffix] for this URI based on available vocabularies, if possible.

Examples:

RDF::URI('http://www.w3.org/2000/01/rdf-schema#').qname       #=> [:rdfs, nil]
RDF::URI('http://www.w3.org/2000/01/rdf-schema#label').qname  #=> [:rdfs, :label]
RDF::RDFS.label.qname                                         #=> [:rdfs, :label]
RDF::Vocab::DC.title.qname(
  prefixes: {dcterms: 'http://purl.org/dc/terms/'})           #=> [:dcterms, :title]

Parameters:

  • prefixes (Hash{Symbol => String}) (defaults to: nil)

    Explicit set of prefixes to look for matches, defaults to loaded vocabularies.

Returns:

  • (Array(Symbol, Symbol))

    or nil if no QName found. The suffix component will not have reserved characters escaped.



663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
# File 'lib/rdf/model/uri.rb', line 663

def qname(prefixes: nil)
  if prefixes
    prefixes.each do |prefix, uri|
      return [prefix, self.to_s[uri.length..-1].to_sym] if self.start_with?(uri)
    end
  elsif 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

#queryString

Returns:

  • (String)


1142
1143
1144
1145
1146
# File 'lib/rdf/model/uri.rb', line 1142

def query
  object.fetch(:query) do
    nil
  end
end

#query=(value) ⇒ RDF::URI

Returns self.

Parameters:

  • value (String, #to_s)

Returns:



1151
1152
1153
1154
1155
# File 'lib/rdf/model/uri.rb', line 1151

def query=(value)
  object[:query] = (value.to_s.dup.force_encoding(Encoding::UTF_8) if value)
  @value = nil
  self
end

#query_values(return_type = Hash) ⇒ Hash, Array

Converts the query component to a Hash value.

Examples:

RDF::URI.new("?one=1&two=2&three=3").query_values
#=> {"one" => "1", "two" => "2", "three" => "3"}
RDF::URI.new("?one=two&one=three").query_values(Array)
#=> [["one", "two"], ["one", "three"]]
RDF::URI.new("?one=two&one=three").query_values(Hash)
#=> {"one" => ["two", "three"]}

Parameters:

  • return_type (Class) (defaults to: Hash)

    (Hash) The return type desired. Value must be either # Hash or Array.

Returns:

  • (Hash, Array)

    The query string parsed as a Hash or Array object.

Raises:

  • (ArgumentError)


1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
# File 'lib/rdf/model/uri.rb', line 1258

def query_values(return_type=Hash)
  raise ArgumentError, "Invalid return type. Must be Hash or Array." unless [Hash, Array].include?(return_type)
  return nil if query.nil?
  query.to_s.split('&').
    inject(return_type == Hash ? {} : []) do |memo,kv|
      k,v = kv.to_s.split('=', 2)
      unless k.to_s.empty?
        k = CGI.unescape(k)
        v = CGI.unescape(v) if v
        if return_type == Hash
          case memo[k]
          when nil then memo[k] = v
          when Array then memo[k] << v
          else memo[k] = [memo[k], v]
          end
        else
          memo << [k, v].compact
        end
      end
      memo
    end
end

#query_values=(value) ⇒ Object

Sets the query component for this URI from a Hash object. An empty Hash or Array will result in an empty query string.

Examples:

Hash with single and array values

uri.query_values = {a: "a", b: ["c", "d", "e"]}
uri.query
# => "a=a&b=c&b=d&b=e"

Array with Array values including repeated variables

uri.query_values = [['a', 'a'], ['b', 'c'], ['b', 'd'], ['b', 'e']]
uri.query
# => "a=a&b=c&b=d&b=e"

Array with Array values including multiple elements

uri.query_values = [['a', 'a'], ['b', ['c', 'd', 'e']]]
uri.query
# => "a=a&b=c&b=d&b=e"

Array with Array values having only one entry

uri.query_values = [['flag'], ['key', 'value']]
uri.query
# => "flag&key=value"

Parameters:

  • value (Hash, #to_hash, Array)

    The new query values.



1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
# File 'lib/rdf/model/uri.rb', line 1306

def query_values=(value)
  if value.nil?
    self.query = nil
    return
  end

  value = value.to_hash if value.respond_to?(:to_hash)
  self.query = case value
  when Array, Hash
    value.map do |(k,v)|
      k = normalize_segment(k.to_s, /[^A-Za-z0-9\._~-]/)
      if v.nil?
        k
      else
        Array(v).map do |vv|
          if vv === TrueClass
            k
          else
            "#{k}=#{normalize_segment(vv.to_s, /[^A-Za-z0-9\._~-]/)}"
          end
        end.join("&")
      end
    end
  else
    raise TypeError,
      "Can't convert #{value.class} into Hash."
  end.join("&")
end

#relative?Boolean

A URI is relative when it does not have a scheme

Returns:

  • (Boolean)

    true or false



330
# File 'lib/rdf/model/uri.rb', line 330

def relative?; !absolute?; end

#relativize(base_uri) ⇒ RDF::URI

Attempt to make this URI relative to the provided base_uri. If successful, returns a relative URI, otherwise the original URI

Parameters:

Returns:



335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
# File 'lib/rdf/model/uri.rb', line 335

def relativize(base_uri)
  if self.to_s.start_with?(base_uri.to_s) && %w(# ?).include?(self.to_s[base_uri.to_s.length, 1]) ||
     base_uri.to_s.end_with?("/", "#") &&
     self.to_s.start_with?(base_uri.to_s)
    return RDF::URI(self.to_s[base_uri.to_s.length..-1])
  else
    # Create a list of parents, for which this IRI may be relative.
    u = RDF::URI(base_uri)
    iri_set = u.to_s.end_with?('/') ? [u.to_s] : []
    iri_set << u.to_s while (u = u.parent)
    iri_set.each_with_index do |bb, index|
      next unless self.to_s.start_with?(bb)
      rel = "../" * index + self.to_s[bb.length..-1]
      return rel.empty? ? "./" : rel
    end
  end
  self
end

#request_uriString

The HTTP request URI for this URI. This is the path and the query string.

Returns:

  • (String)

    The request URI required for an HTTP request.



1340
1341
1342
1343
1344
1345
# File 'lib/rdf/model/uri.rb', line 1340

def request_uri
  return nil if absolute? && scheme !~ /^https?$/
  res = path.to_s.empty? ? "/" : path
  res += "?#{self.query}" if self.query
  return res
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:



602
603
604
605
606
607
608
609
610
# File 'lib/rdf/model/uri.rb', line 602

def root
  if root?
    self
  else
    RDF::URI.new(
      **object.merge(path: '/').
      keep_if {|k, v| %i(scheme authority path).include?(k)})
  end
end

#root?Boolean

Returns true if this URI's scheme is not hierarchical, or its path component is equal to /. Protocols not using hierarchical components are always considered to be at the root.

Examples:

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

Returns:

  • (Boolean)

    true or false



590
591
592
# File 'lib/rdf/model/uri.rb', line 590

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

#schemeString

Returns:

  • (String)


940
941
942
943
944
# File 'lib/rdf/model/uri.rb', line 940

def scheme
  object.fetch(:scheme) do
    nil
  end
end

#scheme=(value) ⇒ RDF::URI

Returns self.

Parameters:

  • value (String, #to_s)

Returns:



949
950
951
952
953
# File 'lib/rdf/model/uri.rb', line 949

def scheme=(value)
  object[:scheme] = (value.to_s.dup.force_encoding(Encoding::UTF_8) if value)
  @value = nil
  self
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)


843
# File 'lib/rdf/model/uri.rb', line 843

def to_str; value; end

#to_uriRDF::URI

Returns self.

Returns:



832
833
834
# File 'lib/rdf/model/uri.rb', line 832

def to_uri
  self
end

#uri?Boolean

Returns true.

Returns:

  • (Boolean)

    true or false

See Also:



277
278
279
# File 'lib/rdf/model/uri.rb', line 277

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



318
319
320
# File 'lib/rdf/model/uri.rb', line 318

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



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

def urn?
  @object ? @object[:scheme] == 'urn' : start_with?('urn:')
end

#userString

Returns:

  • (String)


964
965
966
967
968
# File 'lib/rdf/model/uri.rb', line 964

def user
  object.fetch(:user) do
    @object[:user] = (userinfo.split(':', 2)[0] if userinfo)
  end
end

#user=(value) ⇒ RDF::URI

Returns self.

Parameters:

  • value (String, #to_s)

Returns:



973
974
975
976
977
978
979
# File 'lib/rdf/model/uri.rb', line 973

def user=(value)
  object[:user] = (value.to_s.dup.force_encoding(Encoding::UTF_8) if value)
  @object[:userinfo] = format_userinfo("")
  @object[:authority] = format_authority
  @value = nil
  self
end

#userinfoObject

Userinfo is a combination of user and password



1220
1221
1222
1223
1224
# File 'lib/rdf/model/uri.rb', line 1220

def userinfo
  object.fetch(:userinfo) {
    @object[:userinfo] = (format_userinfo("") if @object[:user])
  }
end

#userinfo=(value) ⇒ RDF::URI

Returns self.

Parameters:

  • value (String, #to_s)

Returns:



1229
1230
1231
1232
1233
1234
1235
# File 'lib/rdf/model/uri.rb', line 1229

def userinfo=(value)
  object.delete_if {|k, v| %i(user password authority).include?(k)}
  object[:userinfo] = (value.to_s.dup.force_encoding(Encoding::UTF_8) if value)
  user; password; authority
  @value = nil
  self
end

#valid?Boolean

Determine if the URI is a valid according to RFC3987

Note that RDF URIs syntactically can contain Unicode escapes, which are unencoded in the internal representation. To validate, %-encode specifically excluded characters from IRIREF

Returns:

  • (Boolean)

    true or false

Since:

  • 0.3.9



374
375
376
# File 'lib/rdf/model/uri.rb', line 374

def valid?
  RDF::URI::IRI.match?(to_s) || false
end

#validate!RDF::URI

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

Returns:

Raises:

  • (ArgumentError)

    if the URI is invalid

Since:

  • 0.3.0



384
385
386
387
# File 'lib/rdf/model/uri.rb', line 384

def validate!
  raise ArgumentError, "#{to_base.inspect} is not a valid IRI" if invalid?
  self
end

#valueString

lexical representation of URI, either absolute or relative

Returns:

  • (String)


857
858
859
860
861
862
863
864
865
# File 'lib/rdf/model/uri.rb', line 857

def value
  @value ||= [
    ("#{scheme}:" if absolute?),
    ("//#{authority}" if authority),
    path,
    ("?#{query}" if query),
    ("##{fragment}" if fragment)
  ].compact.join("").freeze
end