Module: Spider::Dispatcher
- Included in:
- Controller, Router
- Defined in:
- lib/spiderfw/controller/dispatcher.rb
Overview
The includer of this module has to define a method dispatched_object, which must return a child object given the class, the next action, and the route parameters
Defined Under Namespace
Modules: ClassMethods Classes: Route
Instance Attribute Summary collapse
-
#dispatch_previous ⇒ Object
Returns the value of attribute dispatch_previous.
Class Method Summary collapse
Instance Method Summary collapse
- #add_chain_item(method, proc, params) ⇒ Object
-
#can_dispatch?(method, action) ⇒ Boolean
Returns true if there is a route for action, and the routed object responds to method.
-
#dispatch(method, action = '', *arguments) ⇒ Object
Given a method and an action, returns a triplet containing - the object on which to call the method - the new action - the new arguments.
- #dispatch_chain(method) ⇒ Object
-
#dispatch_next(path) ⇒ Object
Returns the (possibly cached) route for path.
- #dispatcher_get_route(path) ⇒ Object
-
#do_dispatch(method, action = '', *arguments) ⇒ Object
Dispatches the given method and action: will get an object and new action and arguments from #dispatch, and then call the method on the object, with new action and new arguments as params.
-
#get_route(path) ⇒ Object
Looks in defined routes, and returns the first matching Route for path.
-
#route(path, dest = nil, options = nil) ⇒ Object
Adds one or more routes to the dispatcher.
-
#routes ⇒ Object
Defined routes.
- #run_chain(method, action = '', *params) ⇒ Object
Instance Attribute Details
#dispatch_previous ⇒ Object
Returns the value of attribute dispatch_previous.
6 7 8 |
# File 'lib/spiderfw/controller/dispatcher.rb', line 6 def dispatch_previous @dispatch_previous end |
Class Method Details
.included(klass) ⇒ Object
8 9 10 |
# File 'lib/spiderfw/controller/dispatcher.rb', line 8 def self.included(klass) klass.extend(ClassMethods) end |
Instance Method Details
#add_chain_item(method, proc, params) ⇒ Object
193 194 195 196 197 198 |
# File 'lib/spiderfw/controller/dispatcher.rb', line 193 def add_chain_item(method, proc, params) @dispatch_chains ||= {} @dispatch_chains[method] ||= [] @dispatch_chain_index ||= {} @dispatch_chains[method] << [proc, params] end |
#can_dispatch?(method, action) ⇒ Boolean
Returns true if there is a route for action, and the routed object responds to method.
92 93 94 95 96 97 98 99 100 101 |
# File 'lib/spiderfw/controller/dispatcher.rb', line 92 def can_dispatch?(method, action) d_next = dispatch_next(action) return false unless d_next if (d_next.dest.is_a?(Class)) return false unless d_next.dest.method_defined?(method) else return false unless d_next.dest.respond_to?(method) end return true end |
#dispatch(method, action = '', *arguments) ⇒ Object
Given a method and an action, returns a triplet containing
-
the object on which to call the method
-
the new action
-
the new arguments
36 37 38 39 40 41 42 43 44 |
# File 'lib/spiderfw/controller/dispatcher.rb', line 36 def dispatch(method, action='', *arguments) return nil unless can_dispatch?(method, action) route = @dispatch_next[action] obj = route.obj new_arguments = arguments new_arguments += route.params unless route.[:remove_params] return [obj, route.action, new_arguments] # return obj.send(method, route.action, *(new_arguments)) end |
#dispatch_chain(method) ⇒ Object
208 209 210 211 |
# File 'lib/spiderfw/controller/dispatcher.rb', line 208 def dispatch_chain(method) our_chain = @dispatch_chains && @dispatch_chains[method] ? @dispatch_chains[method] : [] our_chain + self.class.dispatch_chain(method) end |
#dispatch_next(path) ⇒ Object
Returns the (possibly cached) route for path.
104 105 106 107 |
# File 'lib/spiderfw/controller/dispatcher.rb', line 104 def dispatch_next(path) @dispatch_next ||= {} @dispatch_next[path] ||= dispatcher_get_route(path) end |
#dispatcher_get_route(path) ⇒ Object
109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/spiderfw/controller/dispatcher.rb', line 109 def dispatcher_get_route(path) route = get_route(path) return route if !route || route.obj obj = dispatched_object(route) obj.dispatch_previous = self if obj.respond_to?(:dispatch_previous=) && obj != self route.obj = obj if route.[:do] do_args = [route.matched] + (route.params || []) obj.instance_exec(*(do_args).slice(0, route.[:do].arity), &route.[:do]) end route.obj = obj route end |
#do_dispatch(method, action = '', *arguments) ⇒ Object
Dispatches the given method and action: will get an object and new action and arguments from #dispatch, and then call the method on the object, with new action and new arguments as params.
If #dispatch_methods are defined, will call them before calling method. After calling method, will call a method called “#method_Spider::Dispatcher.new_actionnew_action.downcase”, if it exists
Example:
do_dispatch(:before, 'section_b/news/list')
will get obj (in the example, the ‘section_b’ controller) and call
# any method configured in dispatch_methods
obj.before('news/list')
obj.before_news
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/spiderfw/controller/dispatcher.rb', line 59 def do_dispatch(method, action='', *arguments) obj, route_action, new_arguments = dispatch(method, action, *arguments) return nil unless obj return nil if obj == self && route_action == action # short circuit meth_action = route_action.length > 0 ? route_action : obj.class.default_action begin if (obj.class.dispatch_methods && obj.class.dispatch_methods[method]) obj.class.dispatch_methods[method].each do |dm| conditions, d_method, params = dm test = check_action(route_action, conditions) test = !test if params[:unless] obj.send(d_method, route_action, *new_arguments) if (test) end end res = obj.send(method, route_action, *(new_arguments)) unless meth_action.empty? meth_action = meth_action[0..-2] if meth_action[-1].chr == '/' meth_action = meth_action.split('/', 2)[0] try_meth = "#{method}_#{meth_action.downcase}" res = obj.send(try_meth, *new_arguments) if obj.respond_to?(try_meth) end return res rescue StandardError, SecurityError => exc if (obj.respond_to?(:try_rescue)) obj.send(:try_rescue, exc) else raise end end end |
#get_route(path) ⇒ Object
Looks in defined routes, and returns the first matching Route for path.
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 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 189 190 191 |
# File 'lib/spiderfw/controller/dispatcher.rb', line 124 def get_route(path) path ||= '' r = routes + self.class.routes if nil_route = self.class.nil_route r << [nil, nil_route[0], nil_route[1]] end r.each do |route| try, dest, = route action = nil nil_route = false case try when true, nil action = path matched = nil nil_route = true when String test_path = path if ([:ignore_case]) test_path = path.downcase try.downcase! end if (test_path[0..(try.length-1)] == try) action = path[(try.length)..-1] matched = try end when Regexp action_index = [:action_match] match = try.match(path) if (match) action = action_index ? match[action_index] : match.post_match action = action[0..-2] if action.length > 0 && action[-1].chr == '/' params = match[1..(match.length-1)] matched = match[0] end when Proc res = try.call(path, self) if (res) if (res.is_a?(Array)) action = res[0] params = res[1] matched = res[1] else action = res end end end if action action = action[1..-1] if action[0] && action[0].chr == '/' if ([:prepend]) action = [:prepend] + action end if (dest.class == Symbol) # route to self new_params = [] new_params << action if action && !action.empty? new_params += (params || []) params = new_params action = dest.to_s dest = self end params ||= [] action.sub!(/^\/+/, '') # no leading slash return Route.new(:path => path, :dest => dest, :action => action, :matched => matched, :nil_route => nil_route, :params => params, :options => ) end end return nil end |
#route(path, dest = nil, options = nil) ⇒ Object
Adds one or more routes to the dispatcher. Also accepts an Hash containing path/destination couples
Parameters
- path<String, Regexp>
-
When a string is passed, a path matches if it matches exactly When a regular expression is passed, it is used to match the path
- dest<Spider::Controller, Proc>
-
The route destination
27 28 29 30 |
# File 'lib/spiderfw/controller/dispatcher.rb', line 27 def route(path, dest=nil, =nil) @routes ||= [] self.class.add_route(@routes, path, dest, ) end |
#routes ⇒ Object
Defined routes.
13 14 15 |
# File 'lib/spiderfw/controller/dispatcher.rb', line 13 def routes @routes ||= [] end |
#run_chain(method, action = '', *params) ⇒ Object
200 201 202 203 204 205 206 |
# File 'lib/spiderfw/controller/dispatcher.rb', line 200 def run_chain(method, action='', *params) chain = dispatch_chain(method) return unless chain.length > 0 @dispatch_chain_index ||= {} @dispatch_chain_index[method] = @dispatch_chain_index[method] ? @dispatch_chain_index[method]+1 : 0 instance_eval(&chain[@dispatch_chain_index[method]][0]) if chain[@dispatch_chain_index[method]] end |