hyperresource 0.2.4 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|