Class: PathTo::DescribedRoutes::Application
- Inherits:
-
WithParams
- Object
- WithParams
- PathTo::DescribedRoutes::Application
- Defined in:
- lib/path-to/described_routes.rb
Overview
DescribedRoutes implementation of PathTo::Application.
Instance Attribute Summary collapse
-
#base ⇒ Object
readonly
Base URI of the application.
-
#default_type ⇒ Object
readonly
A Class (or at least something with a #new method) from which child objects will be created.
-
#http_client ⇒ Object
readonly
An HTTParty or similar.
-
#http_options ⇒ Object
readonly
Hash of options to be included in HTTP method calls.
-
#resource_templates ⇒ Object
readonly
An Array of DescribedRoutes::Resource objects.
Attributes inherited from WithParams
Class Method Summary collapse
Instance Method Summary collapse
-
#[](params) ⇒ Object
Creates a copy of self with additional params.
-
#application ⇒ Object
Returns self.
-
#child_class_for(instance, method, params, template) ⇒ Object
Determines whether this application &/or its child objects should respond to the given method, and if so returns a class from which a new child instance (typically Path or a subclass thereof) will be created.
-
#initialize(options) ⇒ Application
constructor
A new instance of Application.
-
#method_missing(method, *args) ⇒ Object
Tries to respond to a missing method.
-
#resource_templates_by_name ⇒ Object
Returns a hash of all ResourceTemplates (the tree flattened) keyed by name.
Methods inherited from WithParams
#child, #complete_params_hash!, #extract_params, #respond_to?
Constructor Details
#initialize(options) ⇒ Application
Returns a new instance of Application.
190 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 |
# File 'lib/path-to/described_routes.rb', line 190 def initialize() super([:parent], [:service], [:params]) @base = [:base] @base.sub(/\/$/, '') if base @default_type = [:default_type] || TemplatedPath @http_client = [:http_client] || HTTPClient @http_options = [:http_options] @resource_templates = [:resource_templates] unless @resource_templates if (json = [:json]) @resource_templates = ResourceTemplate::ResourceTemplates.new(JSON.parse(json)) elsif (yaml = [:yaml]) @resource_templates = ResourceTemplate::ResourceTemplates.new(YAML.load(yaml)) elsif (xml = [:xml]) @resource_templates = ResourceTemplate::ResourceTemplates.parse_xml(xml) end end if parent @base ||= parent.base @default_type ||= parent.default_type @http_client ||= parent.http_client @resource_templates ||= parent.resource_templates @http_options ||= parent. end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args) ⇒ Object
Tries to respond to a missing method. We can do so if
-
we have a resource template matching the method name
-
#child_class_for returns a class or other factory object capable of creating a new child instance
Otherwise we invoke super in the hope of avoiding any hard-to-debug behaviour!
234 235 236 237 238 239 240 241 242 243 |
# File 'lib/path-to/described_routes.rb', line 234 def method_missing(method, *args) child_resource_template = resource_templates_by_name[method.to_s] if child_resource_template && (child_class = child_class_for(self, method, params, child_resource_template)) positional_params, params_hash = extract_params(args, params) complete_params_hash!(params_hash, child_resource_template.positional_params(nil), positional_params) child(child_class, method, params_hash, child_resource_template) else super end end |
Instance Attribute Details
#base ⇒ Object (readonly)
Base URI of the application
138 139 140 |
# File 'lib/path-to/described_routes.rb', line 138 def base @base end |
#default_type ⇒ Object (readonly)
A Class (or at least something with a #new method) from which child objects will be created
132 133 134 |
# File 'lib/path-to/described_routes.rb', line 132 def default_type @default_type end |
#http_client ⇒ Object (readonly)
An HTTParty or similar
135 136 137 |
# File 'lib/path-to/described_routes.rb', line 135 def http_client @http_client end |
#http_options ⇒ Object (readonly)
Hash of options to be included in HTTP method calls
141 142 143 |
# File 'lib/path-to/described_routes.rb', line 141 def @http_options end |
#resource_templates ⇒ Object (readonly)
An Array of DescribedRoutes::Resource objects
129 130 131 |
# File 'lib/path-to/described_routes.rb', line 129 def resource_templates @resource_templates end |
Class Method Details
.discover(url, options = {}) ⇒ Object
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/path-to/described_routes.rb', line 143 def self.discover(url, ={}) = [:http_options] || nil default_type = [:default_type] || Path http_client = [:http_client] || HTTPClient = self.(url, http_client) unless raise ProtocolError.new("no metadata link found") end json = http_client.get(.href, :format => :text, :headers => {"Accept" => "application/json"}) unless json raise ProtocolError.new("no json found") end self.new(.merge(:json => json)) end |
.discover_metadata_link(url, http_client) ⇒ Object
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/path-to/described_routes.rb', line 161 def self.(url, http_client) response = http_client.head(url, {"Accept" => "application/json"}) unless response.kind_of?(Net::HTTPOK) raise ProtocolError.new("got response #{response.inspect} from #{url}") end link_header = LinkHeader.parse(response["Link"]) app_templates_link = link_header.find_link(["rel", "describedby"], ["meta", "ResourceTemplates"]) unless app_templates_link resource_template_link = link_header.find_link(["rel", "describedby"], ["meta", "ResourceTemplate"]) if resource_template_link response = http_client.head(resource_template_link.href, {"Accept" => "application/json"}) unless response.kind_of?(Net::HTTPOK) raise ProtocolError.new("got response #{response.inspect} from #{url}") end link_header = LinkHeader.parse(response["Link"]) app_templates_link = link_header.find_link(["rel", "index"], ["meta", "ResourceTemplates"]) unless app_templates_link raise ProtocolError.new("(2) couldn't find link with rel=\"index\" and meta=\"ResourceTemplates\" at #{resource_template_link.href}") end else unless app_templates_link raise ProtocolError.new("(1) couldn't find link with rel=\"described_by\" and meta=\"ResourceTemplates\" or meta=\"ResourceTemplate\" at #{url}") end end end app_templates_link end |
Instance Method Details
#[](params) ⇒ Object
Creates a copy of self with additional params
222 223 224 |
# File 'lib/path-to/described_routes.rb', line 222 def [](params) self.class.new(:parent => self, :params => params) end |
#application ⇒ Object
Returns self. See TemplatedPath#application.
270 271 272 |
# File 'lib/path-to/described_routes.rb', line 270 def application self end |
#child_class_for(instance, method, params, template) ⇒ Object
Determines whether this application &/or its child objects should respond to the given method, and if so returns a class from which a new child instance (typically Path or a subclass thereof) will be created. This implementation (easily overridden) returns #default_type if there is a URI template defined for the method.
Parameters:
- instance
-
This application or (presumably) one of its child objects
- method
-
The method invoked on the instance that has (presumably) been intercepted by instance#method_missing
- params
-
The instance’s params
256 257 258 |
# File 'lib/path-to/described_routes.rb', line 256 def child_class_for(instance, method, params, template) default_type end |
#resource_templates_by_name ⇒ Object
Returns a hash of all ResourceTemplates (the tree flattened) keyed by name
263 264 265 |
# File 'lib/path-to/described_routes.rb', line 263 def resource_templates_by_name @resource_templates_by_name ||= resource_templates.all_by_name end |