hyperresource 0.2.4 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/hyper_resource.rb +79 -136
- data/lib/hyper_resource/adapter/hal_json.rb +14 -33
- data/lib/hyper_resource/attributes.rb +21 -47
- data/lib/hyper_resource/configuration.rb +159 -0
- data/lib/hyper_resource/exceptions.rb +4 -2
- data/lib/hyper_resource/link.rb +91 -50
- data/lib/hyper_resource/links.rb +42 -36
- data/lib/hyper_resource/modules/config_attributes.rb +293 -0
- data/lib/hyper_resource/modules/data_type.rb +98 -0
- data/lib/hyper_resource/modules/deprecations.rb +56 -0
- data/lib/hyper_resource/modules/http.rb +155 -46
- data/lib/hyper_resource/modules/internal_attributes.rb +7 -18
- data/lib/hyper_resource/objects.rb +10 -29
- data/lib/hyper_resource/version.rb +3 -2
- metadata +24 -6
- data/lib/hyper_resource/response.rb +0 -2
@@ -0,0 +1,159 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'fuzzyurl'
|
3
|
+
|
4
|
+
class HyperResource
|
5
|
+
|
6
|
+
## HyperResource::Configuration is a class which implements a hostmask-
|
7
|
+
## scoped set of configurations. Key/value pairs are stored under hostmasks
|
8
|
+
## like 'api.example.com:8080', 'api.example.com', '*.example.com', or '*'.
|
9
|
+
## Values are retrieved using a hostname and a key, preferring more specific
|
10
|
+
## hostmasks when more than one matching hostmask and key are present.
|
11
|
+
##
|
12
|
+
## HyperResource users are not expected to use this class directly.
|
13
|
+
class Configuration
|
14
|
+
|
15
|
+
## Creates a new HyperResource::Configuration, with the given initial
|
16
|
+
## internal state if provided.
|
17
|
+
def initialize(cfg={})
|
18
|
+
@cfg = cfg
|
19
|
+
@cfg['*'] ||= {}
|
20
|
+
end
|
21
|
+
|
22
|
+
## Returns a deep copy of this object.
|
23
|
+
def clone
|
24
|
+
self.class.new.send(:initialize_copy, self)
|
25
|
+
end
|
26
|
+
|
27
|
+
## Merges a given Configuration with this one. Deep-merges config
|
28
|
+
## attributes correctly.
|
29
|
+
def merge(new)
|
30
|
+
merged_cfg = {}
|
31
|
+
new_cfg = new.send(:cfg)
|
32
|
+
|
33
|
+
(new_cfg.keys | cfg.keys).each do |mask|
|
34
|
+
new_cfg_attrs = new_cfg[mask] || {}
|
35
|
+
cfg_attrs = cfg[mask] || {}
|
36
|
+
merged_cfg[mask] = {}
|
37
|
+
|
38
|
+
## Do a hash merge when it makes sense, except when it doesn't.
|
39
|
+
(new_cfg_attrs.keys | cfg_attrs.keys).each do |attr|
|
40
|
+
if !(%w(namespace adapter).include?(attr)) &&
|
41
|
+
((!cfg_attrs[attr] || cfg_attrs[attr].kind_of?(Hash)) &&
|
42
|
+
(!new_cfg_attrs[attr] || new_cfg_attrs[attr].kind_of?(Hash)))
|
43
|
+
merged_cfg[mask][attr] =
|
44
|
+
(cfg_attrs[attr] || {}).merge(new_cfg_attrs[attr] || {})
|
45
|
+
else
|
46
|
+
merged_cfg[mask][attr] = new_cfg_attrs[attr] || cfg_attrs[attr]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
self.class.new(merged_cfg)
|
51
|
+
end
|
52
|
+
|
53
|
+
## Applies a given Configuration on top of this one.
|
54
|
+
def merge!(new)
|
55
|
+
initialize_copy(merge(new))
|
56
|
+
end
|
57
|
+
|
58
|
+
## Applies a given Hash of configurations on top of this one.
|
59
|
+
def config(hash)
|
60
|
+
merge!(self.class.new(hash))
|
61
|
+
end
|
62
|
+
|
63
|
+
## Returns this object as a Hash.
|
64
|
+
def as_hash
|
65
|
+
clone.send(:cfg)
|
66
|
+
end
|
67
|
+
|
68
|
+
## Returns the value for a particular hostmask and key, or nil if not
|
69
|
+
## present.
|
70
|
+
def get(mask, key)
|
71
|
+
cfg[mask] ||= {}
|
72
|
+
cfg[mask][key.to_s]
|
73
|
+
end
|
74
|
+
|
75
|
+
## Sets a key and value pair for the given hostmask.
|
76
|
+
def set(mask, key, value)
|
77
|
+
cfg[mask] ||= {}
|
78
|
+
cfg[mask][key.to_s] = value
|
79
|
+
end
|
80
|
+
|
81
|
+
## Returns the best matching value for the given URL and key, or nil
|
82
|
+
## otherwise.
|
83
|
+
def get_for_url(url, key)
|
84
|
+
subconfig_for_url(url)[key.to_s]
|
85
|
+
end
|
86
|
+
|
87
|
+
## Sets a key and value pair, using the given URL as the basis of the
|
88
|
+
## hostmask. Path, query, and fragment are ignored.
|
89
|
+
def set_for_url(url, key, value)
|
90
|
+
furl = FuzzyURL.new(url || '*')
|
91
|
+
furl.path = nil
|
92
|
+
furl.query = nil
|
93
|
+
furl.fragment = nil
|
94
|
+
set(furl.to_s, key, value)
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
## Returns hostmasks from our config which match the given url.
|
99
|
+
def matching_masks_for_url(url)
|
100
|
+
url = url.to_s
|
101
|
+
return ['*'] if !url || cfg.keys.count == 1
|
102
|
+
@masks ||= {} ## key = mask string, value = FuzzyURL
|
103
|
+
cfg.keys.each {|key| @masks[key] ||= FuzzyURL.new(key) }
|
104
|
+
|
105
|
+
## Test for matches, and sort by score.
|
106
|
+
scores = {}
|
107
|
+
cfg.keys.each {|key| scores[key] = @masks[key].match(url) }
|
108
|
+
scores = Hash[ scores.select{|k,v| v} ] # remove nils
|
109
|
+
scores.keys.sort_by{|k| [-scores[k], -k.length]} ## TODO length is cheesy
|
110
|
+
end
|
111
|
+
|
112
|
+
private
|
113
|
+
|
114
|
+
def cfg
|
115
|
+
@cfg
|
116
|
+
end
|
117
|
+
|
118
|
+
## Performs a two-level-deep copy of old @cfg.
|
119
|
+
def initialize_copy(old)
|
120
|
+
old.send(:cfg).each do |mask, old_subcfg|
|
121
|
+
new_subcfg = {}
|
122
|
+
old_subcfg.each do |key, value|
|
123
|
+
if value.kind_of?(Array) || value.kind_of?(Hash)
|
124
|
+
value = value.clone
|
125
|
+
end
|
126
|
+
new_subcfg[key] = value
|
127
|
+
end
|
128
|
+
@cfg[mask] = new_subcfg
|
129
|
+
end
|
130
|
+
self
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
## Returns a merged subconfig consisting of all matching hostmask
|
135
|
+
## subconfigs, giving priority to more specific hostmasks.
|
136
|
+
def subconfig_for_url(url)
|
137
|
+
matching_masks_for_url(url).inject({}) do |subcfg, mask|
|
138
|
+
(cfg[mask] || {}).merge(subcfg)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
## Returns the hostmasks which match the given url, sorted best match
|
143
|
+
## first.
|
144
|
+
def get_possible_masks_for_host(host, port=80, masks=nil)
|
145
|
+
masks ||= ["#{host}:#{port}", host] ## exact matches first
|
146
|
+
host_parts = host.split('.')
|
147
|
+
|
148
|
+
if host_parts.count < 2
|
149
|
+
masks << '*' ## wildcard match last
|
150
|
+
else
|
151
|
+
parent_domain = host_parts[1..-1].join('.')
|
152
|
+
masks << '*.' + parent_domain
|
153
|
+
get_possible_masks_for_host(parent_domain, port, masks)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
@@ -3,7 +3,8 @@ class HyperResource
|
|
3
3
|
## The internal exception which led to this one, if any.
|
4
4
|
attr_accessor :cause
|
5
5
|
|
6
|
-
|
6
|
+
# @private
|
7
|
+
def initialize(message, attrs={})
|
7
8
|
self.cause = attrs[:cause]
|
8
9
|
super(message)
|
9
10
|
end
|
@@ -17,7 +18,8 @@ class HyperResource
|
|
17
18
|
## May be blank, e.g. in case of deserialization errors.
|
18
19
|
attr_accessor :body
|
19
20
|
|
20
|
-
|
21
|
+
# @private
|
22
|
+
def initialize(message, attrs={})
|
21
23
|
self.response = attrs[:response]
|
22
24
|
self.body = attrs[:body]
|
23
25
|
|
data/lib/hyper_resource/link.rb
CHANGED
@@ -1,59 +1,100 @@
|
|
1
1
|
require 'uri_template'
|
2
|
+
require 'hyper_resource/modules/http'
|
2
3
|
|
3
|
-
class HyperResource
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
##
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
4
|
+
class HyperResource
|
5
|
+
|
6
|
+
## HyperResource::Link is an object to represent a hyperlink and its
|
7
|
+
## URL or body parameters, and to encapsulate HTTP calls involving this
|
8
|
+
## link. Links are typically created by HyperResource, not by end users.
|
9
|
+
##
|
10
|
+
## HTTP method calls return the response as a HyperResource (or subclass)
|
11
|
+
## object. Calling an unrecognized method on a link will automatically
|
12
|
+
## load the resource pointed to by this link, and repeat the method call
|
13
|
+
## on the resource object.
|
14
|
+
##
|
15
|
+
## A HyperResource::Link requires the resource it is based upon to remain
|
16
|
+
## in scope. In practice this is rarely a problem, as links are almost
|
17
|
+
## always accessed through the resource object.
|
18
|
+
|
19
|
+
class Link
|
20
|
+
|
21
|
+
include HyperResource::Modules::HTTP
|
22
|
+
|
23
|
+
## The literal href of this link; may be templated.
|
24
|
+
attr_accessor :base_href
|
25
|
+
|
26
|
+
## An optional name describing this link.
|
27
|
+
attr_accessor :name
|
28
|
+
|
29
|
+
## `true` if this link's href is a URI Template, `false` otherwise.
|
30
|
+
attr_accessor :templated
|
31
|
+
|
32
|
+
## A hash of URL or request body parameters.
|
33
|
+
attr_accessor :params
|
34
|
+
|
35
|
+
## Default HTTP method for implicit loading.
|
36
|
+
attr_accessor :default_method
|
37
|
+
|
38
|
+
## The resource from which this link originates.
|
39
|
+
attr_accessor :resource
|
40
|
+
|
41
|
+
## Returns a link based on the given resource and link specification
|
42
|
+
## hash. `link_spec` keys are: `href` (string, required), `templated`
|
43
|
+
## (boolean), `params` (hash), and `default_method` (string, default
|
44
|
+
## `"get"`).
|
45
|
+
def initialize(resource, link_spec={})
|
46
|
+
unless link_spec.kind_of?(Hash)
|
47
|
+
raise ArgumentError, "link_spec must be a Hash (got #{link_spec.inspect})"
|
48
|
+
end
|
49
|
+
link_spec = Hash[ link_spec.map{|(k,v)| [k.to_s, v]} ] ## stringify keys
|
20
50
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
self.base_href
|
51
|
+
self.resource = resource
|
52
|
+
self.base_href = link_spec['href']
|
53
|
+
self.name = link_spec['name']
|
54
|
+
self.templated = !!link_spec['templated']
|
55
|
+
self.params = link_spec['params'] || {}
|
56
|
+
self.default_method = link_spec['method'] || 'get'
|
28
57
|
end
|
29
|
-
end
|
30
58
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
59
|
+
## Returns this link's href, applying any URI template params.
|
60
|
+
def href
|
61
|
+
if self.templated
|
62
|
+
filtered_params = self.resource.outgoing_uri_filter(params)
|
63
|
+
URITemplate.new(self.base_href).expand(filtered_params)
|
64
|
+
else
|
65
|
+
self.base_href
|
66
|
+
end
|
67
|
+
end
|
41
68
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
69
|
+
## Returns this link's fully resolved URL, or nil if `resource.root`
|
70
|
+
## or `href` are malformed.
|
71
|
+
def url
|
72
|
+
begin
|
73
|
+
URI.join(self.resource.root, self.href.to_s).to_s
|
74
|
+
rescue StandardError
|
75
|
+
nil
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
## Returns a new scope with the given params; that is, returns a copy of
|
80
|
+
## itself with the given params applied.
|
81
|
+
def where(params)
|
82
|
+
params = Hash[ params.map{|(k,v)| [k.to_s, v]} ]
|
83
|
+
self.class.new(self.resource,
|
84
|
+
'href' => self.base_href,
|
85
|
+
'name' => self.name,
|
86
|
+
'templated' => self.templated,
|
87
|
+
'params' => self.params.merge(params),
|
88
|
+
'method' => self.default_method)
|
89
|
+
end
|
90
|
+
|
91
|
+
## Unrecognized methods invoke an implicit load of the resource pointed
|
92
|
+
## to by this link. The method call is then repeated on the returned
|
93
|
+
## resource.
|
94
|
+
def method_missing(method, *args)
|
95
|
+
self.send(default_method || :get).send(method, *args)
|
96
|
+
end
|
46
97
|
|
47
|
-
## Delegate HTTP methods to the resource.
|
48
|
-
def get(*args); self.resource.get(*args) end
|
49
|
-
def post(*args); self.resource.post(*args) end
|
50
|
-
def patch(*args); self.resource.patch(*args) end
|
51
|
-
def put(*args); self.resource.put(*args) end
|
52
|
-
def delete(*args); self.resource.delete(*args) end
|
53
|
-
|
54
|
-
## If we were called with a method we don't know, load this resource
|
55
|
-
## and pass the message along. This achieves implicit loading.
|
56
|
-
def method_missing(method, *args)
|
57
|
-
self.get.send(method, *args)
|
58
98
|
end
|
59
99
|
end
|
100
|
+
|
data/lib/hyper_resource/links.rb
CHANGED
@@ -1,52 +1,53 @@
|
|
1
1
|
class HyperResource
|
2
|
+
|
3
|
+
## HyperResource::Links is a modified Hash that permits lookup
|
4
|
+
## of a link by its link relation (rel), or an abbreviation thereof.
|
5
|
+
## It also provides read access through `method_missing`.
|
6
|
+
## It is typically created by HyperResource, not by end users.
|
7
|
+
##
|
8
|
+
## For example, a link with rel `someapi:widgets` is accessible
|
9
|
+
## by any of `self.widgets`, `self['widgets']`, `self[:widgets]`, and
|
10
|
+
## `self['someapi:widgets'].
|
2
11
|
class Links < Hash
|
3
|
-
attr_accessor :_resource
|
4
12
|
|
13
|
+
# @private
|
5
14
|
def initialize(resource=nil)
|
6
|
-
|
15
|
+
## We used to store the resource, but we didn't need to. Now we don't.
|
7
16
|
end
|
8
17
|
|
9
|
-
##
|
10
|
-
##
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
if args.count > 0
|
22
|
-
self[attr].where(*args)
|
23
|
-
else
|
24
|
-
self[attr]
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
## Don't stomp on _resource's methods
|
29
|
-
unless _resource.respond_to?(attr_sym)
|
30
|
-
_resource.class.send(:define_method, attr_sym) do |*args|
|
31
|
-
links.send(attr_sym, *args)
|
32
|
-
end
|
33
|
-
end
|
18
|
+
## Stores a link for future retrieval by its link rel or abbreviations
|
19
|
+
## thereof.
|
20
|
+
def []=(rel, link)
|
21
|
+
rel = rel.to_s
|
22
|
+
|
23
|
+
## Every link must appear under its literal name.
|
24
|
+
names = [rel]
|
25
|
+
|
26
|
+
## Extract 'foo' from e.g. 'http://example.com/foo',
|
27
|
+
## 'http://example.com/url#foo', 'somecurie:foo'.
|
28
|
+
if m=rel.match(%r{[:/#](.+)})
|
29
|
+
names << m[1]
|
34
30
|
end
|
35
31
|
|
36
|
-
|
37
|
-
|
32
|
+
## Underscore all non-word characters.
|
33
|
+
underscored_names = names.map{|n| n.gsub(/[^a-zA-Z_]/, '_')}
|
34
|
+
names = (names + underscored_names).uniq
|
38
35
|
|
39
|
-
|
40
|
-
|
36
|
+
## Register this link under every name we've come up with.
|
37
|
+
names.each do |name|
|
38
|
+
super(name, link)
|
39
|
+
end
|
41
40
|
end
|
42
41
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
nil
|
42
|
+
## Retrieves a link by its rel.
|
43
|
+
def [](rel)
|
44
|
+
super(rel.to_s)
|
47
45
|
end
|
48
46
|
|
49
|
-
|
47
|
+
## Provides links.somelink(:a => b) to links.somelink.where(:a => b)
|
48
|
+
## expansion.
|
49
|
+
# @private
|
50
|
+
def method_missing(method, *args)
|
50
51
|
unless self[method]
|
51
52
|
raise NoMethodError, "undefined method `#{method}' for #{self.inspect}"
|
52
53
|
end
|
@@ -58,6 +59,11 @@ class HyperResource
|
|
58
59
|
end
|
59
60
|
end
|
60
61
|
|
62
|
+
# @private
|
63
|
+
def respond_to?(method, *args)
|
64
|
+
return true if self.has_key?(method.to_s)
|
65
|
+
super
|
66
|
+
end
|
61
67
|
end
|
62
68
|
end
|
63
69
|
|
@@ -0,0 +1,293 @@
|
|
1
|
+
class HyperResource
|
2
|
+
module Modules
|
3
|
+
module ConfigAttributes
|
4
|
+
|
5
|
+
ATTRS = [:auth, :headers, :namespace, :adapter, :faraday_options]
|
6
|
+
|
7
|
+
def self.included(klass)
|
8
|
+
klass.extend(ClassMethods)
|
9
|
+
end
|
10
|
+
|
11
|
+
# @private
|
12
|
+
def hr_config
|
13
|
+
@hr_config ||= self.class::Configuration.new
|
14
|
+
end
|
15
|
+
|
16
|
+
# @private
|
17
|
+
def hr_config=(cfg)
|
18
|
+
@hr_config = cfg
|
19
|
+
end
|
20
|
+
|
21
|
+
## When called with no arguments, returns this resource's Configuration.
|
22
|
+
## When called with a hash, applies the given configuration parameters
|
23
|
+
## to this resource's Configuration. `hash` must be in the form:
|
24
|
+
## {'hostmask' => {'attr1' => {...}, 'attr2' => {...}, ...}}
|
25
|
+
## Valid attributes are `auth`, `headers`, `namespace`, `adapter`,
|
26
|
+
## `default_attributes`, and `faraday_options`.
|
27
|
+
def config(hash=nil)
|
28
|
+
return hr_config unless hash
|
29
|
+
hr_config.config(hash)
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
## Returns the auth config hash for this resource.
|
34
|
+
def auth
|
35
|
+
cfg_get(:auth)
|
36
|
+
end
|
37
|
+
|
38
|
+
## Returns the auth config hash for the given url.
|
39
|
+
def auth_for_url(url)
|
40
|
+
self.hr_config.get_for_url(url, :auth)
|
41
|
+
end
|
42
|
+
|
43
|
+
## Sets the auth config hash for this resource.
|
44
|
+
## Currently only the format `{:basic => ['username', 'password']}`
|
45
|
+
## is supported.
|
46
|
+
def auth=(v)
|
47
|
+
cfg_set(:auth, v)
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
## Returns the headers hash for this resource.
|
52
|
+
## This is done by merging all applicable header configs.
|
53
|
+
def headers
|
54
|
+
matching_masks = self.hr_config.matching_masks_for_url(self.url)
|
55
|
+
matching_masks.inject({}) do |hash, mask|
|
56
|
+
hash.merge(self.hr_config.get(mask, 'headers') || {})
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
## Returns the headers hash for the given url.
|
61
|
+
def headers_for_url(url)
|
62
|
+
self.hr_config.get_for_url(url, :headers)
|
63
|
+
end
|
64
|
+
|
65
|
+
## Sets the headers hash for this resource.
|
66
|
+
def headers=(v)
|
67
|
+
cfg_set(:headers, v)
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
## Returns the namespace string/class for this resource.
|
72
|
+
def namespace
|
73
|
+
cfg_get(:namespace)
|
74
|
+
end
|
75
|
+
|
76
|
+
## Returns the namespace string/class for the given url.
|
77
|
+
def namespace_for_url(url)
|
78
|
+
self.hr_config.get_for_url(url, :namespace)
|
79
|
+
end
|
80
|
+
|
81
|
+
## Sets the namespace string/class for this resource.
|
82
|
+
def namespace=(v)
|
83
|
+
cfg_set(:namespace, v)
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
## Returns the adapter class for this resource.
|
88
|
+
def adapter
|
89
|
+
cfg_get(:adapter) ||
|
90
|
+
HyperResource::Adapter::HAL_JSON
|
91
|
+
end
|
92
|
+
|
93
|
+
## Returns the adapter class for the given url.
|
94
|
+
def adapter_for_url(url)
|
95
|
+
self.hr_config.get_for_url(url, :adapter) ||
|
96
|
+
HyperResource::Adapter::HAL_JSON
|
97
|
+
end
|
98
|
+
|
99
|
+
## Sets the adapter class for this resource.
|
100
|
+
def adapter=(v)
|
101
|
+
cfg_set(:adapter, v)
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
## Returns the hash of default attributes for this resource.
|
106
|
+
def default_attributes
|
107
|
+
cfg_get(:default_attributes)
|
108
|
+
end
|
109
|
+
|
110
|
+
## Returns the hash of default attributes for the given url.
|
111
|
+
def default_attributes_for_url(url)
|
112
|
+
self.hr_config.get_for_url(url, :default_attributes)
|
113
|
+
end
|
114
|
+
|
115
|
+
## Sets the hash of default attributes for this resource.
|
116
|
+
## These attributes will be passed along with every HTTP request.
|
117
|
+
def default_attributes=(v)
|
118
|
+
cfg_set(:default_attributes, v)
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
## Returns the Faraday connection options hash for this resource.
|
123
|
+
def faraday_options
|
124
|
+
cfg_get(:faraday_options)
|
125
|
+
end
|
126
|
+
|
127
|
+
## Returns the Faraday connection options hash for this resource.
|
128
|
+
def faraday_options_for_url(url)
|
129
|
+
self.hr_config.get_for_url(url, :faraday_options)
|
130
|
+
end
|
131
|
+
|
132
|
+
## Sets the Faraday connection options hash for this resource.
|
133
|
+
## These options will be used for all HTTP requests.
|
134
|
+
def faraday_options=(v)
|
135
|
+
cfg_set(:faraday_options, v)
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
private
|
140
|
+
|
141
|
+
def cfg_get(key)
|
142
|
+
hr_config.get_for_url(self.url, key) ||
|
143
|
+
self.class.hr_config.get_for_url(self.url, key)
|
144
|
+
end
|
145
|
+
|
146
|
+
## Sets a config key-value pair for this resource.
|
147
|
+
def cfg_set(key, value)
|
148
|
+
hr_config.set_for_url(url.to_s, key, value)
|
149
|
+
end
|
150
|
+
|
151
|
+
public
|
152
|
+
|
153
|
+
module ClassMethods
|
154
|
+
|
155
|
+
def hr_config
|
156
|
+
@hr_config ||= self::Configuration.new
|
157
|
+
end
|
158
|
+
|
159
|
+
## When called with no arguments, returns this class's Configuration.
|
160
|
+
## When called with a hash, applies the given configuration parameters
|
161
|
+
## to this resource's Configuration. `hash` must be in the form:
|
162
|
+
## {'hostmask' => {'key1' => 'value1', 'key2' => 'value2', ...}}
|
163
|
+
## Valid keys are `auth`, `headers`, `namespace`, `adapter`, and
|
164
|
+
## `faraday_options`.
|
165
|
+
def config(hash=nil)
|
166
|
+
return hr_config unless hash
|
167
|
+
hr_config.config(hash)
|
168
|
+
end
|
169
|
+
|
170
|
+
|
171
|
+
## Returns the auth config hash for this resource class.
|
172
|
+
def auth
|
173
|
+
cfg_get(:auth)
|
174
|
+
end
|
175
|
+
|
176
|
+
## Returns the auth config hash for the given url.
|
177
|
+
def auth_for_url(url)
|
178
|
+
self.hr_config.get_for_url(url, :auth)
|
179
|
+
end
|
180
|
+
|
181
|
+
## Sets the auth config hash for this resource class.
|
182
|
+
## Currently only the format `{:basic => ['username', 'password']}`
|
183
|
+
## is supported.
|
184
|
+
def auth=(v)
|
185
|
+
cfg_set(:auth, v)
|
186
|
+
end
|
187
|
+
|
188
|
+
|
189
|
+
## Returns the headers hash for this resource class.
|
190
|
+
def headers
|
191
|
+
cfg_get(:headers)
|
192
|
+
end
|
193
|
+
|
194
|
+
## Returns the headers hash for the given url.
|
195
|
+
def headers_for_url(url)
|
196
|
+
self.hr_config.get_for_url(url, :headers)
|
197
|
+
end
|
198
|
+
|
199
|
+
## Sets the headers hash for this resource class.
|
200
|
+
def headers=(v)
|
201
|
+
cfg_set(:headers, v)
|
202
|
+
end
|
203
|
+
|
204
|
+
|
205
|
+
## Returns the namespace string/class for this resource class.
|
206
|
+
def namespace
|
207
|
+
cfg_get(:namespace)
|
208
|
+
end
|
209
|
+
|
210
|
+
## Returns the namespace string/class for the given url.
|
211
|
+
def namespace_for_url(url)
|
212
|
+
self.hr_config.get_for_url(url, :namespace)
|
213
|
+
end
|
214
|
+
|
215
|
+
## Sets the namespace string/class for this resource class.
|
216
|
+
def namespace=(v)
|
217
|
+
cfg_set(:namespace, v)
|
218
|
+
end
|
219
|
+
|
220
|
+
|
221
|
+
## Returns the adapter class for this resource class.
|
222
|
+
def adapter
|
223
|
+
cfg_get(:adapter) || HyperResource::Adapter::HAL_JSON
|
224
|
+
end
|
225
|
+
|
226
|
+
## Returns the adapter class for the given url.
|
227
|
+
def adapter_for_url(url)
|
228
|
+
self.hr_config.get_for_url(url, :adapter) ||
|
229
|
+
HyperResource::Adapter::HAL_JSON
|
230
|
+
end
|
231
|
+
|
232
|
+
## Sets the adapter class for this resource class.
|
233
|
+
def adapter=(v)
|
234
|
+
cfg_set(:adapter, v)
|
235
|
+
end
|
236
|
+
|
237
|
+
|
238
|
+
## Returns the hash of default attributes for this resource class.
|
239
|
+
def default_attributes
|
240
|
+
cfg_get(:default_attributes)
|
241
|
+
end
|
242
|
+
|
243
|
+
## Returns the hash of default attributes for the given url.
|
244
|
+
def default_attributes_for_url(url)
|
245
|
+
self.hr_config.get_for_url(url, :default_attributes)
|
246
|
+
end
|
247
|
+
|
248
|
+
## Sets the hash of default attributes for this resource class.
|
249
|
+
## These attributes will be passed along with every HTTP request.
|
250
|
+
def default_attributes=(v)
|
251
|
+
cfg_set(:default_attributes, v)
|
252
|
+
end
|
253
|
+
|
254
|
+
|
255
|
+
## Returns the Faraday connection options hash for this resource class.
|
256
|
+
def faraday_options
|
257
|
+
cfg_get(:faraday_options)
|
258
|
+
end
|
259
|
+
|
260
|
+
## Returns the Faraday connection options hash for this resource class.
|
261
|
+
def faraday_options_for_url(url)
|
262
|
+
self.hr_config.get_for_url(url, :faraday_options)
|
263
|
+
end
|
264
|
+
|
265
|
+
## Sets the Faraday connection options hash for this resource class.
|
266
|
+
## These options will be used for all HTTP requests.
|
267
|
+
def faraday_options=(v)
|
268
|
+
cfg_set(:faraday_options, v)
|
269
|
+
end
|
270
|
+
|
271
|
+
|
272
|
+
private
|
273
|
+
|
274
|
+
def cfg_get(key)
|
275
|
+
value = hr_config.get_for_url(self.root, key)
|
276
|
+
if value != nil
|
277
|
+
value
|
278
|
+
elsif superclass.respond_to?(:hr_config)
|
279
|
+
superclass.hr_config.get_for_url(self.root, key)
|
280
|
+
else
|
281
|
+
nil
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
def cfg_set(key, value)
|
286
|
+
hr_config.set_for_url(self.root, key, value)
|
287
|
+
end
|
288
|
+
|
289
|
+
end
|
290
|
+
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|