Class: ApiHammer::Weblink

Inherits:
Object show all
Defined in:
lib/api_hammer/weblink.rb

Overview

Defined Under Namespace

Classes: Error, NoContextError, ParseError

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(target_uri, attributes, context_uri = nil) ⇒ Weblink

Returns a new instance of Weblink.



54
55
56
57
58
# File 'lib/api_hammer/weblink.rb', line 54

def initialize(target_uri, attributes, context_uri=nil)
  @target_uri = to_addressable_uri(target_uri)
  @attributes = attributes
  @context_uri = to_addressable_uri(context_uri)
end

Instance Attribute Details

#attributesObject (readonly)

link attributes



85
86
87
# File 'lib/api_hammer/weblink.rb', line 85

def attributes
  @attributes
end

#context_uriObject (readonly) Also known as: context_iri

the context uri of the link, as an Addressable URI. this URI must be absolute, and the target_uri may be resolved against it. this is most typically the request URI of a request to a service



62
63
64
# File 'lib/api_hammer/weblink.rb', line 62

def context_uri
  @context_uri
end

#target_uriObject (readonly) Also known as: target_iri

returns the target URI as an Addressable::URI



68
69
70
# File 'lib/api_hammer/weblink.rb', line 68

def target_uri
  @target_uri
end

Class Method Details

parses an array of Web Links from the value an HTTP Link header, as described in https://tools.ietf.org/html/rfc5988#section-5

returns an Array of Weblink objects



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/api_hammer/weblink.rb', line 19

def self.parse_link_value(link_value, context_uri=nil)
  links = []

  return links unless link_value

  attr_char = /[a-zA-Z0-9!#\$&+\-.^_`|~]/ # defined in https://tools.ietf.org/html/rfc5987#section-3.2.1
  ptoken = %r([a-zA-Z0-9!#\$%&'()*+\-./:<=>?@\[\]^_`{|}~])
  quoted_string = /"([^"]*)"/

  require 'strscan'
  ss = StringScanner.new(link_value)
  parse_fail = proc do
    raise ParseError, "Unable to parse link value: #{link_value} " +
      "around character #{ss.pos}: #{ss.peek(link_value.length - ss.pos)}"
  end

  while !ss.eos?
    # get the target_uri, within some angle brackets 
    ss.scan(/\s*<([^>]+)>/) || parse_fail.call
    target_uri = ss[1]
    attributes = {}
    # get the attributes: semicolon, some attr_chars, an optional asterisk, equals, and a quoted 
    # string or series of unquoted ptokens 
    while ss.scan(/\s*;\s*(#{attr_char.source}+\*?)\s*=\s*(?:#{quoted_string.source}|(#{ptoken.source}+))\s*/)
      attributes[ss[1]] = ss[2] || ss[3]
    end
    links << new(target_uri, attributes, context_uri)
    unless ss.eos?
      # either the string ends or has a comma followed by another link 
      ss.scan(/\s*,\s*/) || parse_fail.call
    end
  end
  links
end

Instance Method Details

#[](attribute_key) ⇒ Object

subscript returns an attribute of this Link, if defined, otherwise nil



88
89
90
# File 'lib/api_hammer/weblink.rb', line 88

def [](attribute_key)
  @attributes[attribute_key]
end

#absolute_target_uriObject

attempts to make target_uri absolute, using context_uri if available. raises if there is not information available to make an absolute target URI



74
75
76
77
78
79
80
81
82
# File 'lib/api_hammer/weblink.rb', line 74

def absolute_target_uri
  if target_uri.absolute?
    target_uri
  elsif context_uri
    context_uri + target_uri
  else
    raise NoContextError, "Target URI is relative but no Context URI given - cannot determine absolute target URI"
  end
end

#relObject Also known as: relation_type

link rel attribute



93
94
95
# File 'lib/api_hammer/weblink.rb', line 93

def rel
  self['rel']
end

#rel?(other_rel) ⇒ Boolean

compares relation types in a case-insensitive manner as mandated in https://tools.ietf.org/html/rfc5988#section-4.1

Returns:

  • (Boolean)


100
101
102
# File 'lib/api_hammer/weblink.rb', line 100

def rel?(other_rel)
  rel && other_rel && rel.downcase == other_rel.downcase
end

#to_sObject

a string of this weblink, appropriate for adding to a Link header



105
106
107
# File 'lib/api_hammer/weblink.rb', line 105

def to_s
  "<#{target_uri}>" + attributes.map { |k,v| %Q(; #{k}="#{v}") }.join('')
end