Class: Spider::Controller

Inherits:
Object show all
Includes:
Annotations, ControllerMixins, Dispatcher, Helpers, Logger
Defined in:
lib/spiderfw/controller/controller.rb,
lib/spiderfw/controller/controller_exceptions.rb

Defined Under Namespace

Modules: SceneMethods Classes: BadRequest, ControllerError, Forbidden, NotFound

Instance Attribute Summary collapse

Attributes included from Dispatcher

#dispatch_previous

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Annotations

included

Methods included from Logger

add, close, close_all, datetime_format, datetime_format=, #debug, debug, debug?, #debug?, enquire_loggers, #error, error, #error?, error?, #fatal, fatal, #fatal?, fatal?, info, #info, info?, #info?, method_missing, open, reopen, send_to_loggers, unknown, #unknown, #warn, warn, warn?, #warn?

Methods included from Dispatcher

#add_chain_item, #can_dispatch?, #dispatch, #dispatch_chain, #dispatch_next, #do_dispatch, #get_route, included, #route, #routes, #run_chain

Constructor Details

#initialize(request, response, scene = nil) ⇒ Controller

Returns a new instance of Controller.



136
137
138
139
140
141
142
143
144
# File 'lib/spiderfw/controller/controller.rb', line 136

def initialize(request, response, scene=nil)
    @request = request
    @response = response
    @scene = scene || get_scene
    @dispatch_path = ''
    @is_target = true
    init
    #@parent = parent
end

Instance Attribute Details

#dispatch_actionObject

Returns the value of attribute dispatch_action.



134
135
136
# File 'lib/spiderfw/controller/controller.rb', line 134

def dispatch_action
  @dispatch_action
end

#executed_methodObject (readonly)

Returns the value of attribute executed_method.



133
134
135
# File 'lib/spiderfw/controller/controller.rb', line 133

def executed_method
  @executed_method
end

#is_targetObject

Returns the value of attribute is_target.



134
135
136
# File 'lib/spiderfw/controller/controller.rb', line 134

def is_target
  @is_target
end

#requestObject (readonly)

Returns the value of attribute request.



133
134
135
# File 'lib/spiderfw/controller/controller.rb', line 133

def request
  @request
end

#responseObject (readonly)

Returns the value of attribute response.



133
134
135
# File 'lib/spiderfw/controller/controller.rb', line 133

def response
  @response
end

#sceneObject (readonly)

Returns the value of attribute scene.



133
134
135
# File 'lib/spiderfw/controller/controller.rb', line 133

def scene
  @scene
end

Class Method Details

.appObject



41
42
43
44
45
46
47
48
49
# File 'lib/spiderfw/controller/controller.rb', line 41

def app
    return @app if @app
    @app ||= self.parent_module
    while @app && !@app.include?(Spider::App) && @app != Object
        @app = @app.parent_module
    end
    @app = nil if @app && !@app.include?(Spider::App)
    return @app
end

.before(conditions, method, params = {}) ⇒ Object

Defines a method that will be called before the controller’s before, if the action matches the given conditions.

  • The first argument, the condition(s), may be a String, a Regexp, a Proc or a Symbol,

that will be checked against the action, or an Array containing several conditions.

  • The second argument, a Symbol, is the method to be called if the conditions match.

  • The third optional argument, an Hash, may contain :unless => true: in this case,

the conditions will be inverted, that is, the method will be executed unless the conditions match. Example:

before('list_', :before_lists)

will call the method before_lists if the action starts with ‘list_’



72
73
74
75
76
# File 'lib/spiderfw/controller/controller.rb', line 72

def before(conditions, method, params={})
    @dispatch_methods ||= {}
    @dispatch_methods[:before] ||= []
    @dispatch_methods[:before] << [conditions, method, params]
end

.before_methodsObject



78
79
80
# File 'lib/spiderfw/controller/controller.rb', line 78

def before_methods
    @dispatch_methods && @dispatch_methods[:before] ? @dispatch_methods[:before] : []
end

.before_unless(condition, method, params = {}) ⇒ Object



82
83
84
85
86
87
# File 'lib/spiderfw/controller/controller.rb', line 82

def before_unless(condition, method, params={})
    @dispatch_methods ||= {}
    @dispatch_methods[:before] ||= []
    params[:unless] = true
    @dispatch_methods[:before] << [condition, method, params]
end

.controller_action?(method) ⇒ Boolean

Returns:

  • (Boolean)


97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/spiderfw/controller/controller.rb', line 97

def controller_action?(method)
    return false unless self.method_defined?(method)
    return true if default_action && method == default_action.to_sym
    if @controller_actions
        res = @controller_actions.include?(method)
        if (!res)
            Spider.logger.info("Method #{method} is not a controller action for #{self}")
        end
        return res
    else
        return true
    end
end

.controller_actions(*methods) ⇒ Object



89
90
91
92
93
94
95
# File 'lib/spiderfw/controller/controller.rb', line 89

def controller_actions(*methods)
    if (methods.length > 0)
        @controller_actions ||= []
        @controller_actions += methods
    end
    @controller_actions
end

.default_actionObject



37
38
39
# File 'lib/spiderfw/controller/controller.rb', line 37

def default_action
    'index'
end

.find_resource(type, name, cur_path = nil) ⇒ Object



111
112
113
# File 'lib/spiderfw/controller/controller.rb', line 111

def find_resource(type, name, cur_path=nil)
    Spider.find_resource(type, name, cur_path, self)
end

.find_resource_path(type, name, cur_path = nil) ⇒ Object



115
116
117
118
# File 'lib/spiderfw/controller/controller.rb', line 115

def find_resource_path(type, name, cur_path=nil)
    res = Spider.find_resource(type, name, cur_path, self)
    return res ? res.path : nil
end

.layout_pathObject



56
57
58
59
# File 'lib/spiderfw/controller/controller.rb', line 56

def layout_path
    return nil unless self.app
    return self.app.path+'/views'
end

.option(k, v) ⇒ Object



33
34
35
# File 'lib/spiderfw/controller/controller.rb', line 33

def option(k, v)
    self.option[k] = v
end

.optionsObject



29
30
31
# File 'lib/spiderfw/controller/controller.rb', line 29

def options
    @options ||= {}
end

.template_pathObject



51
52
53
54
# File 'lib/spiderfw/controller/controller.rb', line 51

def template_path
    return nil unless self.app
    return self.app.path+'/views'
end

.urlObject



124
125
126
# File 'lib/spiderfw/controller/controller.rb', line 124

def url
    @url || ''
end

.url=(url) ⇒ Object



120
121
122
# File 'lib/spiderfw/controller/controller.rb', line 120

def url=(url)
    @url = url
end

Instance Method Details

#action_target?Boolean

Returns true if this controller is the final target for the current action, that is, if it does not dispatch to any route

Returns:

  • (Boolean)


189
190
191
# File 'lib/spiderfw/controller/controller.rb', line 189

def action_target?
    !@dispatch_next[@call_path] || @dispatch_next[@call_path].dest == self
end

#after(action = '', *arguments) ⇒ Object



242
243
244
245
246
247
248
249
250
251
252
# File 'lib/spiderfw/controller/controller.rb', line 242

def after(action='', *arguments)
    catch(:done) do
        do_dispatch(:after, action, *arguments)
    end
    # begin
    #     run_chain(:after)
    #     #dispatch(:after, action, params)
    # rescue => exc
    #     try_rescue(exc)
    # end
end

#before(action = '', *arguments) ⇒ Object



232
233
234
235
236
237
238
# File 'lib/spiderfw/controller/controller.rb', line 232

def before(action='', *arguments)
    @call_path = action
    catch(:done) do
        #debug("#{self} before")
        do_dispatch(:before, action, *arguments)
    end
end

#call_pathObject



155
156
157
158
159
160
161
162
# File 'lib/spiderfw/controller/controller.rb', line 155

def call_path
    act = @dispatch_action || ''
    if (@dispatch_previous)
        prev = @dispatch_previous.call_path 
        act = prev+'/'+act unless prev.empty?
    end
    return ('/'+act).gsub(/\/+/, '/').sub(/\/$/, '')
end

#check_action(action, c) ⇒ Object



268
269
270
# File 'lib/spiderfw/controller/controller.rb', line 268

def check_action(action, c)
    self.class.check_action(action, c)
end

#doneObject



258
259
260
261
# File 'lib/spiderfw/controller/controller.rb', line 258

def done
    self.done = true
    throw :done
end

#done=(val) ⇒ Object



263
264
265
266
# File 'lib/spiderfw/controller/controller.rb', line 263

def done=(val)
    @__done = val
    @dispatch_previous.done = val if @dispatch_previous
end

#done?Boolean

Returns:

  • (Boolean)


254
255
256
# File 'lib/spiderfw/controller/controller.rb', line 254

def done?
    @__done
end

#execute(action = '', *arguments) ⇒ Object



199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/spiderfw/controller/controller.rb', line 199

def execute(action='', *arguments)
    return if @__done
    # return if self.is_a?(Spider::Widget) # FIXME: this is obviously wrong. Widgets must override the behaviour
    # # somewhere else, or probably just not inherit controller.
    debug("Controller #{self} executing #{action} with arguments #{arguments}")
    # before(action, *arguments)
    # do_dispatch(:before, action, *arguments)
    catch(:done) do
        if (can_dispatch?(:execute, action))
            d_next = dispatch_next(action)
            #run_chain(:execute, action, *arguments)
            #  shortcut route to self
            return do_dispatch(:execute, action) if d_next.dest != self 
            arguments = d_next.params
        end
        if (@executed_method)
            meth = self.method(@executed_method)
            args = arguments + @executed_method_arguments
            @controller_action = args[0]
            arity = meth.arity
            unless arity == -1
                arity = (-arity + 1) if arity < 0
                args = arity == 0 ? [] : args[0..(arity-1)]
                args = [nil] if meth.arity == 1 && args.empty?
            end
            Spider.logger.info("Executing: #{self.class.name}##{@executed_method}.#{@request.format}")
            send(@executed_method, *args)
        else
            raise NotFound.new(action)
        end
    end
end

#get_action_method(action) ⇒ Object



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/spiderfw/controller/controller.rb', line 168

def get_action_method(action)
    method = nil
    additional_arguments = nil
    # method = action.empty? ? self.class.default_action : action
    # method = method.split('/', 2)[0]
    if (action =~ /^([^:]+)(:.+)$/)
        method = $1
    elsif (action =~ /^([^\/]+)\/(.+)$/) # methods followed by a slash
        method = $1
        additional_arguments = [$2]
    else
        method = action
    end
    method = method[0..-2] if !method.blank? && method[-1].chr == '/'
    method = self.class.default_action if !method || method.empty?
    return nil if method.empty?
    return [method.to_sym, additional_arguments]
end

#get_scene(scene = nil) ⇒ Object



272
273
274
275
276
277
278
# File 'lib/spiderfw/controller/controller.rb', line 272

def get_scene(scene=nil)
    scene = Scene.new(scene) if scene.class == Hash
    scene ||= Scene.new
    # debugger
    # scene.extend(SceneMethods)
    return scene
end

#initObject

Override this for controller initialization



147
148
149
# File 'lib/spiderfw/controller/controller.rb', line 147

def init
    
end

#inspectObject



151
152
153
# File 'lib/spiderfw/controller/controller.rb', line 151

def inspect
    self.class.to_s
end

#is_target?Boolean

Returns false if the target of the call is a widget, true otherwise

Returns:

  • (Boolean)


194
195
196
# File 'lib/spiderfw/controller/controller.rb', line 194

def is_target?
    @is_target
end

#prepare_scene(scene) ⇒ Object



280
281
282
283
284
285
286
287
288
289
290
291
292
293
# File 'lib/spiderfw/controller/controller.rb', line 280

def prepare_scene(scene)
    req_path = @request.path
    req_path += 'index' if !req_path.blank? && req_path[-1].chr == '/'
    scene.request = {
        :path => @request.path,
        :page_path => req_path
    }
    scene.controller = {
        :request_path => request_path,
        :class => self.class
    }
    scene.content = {}
    return scene
end

#request_pathObject



164
165
166
# File 'lib/spiderfw/controller/controller.rb', line 164

def request_path
    call_path
end